Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
MrMoo
Sep 14, 2000

Has anyone been able to mock a simple function with TS-Node and NodeJS v20s Test Runner? I cannot believe this poo poo doesn't work. Classes and objects are fine, but not possible with functions. "esmock" almost works but generally not great.

Scenario should be super common: mock the auth() middleware commonly used with ExpressJS.

If you ignore that rather large deficit, it does run quite significantly faster than Jest.

I found that top-level await is a minefield. If you use that in a module and include that module in one under test, then pretty much all test runners will exit early. Maybe it is a language issue? Are you supposed to dynamic import modules that use top-level await?

quote:

This means that modules with child modules that use await will wait for the child modules to execute before they themselves run, all while not blocking other child modules from loading.
Sounds like it should work as expected?

MrMoo fucked around with this message at 04:08 on Sep 30, 2023

Adbot
ADBOT LOVES YOU

abraham linksys
Sep 6, 2010

:darksouls:

MrMoo posted:

Has anyone been able to mock a simple function with TS-Node and NodeJS v20s Test Runner? I cannot believe this poo poo doesn't work. Classes and objects are fine, but not possible with functions. "esmock" almost works but generally not great.

it just kinda looks like node:test doesn't have any functionality for mocking module imports at the moment: https://github.com/orgs/nodejs/discussions/47959

smackfu
Jun 7, 2004

I feel like I try these new things with our code base at work and immediately find five dealbreakers and I wonder if they even test stuff.

abraham linksys
Sep 6, 2010

:darksouls:
i figure module import mocking is probably not something the average node codebase has and i get why they didn't implement it for v0 of this extremely new thing (node:test isn't even in the LTS version without a feature flag, is it?)

necrotic
Aug 2, 2005
I owe my brother big time for this!

abraham linksys posted:

i figure module import mocking is probably not something the average node codebase has and i get why they didn't implement it for v0 of this extremely new thing (node:test isn't even in the LTS version without a feature flag, is it?)

Yeah it’s still experimental in 18, but marked stable in 20. I don’t think it’s feature flagged, though, as you have to explicitly import and use it.

MrMoo
Sep 14, 2000

The Test Runner has been there since NodeJS 16 in 2021.

https://nodejs.dev/en/api/v16/test/

Unit tests are all about units, so defining units and mocking the interfaces is a rather fundamental aspect.

Also consider the current trend in webdev is to avoid classes and treat modules as classes, just exporting functions instead. It is overly surprising to see something that doesn't co-operate with at least 50% of modern code architecture.

My example was testing ExpressJS with authentication, which is definitely not a small niche target. I can understand that "testing" is not a popular concept, in an industry with zealots hating on TypeScript because it is affecting there development speeeed.

MrMoo fucked around with this message at 19:05 on Sep 30, 2023

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!

MrMoo posted:

in an industry with zealots hating on TypeScript because it is affecting there development speeeed.
gently caress, I wish they'd drop Javascript for full Typescript, because it'd probably allow for the JIT to do better optimization via more specific type constraints, and finally enable runtime generics of all things.

MrMoo
Sep 14, 2000

I'd rather JavaScript gain full optional type support via a "use types;" stupid header and then just ignore TypeScript forever more. It's pretty strange that Microsoft never made a test runner for TypeScript either.

abraham linksys
Sep 6, 2010

:darksouls:

MrMoo posted:

Unit tests are all about units, so defining units and mocking the interfaces is a rather fundamental aspect.

Also consider the current trend in webdev is to avoid classes and treat modules as classes, just exporting functions instead. It is overly surprising to see something that doesn't co-operate with at least 50% of modern code architecture.

sure, but those methods can actually be passed to the functions that use them as arguments, the most basic form of dependency injection. common in javascript and swift and lotta other languages. i always do this with api clients and stuff; no reason to mock import axios 'from 'axios' when you can create a mock apiClient and pass that as the first argument to fetchMyThings(apiClient)

and, yknow, plenty of languages don't have the ability to mock imports at all and have done fine with actual dependency injection, java and c# and whatnot. different pattern but does happen in node or browser code, i know nestjs has it and if you squint a lot of frontend frameworks have something that kind of looks like it (i have totally used react contexts for this)

