#At runtime (node), get all argument values of a function.

93 messages · Page 1 of 1 (latest)

vague ibex
#

Is there a helpful library that can give me the argument values passed into a certain function? I want to write an automated test to check that, for every rename(x, y) in my code, x does not exist in any of my .html files.

For context, my app is 100% client-side, but I build it with node. When my code runs in the browser, rename(x, y) modifies .html stored in variables. But I also want to modify .html files on my filesystem (fs). The fs files shouldn't contain the x value either, since they should be renamed to y.

At the moment I modify the fs files via replace all in my editor. But I would like to make this a more automated process because sometimes I forget to do this.

#

@dawn dawn : I don't think I can use arguments because, at runtime (i.e., in the browser), the file paths of the .html files aren't known.

#

Plus, once bundled, the fs HTML files are rendered directly in the browser. I would have to preprocess every HTML file somehow to interpret x as y. ideally, I could just modify the file contents once and for all

dawn dawn
#

it's still very unclear what you are working with and are trying to do
from my understanding:

  • you have a nodejs program that is some kind of bundler/pre-processor and that does assertions on the code
  • that program reads HTML files from the file system, and process the string content
  • those HTML strings contain a JS script tag with a rename(x, y) function that will be called in the browser
  • in nodejs, your code should keep track of every time rename will be called, keep track of what values it has been called with, and ensure those values aren't present in the HTML string
#

is that correct? @vague ibex

#

if not, can you provide an actual code smaple, along with the expected output

vague ibex
#

my.ts

const value = state.get(`x`);
const newValue = rename(`foo`, `bar`);
state.set(`x`, newValue);
...
const value2 = state.get(`y`);
const newValue2 = rename(`baz`, `qux`);
state.set(`y`, newValue2);

index.html

...
<span>foo</span>
...

automated-test.ts

it(`errors if the first argument value to "rename" exists in any .html file`, () => {
  const htmlFiles: string[] = getAllHtmlFiles();
  const renameFirstArgValues: string[] = getAllRenameFirstArgValues(); // [`foo`, `baz`]
  htmlFiles.forEach((htmlContent) => {
    assertFalse(htmlContent.containsAny(renameFirstArgValues));
  });
});

@dawn dawn

#

So for my question, I guess I'm asking if there's a library/technique that will make it easier to implement getAllRenameFirstArgValues

dawn dawn
#

my.ts runs in the browser, right?

vague ibex
#

after being transpiled and bundled, yeah

dawn dawn
#

your tests should also run in the browser then

vague ibex
#

automated-test.ts does not

dawn dawn
#

or at least simulate a browser env then

#

I suggest using karma, or jest

vague ibex
#

They can do the latter

dawn dawn
#

but mainly

#

use better tools

#

doing raw html and js won't get you far

#

especialyl if you want to combine testing

vague ibex
#

I don't understand how running the test in the browser helps this problem

dawn dawn
#

the tests in the browser will run the code in the browser

#

and make assertions

vague ibex
#

I think there's something else confusing about what I said that may be why you're saying that

dawn dawn
#

to test the code, you must run it

vague ibex
#

Even if I run the tests in the browser, I would still need to getAllRenameFirstArgValues

dawn dawn
#

not just "find how many times this function is called based on its name"

vague ibex
#

I already test my.ts. What I want to test is the .html files, now

#

but I specifically want to test that they don't contain something like <span>foo</span>

#

I think I might understand your suggestion now

dawn dawn
#

you need to actually run my.ts to see if it's working

vague ibex
#

I do

dawn dawn
#

the tests run the code, and check for the side effects

dawn dawn
#

which is why you need to write tests inside of the browser

vague ibex
#

it does, in another it

#

