bhouston / threeify

A Typescript 3D library loosely based on three.js
http://threeify.org
Other
199 stars 15 forks source link

Adopt github actions to run unit tests. #5

Open bhouston opened 4 years ago

bhouston commented 4 years ago

What is the most popular unit test framework these days? I think it is jest.

pailhead commented 4 years ago

There is no configuration for the build tools other than tsconfig? Maybe a good start would be to just install jest properly, so that it works with typescript? I'm not sure if this is as straightforward as one might think.

bhouston commented 4 years ago

We can move back to webpack? I had webpack initially but this PR removed it: https://github.com/bhouston/threeify/pull/1 We can go back to webpack -- I do think it is likely the best path forward as its configurability is extreme.

I've already run into the problem that the TypeScript builder doesn't package up glsl files properly -- and I do not believe it is fixable without moving away from the tsconfig builder.

/ping @justinfagnani ?

justinfagnani commented 4 years ago

The configurability of Webpack is the problem. It supports all kinds of things that browsers don't actually support. So if you want you code to load in browsers without a bundler, or with bundlers that don't support non-standard behavior (Snowpack, Vite, Rollup without the right plugins, etc.) you'll have to be very careful not to use most of Webpack's features. At that point Webpack will mainly slow development down.

You can certainly test without bundling. I'm not sure what the intersection with Webpack is for this topic.

bhouston commented 4 years ago

Jest requires Babel according to @pailhead ... But maybe that requires further investigation to confirm...

pailhead commented 4 years ago

Open to suggestions. Please advise.

pailhead commented 4 years ago

I guess what I don’t understand is, this is typescript, it’s bound to be “bundled” or at least transpiled? I think this is the issue with jest. I haven’t had time to dig into all this, I’ll just investigate what’s the minimum amount of dependencies / tooling required to run jest.

bhouston commented 4 years ago

I think the way to do this is to have the tests written in Typescript in the /src directory. Have the tsc (the typescript compiler) convert them to JavaScript and place them in the /dist directory. This happens automatically when we run "npm run dev". Then we set it up so that the tests from /dist via JavaScript. Something like "npm run tests" which reaches into /dist and runs jest from there after the compile is done.

This is all in the spirit of what @ustinfagnani is mentioning in general on twitter. This project, since it is intended to be a library, shouldn't use a bundler for its own library. Instead it should just focus on producing JavaScript modules as many individual JS files in the /dist directory. This can then be used by other people's bundlers in an efficient fashion -- and tree shaken as well effectively. We could also use a bundler for our examples, but not within our core library.

I think the key issue is does Jest support running off of JS modules directly? I suspect it can, especially if we run it through the TS compiler as well.

Does this make sense?

justinfagnani commented 4 years ago

@bhouston that's right.

Though on the testing topic I would question using Jest. My understanding is that Jest is normally run through jsdom on Node. Shouldn't you test in a real browser? jsdom doesn't have <script type='module'> support yet, afaik.

When testing native modules I tent to use Karma with open-wc.org's Karma + ESM helpers.

pailhead commented 4 years ago

I may have volunteered for this task to eagerly :)

My understanding is that with a (sort of) a refactor project like this, it is a good opportunity to implement unit tests. Both to help the task at hand and to increase confidence in the future. This is why unit tests matter?

My limited understanding of testing in general, makes it seem so that these frameworks are more or less the same. The syntax and patterns seem very similar if not the same.

Finally, I understand that the issue discussed here is which framework is the most compatible with the way this library is currently being built, but also considering alternatives. I understand that some things are in flux, but not which.

The goal of this project is to build some JavaScript on it's own, that's module compatible? Ie. /src/foo.ts -> /dist/foo.es6module.js ?

Is it feasible that i as a user don't care about this, if the project on my end is not using modules at all, but the only js is some massive monolithic bundle.js? Or is this more of a thing that bundles, chunks and what not are going away in favor of these <script type='module'> so in the former scenario, i should consider what's the modern way of doing this? I somehow expected that if using *.ts files from some library, i shouldn't care what it does in terms of modules and it's path to generating something that browsers can read, since TS is not a browser thing at all. Does this break the whole goal of tree shaking and such?

My understanding was that when testing, i want to implement:

//feature.ts

export const feature: SomeType<T> = (input: SomeInterface) : SomeResultType => { ...lots of types }

And then at the same time, have the ability to write a:

//feature.test.ts
import {feature} from './feature'

it( 'Should execute without errors', ()=> {
  expect(feature()).toBe(...)
}

As i'm writing this test, i half expected to be in TS land, where i see the types, my IDE understands them etc. Where does this fit this understanding, if at all?

Shouldn't you test in a real browser?

edit

I see, so both the tests and source would be transpiled, and then some testing framework would just run those plain javascript tests.

pailhead commented 4 years ago

To clarify the issue with jest should be:

//feature.test.ts
import {feature} from './feature' //ERROR

Because it would not know how to interpret a .ts file, that's if it even is able to read the test.ts (since you could just write a plain js test file).

For this to work it seems like it requires babel. It doesn't matter if you're using webpack, i don't think there's a specific webpack config or approach, it just means that its most likely transpiling things, and if so, babel needs to be set up to mimic the webpack config. That was at least my understanding, this is an area where i want to grow :)

Karma actually spins up an instance of Chrome?

pailhead commented 4 years ago

@justinfagnani could you maybe add/propose new tasks here: https://github.com/bhouston/threeify/issues/10

Maybe just define what the outcome of jest v karma v something else could be?

Astrak commented 4 years ago

@pailhead jest works with typescript through ts-jest. That module needs to be passed in the jest config, e.g. in the package.json:


{
  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node",
    "testRegex": "tests/unit-tests/",
    "rootDir": "."
  }
}
munrocket commented 4 years ago

Zora and tape-modern uses pure ESM approach and works in browser and in node. But I am not sure here, they not popular.