I'm kinda ragging on you, and from poking at github issues it looks like module import mocking is something the implementer of this feature is planning on adding (it requires some esm loader stuff that isn't done yet in node), they just figured it wasn't worth blocking shipping on given the api is stable. in the meantime, jest exists!

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
A while back when I started my project with CRA, I initially wanted to do the front-end in Typescript and TSX, but eventually ditched the idea because every hot reload involved running the Typescript compiler and it got annoying quickly. Now that I switched to Vite a while ago, Typescript got viable again. What I'm wondering now is, if you want a web service and front-end communicating with each other, how do you handle the type data? In a third module shared between both, or import the types from the web service module directly?

necrotic
Aug 2, 2005
I owe my brother big time for this!

Combat Pretzel posted:

A while back when I started my project with CRA, I initially wanted to do the front-end in Typescript and TSX, but eventually ditched the idea because every hot reload involved running the Typescript compiler and it got annoying quickly. Now that I switched to Vite a while ago, Typescript got viable again. What I'm wondering now is, if you want a web service and front-end communicating with each other, how do you handle the type data? In a third module shared between both, or import the types from the web service module directly?

Yeah we have a package for sharing types and utilities between the backend and front end.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
I've handwritten types by looking at the API docs at any job i've been to.

e: not saying it's the most efficient, but it gets the job done

teen phone cutie fucked around with this message at 19:43 on Oct 2, 2023

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

teen phone cutie posted:

I've handwritten types by looking at the API docs at any job i've been to.

e: not saying it's the most efficient, but it gets the job done

i've used handwritten types in any codebase i've worked in but i did my own pilot project at work with swagger and it really saved a lot of time generating the client code with swagger codegen.

MrMoo
Sep 14, 2000

abraham linksys posted:

sure, but those methods can actually be passed to the functions that use them as arguments, the most basic form of dependency injection. common in javascript and swift and lotta other languages. i always do this with api clients and stuff; no reason to mock import axios 'from 'axios' when you can create a mock apiClient and pass that as the first argument to fetchMyThings(apiClient)

and, yknow, plenty of languages don't have the ability to mock imports at all and have done fine with actual dependency injection, java and c# and whatnot.

Sounds like you are paid by the hour or line of code. Wouldn't it be great if you didn't have to add absolutely zero-value abstractions with all the potential human error, code bloat, and performance overhead, and just target the modules directly?

Java is a hilarious example as it only supports class exports.

Software is supposed to enable users to be more productive, that's why we have such clunky high level languages. Development teams and organisations should be going out of way to force vendors to test and prove their testing of software. How is this any progress over development in 1960? I love Perl in all, but espousing zero type safety and zero testing is not the way to build modern large applications.

MREBoy
Mar 14, 2005

MREs - They're whats for breakfast, lunch AND dinner !
noob question here -

I've been tasked with working on something someone else built. This thing uses Leaflet and there are lines like this to tell the app where to look for the processed imgs it uses for the map:

code:
url='http://site.something.com/map_tiles/{z}/{z}_{x}_{y}.png'
Its a hard coded/absolute http url for images that are on the same hardware/server/filesystem the app itself is on. The map_tiles directory is quite literally 5 directory levels up from the calling file in the root directory of the apps file/directory structure. What I would like to know is that would either of the following work instead:

code:
url='http://localhost/map_tiles/{z}/{z}_{x}_{y}.png'

url='../../../../../map_tiles/{z}/{z}_{x}_{y}.png'
which makes more sense to me if something were to happen to something.com in the future as this would be a more relative(-ish?) link instead of hard coded.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

MREBoy posted:

code:
url='../../../../../map_tiles/{z}/{z}_{x}_{y}.png'
which makes more sense to me if something were to happen to something.com in the future as this would be a more relative(-ish?) link instead of hard coded.
URLs aren't accessing the filesystem, they're accessing the web server, which evidently has /map_tiles/ pointing at the directory in which those files reside.

url="/map_tiles/{z}/{z}_{x}_{y}.png"

should work and make it not dependent on the server address remaining unchanged - but it *does* make it dependent on the image files continuing to be served on the same domain as the html, versus the current very explicit URLs make it so if the html was moved to somethingelse.com and the images stayed where they were, it would still work.

(Your mess of .. would probably also work, but only because .. from the top level path does nothing.)

MREBoy
Mar 14, 2005

MREs - They're whats for breakfast, lunch AND dinner !

roomforthetuna posted:

URLs aren't accessing the filesystem, they're accessing the web server, which evidently has /map_tiles/ pointing at the directory in which those files reside.

url="/map_tiles/{z}/{z}_{x}_{y}.png"

should work and make it not dependent on the server address remaining unchanged - but it *does* make it dependent on the image files continuing to be served on the same domain as the html, versus the current very explicit URLs make it so if the html was moved to somethingelse.com and the images stayed where they were, it would still work.

(Your mess of .. would probably also work, but only because .. from the top level path does nothing.)

ty for this, will give it a try :tipshat:

huhu
Feb 24, 2006
Today I learned if you pass an excessively large number to setInterval in JavaScript, it'll just start executing the callback function hundreds of times a second. That took way too long to troubleshoot.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

huhu posted:

Today I learned if you pass an excessively large number to setInterval in JavaScript, it'll just start executing the callback function hundreds of times a second. That took way too long to troubleshoot.
setinterval takes a 32-bit signed int as argument for delay in the v8 engine:
https://stackoverflow.com/questions/12633405/what-is-the-maximum-delay-for-setinterval

Bruegels Fuckbooks fucked around with this message at 22:08 on Oct 23, 2023

N.Z.'s Champion
Jun 8, 2003

Yam Slacker
Use Number.MAX_SAFE_INTEGER

some kinda jackal
Feb 25, 2003

 
 
This is kind of a high level direction question from someone who has only superficial current experience in coding (code when all other solutions are exhausted) but is slowly starting to take on a few hobby projects around APIs and front end.

Context:

I took up Node.JS because I was looking for something fairly robust that is suited for backend work and the skillsets with the language could extend to frontend as well. My background in development is being an IT guy who got tricked into writing some .NET code regularly probably twenty years ago, so I have a superficial self-taught understanding of program logic, OOP concepts, domain modelling, etc.

Motivation:

My goals are very modest. I just want to know enough about a language to no longer have to spend 45 minutes googling "XYZ basics" from scratch when I choose to start a new project, either long term or just as a point-solution to something I'm working on at that moment.

My actual question:

I have some vague notions of the benefits of typescript but I'm not sure these benefits are ever really likely to realize for me in my meagre hobbyist future. THAT SAID, if you look back at your own JS/Node path, would you suggest that someone just starting out focus on TS?

I realize it's a superset of JS so it's not like I have to pick one or the other and TS can build on my existing skills, BUT I'm also very cognizant of the fact that this is a hobby and I want to put my time where it's most effective.

I'm one of those weirdos who like to analyze things so essentially I have two paths I can come up with:

Learn Node.JS/ES -> Code until I run up against something compelling to learn TS which may or may not ever happen -> Learn and apply TS -> I die in 20 years
- Pro: Wealth of information about NJS w/ES. Virtually every node tutorial is just using JS/ES unless it's specifically about TS
- Con: I may or may not have to learn something new at some point.

- Learn Node.JS/TS -> Code until I die in 20 years
- Pro: I'm basically at square one learning JS/ES so why not start with TS? One language to think in, don't really have to figure out whether I need ES or TS.
- Con: Maybe more complexity in coding/toolchain? idk. Unclear on TS usability in frontend dev, whether I'd need to know base ES for that, possibly negating my "just learn one thing" point.


I hate making these kinds of posts because any time I make one it turns out I'm habitually obsessing over literally the most ridiculous aspect. Like some guy who desperately needs to buy a car to get to work to avoid getting fired but then spends a month posting on car forums asking about whether he should buy rubber or fabric floor mats. But this has been running through my head the past few weeks while I've been dutifully picking up ES so I figured I'd make an rear end of myself yet again.

To be clear though, I'm not pausing learning and developing while I try to figure this out, this is just borne out of the fact that if I want to change it'll never be easier than it is now.

As always, I'm happy to be roasted so have at.

some kinda jackal fucked around with this message at 12:03 on Oct 27, 2023

Osmosisch
Sep 9, 2007

I shall make everyone look like me! Then when they trick each other, they will say "oh that Coyote, he is the smartest one, he can even trick the great Coyote."



Grimey Drawer
I would absolutely start with typescript, because strong typing is nice to have, especially when learning, since it helps guide your code, and makes exploring other code easier

some kinda jackal
Feb 25, 2003

 
 
I've been dabbling with it for the past day and I have to agree. I really do prefer it.