it(`renames "foo" to "bar" in \`state\`"`, () => {...

#

Sorry, I know I'm the problem here because I'm not explaining this well. Let me take a step back. Even if I test my.ts in automated-test.ts, I still don't know how to implement getAllRenameFirstArgValues. I think if you showed me some pseudocode of how you would write automated-test.ts, I'll understand what I'm saying wrong

dawn dawn
#

ok, I think I now get what you're trying to do

#

however, this isn't a good idea

#

you can very well read my.ts as text, and, using a regex, search for all the first arguments when "calling" the replace function

#

or you could read my.ts, parser it as an AST (abstract syntax tree), then pick those actual function calls and perform the same tests

dawn dawn
dawn dawn
#

that is not a good way to test you code

#

if you want to test your code, run it
then check what the results are

vague ibex
#

right. Sorry, my thumbs up emoji was based on emotion.once you said that I could tell you understood what I was asking.

dawn dawn
#

tbh, those kinds of tests you're trying to perform don't add that much value

#

just write an assertion inside of replace to see if it's the first call, and if that value is present in the document

vague ibex
dawn dawn
#

the webapp I meant

vague ibex
#

I'm not sure how the function can get access to the webapp source code in order to assert on it

dawn dawn
#

do you have control over rename?

vague ibex
#

control in what sense? I wrote it and I can modify it, if that's what you're asking

dawn dawn
#

yes

#

then just make a check inside of rename, where if it the first time this function is called, it will look that that string in the webapp, in the dom, where it's displayed, and if it's present, will throw an error

#

sometimes it's easier to just throw at runtime than writing complex and brittle tests

#

but tbh, the root cause of the problem is my.ts and what it's doing

#

if you need something to be replaced, do it sooner

#

don't send extra js and try to test it works

#

replace the html before it's sent, or integrate that behavior in the webapp

vague ibex
dawn dawn
#

and when it's in the webapp, use a testig framework that supports the web

dawn dawn
#

can you provide more context as to why you think you need this?

vague ibex
#

yeah. Would you mind writing some pseudocode for me of rename's impl? I still think I'm doing something differently from what you are imagining, but it's hard to understand what that difference is without knowing what you're imagining

dawn dawn
#

Would you mind writing some pseudocode for me of rename's impl?
I can't

#

not sure what it's even supposed to do

#

if you just want to replace a string in the dom, grab the corresponding dom element, then replace the value

vague ibex
#

there are a subset of elements that could contain the x value

#

I'll write an automated test to start the webapp and put the assert in replace like you said. This will catch any missed renames in an automated test

#

FWIW, it'd look something like this:

function replace(x, y) {
  const haystacks = getAllDomElementsToCheck();
  if (haystacks.includes(x)) { throw new Error() }
}
dawn dawn
#

about those variables you are trying to replace, do the contain configuration, like URLs or credentials of some sort?

vague ibex
#

nope

dawn dawn
#

isn't it something you could do when switching to a more modern frontend framework? something that would replace some env variables when building the webapp?

vague ibex
#

I'm sure, but unfortunately it's not an option to replace it

dawn dawn
#

because it seems you are both trying to create a framework and test said framework while also having your own app that is built on top of that framework

vague ibex
#

lol that's so true

#

I hadn't thought about that before

dawn dawn
#

that's your main problem tbh

vague ibex
#

But yeah, the framework wasn't built with testability in mind

#

I guess I'm not really trying to create a framework, though

dawn dawn
#

I wouldn't bother testing that tbh then

#

if it's really important, then take the time to use more modern/standard stuff

vague ibex
#

"stuff?"

dawn dawn
dawn dawn
# vague ibex "stuff?"

there are so many different technologies nowadays to do frontend stuff
from very minial to very advanced

#

but at those those solutions are somewhat "standard", have some proper support, and are ready to go

#

that would be one less thing to maintain and worry about

vague ibex
#

Yeah, I know a bit of react and modern angular. I use them occasionally. It's just not an option for this specific project

#

At my day job I definitely heed your advice. But I think this is a special scenario

dawn dawn