Shoehorning it into Node feels a little clunky but manageable. I gave Deno a try since Oak feels about as usable as Express for my little pet project so until I have a reason to switch back to Node I'll use the thing that's TS native.

Thanks!

Roadie
Jun 30, 2013
Just keep in mind that because the JS ecosystem is a garbage fire where everything changes all the time and nothing is documented, and since nobody maintaining TypeScript considers basic real-life use cases, even doing simple stuff like making TypeScript work with Jest is a nightmare of loving around with random config stuff off Google until something happens to work for you.

Osmosisch
Sep 9, 2007

I shall make everyone look like me! Then when they trick each other, they will say "oh that Coyote, he is the smartest one, he can even trick the great Coyote."



Grimey Drawer
The problem there is more Jest than anything else, test with something else like mocha.

Doom Mathematic
Sep 2, 2008
Yeah, Jest is a horror show. We're switching our UI testing over to Mocha, it's that bad.

smackfu
Jun 7, 2004

Really the worst idea is using jest helpers for stuff like fake timers because then you can’t actually switch test runners easily.

Also using any Facebook product is probably a bad idea.

MrMoo
Sep 14, 2000

Allegedly Bun Test is Jest compatible, but to move to NodeJS runner is not zero effort.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
I started using Vitest. It's nice.

Sad Panda
Sep 22, 2004

I'm a Sad Panda.
I'm looking at JS for the first time in a while and usign Puppeteer to do some scraping. It looks at the three URLs it is given and finds more links on them and should add them to my array to be dealt with.

JavaScript code:
  const URLsOfInterest = [
    "https://www.blahblah.com", "https://www.blahblah2.com", "https://www.blahblah3.com"
  ];

  let URLsToScrape = [];
  // Iterate through URLs of interest finding new pages that need scraping
  for (const siteURL of URLsOfInterest) {
    await page.goto(siteURL, {
      waitUntil: "domcontentloaded",
    });
    const cardSelector = ".card.item";

    URLsToScrape.push(
      ...(await page.$$eval(cardSelector, (elements) => {
        return elements.map((ele) => ele.href);
      }))
    });
  }
Is there a neater way to write that push part at the bottom? Putting that spread operator at the start so I get the individual items back rather than the whole array looks a bit ugly in my mind.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You could do something like:
code:
let URLsToScrape = URLsOfInterest.flatMap((siteUrl) => {
	// the code you have now, but just return the array directly instead of pushing the elements anywhere
});

some kinda jackal
Feb 25, 2003

 
 
I backslid off of Deno back to Node+TS just to not bite off more than I can chew. TS and Node is fine, I can deal with a few extra commands. Plus I instantly ran into availability of a pkcs11 package that worked with Deno even through npm imports.

That said, what is the current accepted best practice for nodemonning a TS project? is it to install node-ts and just set up a "nodemon src/app.ts" script in package.json? Or is there some other ts specific monitor/watcher I should be using? Obviously something I can google but I feel like I got a few different answers. Maybe I'm just too green to know what to specifically search for.

huhu
Feb 24, 2006

some kinda jackal posted:

I backslid off of Deno back to Node+TS just to not bite off more than I can chew. TS and Node is fine, I can deal with a few extra commands. Plus I instantly ran into availability of a pkcs11 package that worked with Deno even through npm imports.

That said, what is the current accepted best practice for nodemonning a TS project? is it to install node-ts and just set up a "nodemon src/app.ts" script in package.json? Or is there some other ts specific monitor/watcher I should be using? Obviously something I can google but I feel like I got a few different answers. Maybe I'm just too green to know what to specifically search for.

The project I started a few months ago was doing nodemon pointed at my app entry point. Required zero configuration besides the usual tsconfig.

https://blog.logrocket.com/configuring-nodemon-with-typescript/

some kinda jackal
Feb 25, 2003

 
 
Pretty much what I settled on, thanks! Getting into the flow. Node rocks.


SO I have a follow-on question.. I'm really getting a lot done with Node and TS, but.. the "just learn typescript first" thing is going poorly. Every tutorial or resource seems to assume a familiarity with Javascript and tends to focus on the deltas. What I'd love to find is a resource that teaches TS with no prior, introducing all the JS conventions you need in a TS-first manner.

I'm not opposed to going through a JS course, mind you, but every video I find is either "advanced JS" or "this is a variable, this is how you add two variables" and I tend to start scrubbing around which means I will invariably start to miss things.

So question to the thread. I'm doing my own independent research on this, but if anyone knows of a good "JS hit the ground running" abbreviated type course that goes through JS with the understanding that the viewer has familiarity with programming, just not JS itself -- OR a TS-first course that goes through all the necessary conventions to be fluent with the language, not just the TS-specific superset features.

Surprisingly hard to find IMO.



I've gotten a lot done with Node, and it's not like I'm flailing. I'm googling a lot, reading a lot of docs, but then I come across some cool concept I didn't know and I'm left wondering what else is useful that I could be making use of, even at a basic level. Absent finding anything above I still think I've had more fun programming in the past week and change than I have in the last 20 blindly groping around google for python snippets and it's really rewarding. I could probably continue blindly groping for node and TS stuff on google instead and be just fine, but I guess I find this valuable enough that I can dedicate at least some time to learn the basics. I just don't relish sitting through a 12 hour youtube video on JS.

some kinda jackal fucked around with this message at 23:44 on Nov 2, 2023

huhu
Feb 24, 2006
Perhaps https://learnxinyminutes.com/ is what you’re looking for?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

some kinda jackal posted:

I've gotten a lot done with Node, and it's not like I'm flailing. I'm googling a lot, reading a lot of docs, but then I come across some cool concept I didn't know and I'm left wondering what else is useful that I could be making use of, even at a basic level. Absent finding anything above I still think I've had more fun programming in the past week and change than I have in the last 20 blindly groping around google for python snippets and it's really rewarding. I could probably continue blindly groping for node and TS stuff on google instead and be just fine, but I guess I find this valuable enough that I can dedicate at least some time to learn the basics. I just don't relish sitting through a 12 hour youtube video on JS.
I am really sympathetic to this particular plight because I do *all the languages* at work and it's frustrating when something comes up that isn't how you might expect (e.g. python's async/await doesn't actually set a thing in motion at all until you await that specific thing, unless you also do something with a Task, versus javascript's does, and golang's equivalent does.)

Some things that are good to know about, may not be familiar from other languages, and make a huge difference:
1. async/await (and using them without converting them into promises in almost every context)
2. if you're doing front-end, document.querySelectorAll is massive (though less so if you're also using some framework)
3. generics in typescript can solve a lot of typing problems
4. The magic of backtick strings for formatting (never do str1+" "+str2+" "+str3!)

Fun thing I learned at work yesterday - react <div>{someBigIntVariable}</div> gives an empty div, but `${someBigIntVariable}` stringifies it like you'd expect.

some kinda jackal
Feb 25, 2003

 
 
hell yeah gang, that's the stuff.

I begrudgingly started watching some JS "complete course" videos and honestly maybe I made too big a deal of complaining about it. I'm just fast forwarding 30 seconds at a time through the stuff that is plainly obvious until I run across something that I don't immediately recognize and maybe this is fine.

I didn't even know the learnX site existed. I'm definitely bookmarking that for more than just JS.

And on the hitlist stuff, that's perfect too -- you basically listed all the things I'm *aware* of, but I don't really know anything about to an extent. I know the general idea of async and promises but I'll be damned if I can tell you why I'm using them. And when I do it's just because I did it once based on a code snippet. So I've got a lot of good leads to follow.

Polio Vax Scene
Apr 5, 2009



I must be missing something about module imports.
In this page the green square is pulled towards or repelled away from your mouse when you hold left click or right click.
This is done by checking MouseHandler.leftClicked and MouseHandler.rightClicked. here is the source code.
The class TestBlock extends GameObject, and GameObject is intended to draw a yellow or red outline on the square based on the same mouse events.
However, that part isn't working - the MouseHandler values in TestBlock are different from the values in GameObject for some reason.
I'm still very new to modules, if I had to guess, it has something to do with importing the same module in both classes' js files.

MrMoo
Sep 14, 2000

That hosting is transpiling down to require() based imports separate for each module and thus there is no shared state.

Practice using the :chome: devtools, add a break point in the Render API and step through and watch the global state

.

Adbot
ADBOT LOVES YOU

Polio Vax Scene
Apr 5, 2009



thank you. I ended up making the MouseHandler a non-static prop of GameHandler and passing it to the game objects as they are updated/rendered. I'm not sure if this is the best way to do it, but it at least gives consistent state to the TestBlock and its super.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply