Conversation
Conflicts: lib/Generate.js lib/RunTests.js
jfmengels
left a comment
There was a problem hiding this comment.
Great work I'm not sure I reviewed everything, it was a lot of changes, but here are a few suggestions I have.
I think at this point it would be better for me to review by trying it out. If you have some instructions on how to use the 2 branches together, I would love to see them.
|
|
||
|
|
||
| sendResult : Int -> Bool -> String -> List String -> Maybe String -> Decode.Value -> Decode.Value -> Cmd msg | ||
| sendResult testId isFuzzTest jsDefinitionName labels expectationElmCode debugLogs report = |
There was a problem hiding this comment.
Maaaybe worth using a record to make function calls easier to read?
There was a problem hiding this comment.
The call sites look like this:
Ports.sendResult testId False jsDefinitionName labels expectationElmCode debugLogs reportPorts.sendResult testId True jsDefinitionName labels expectationElmCode debugLogs reportSo a record would mostly be 🦜 (but give a name to the boolean).
I wonder what’s faster, passing a big record or many parameters. My guess would be many parameters (up to a point).
There was a problem hiding this comment.
Alright that's fair.
I wonder what’s faster, passing a big record or many parameters.
Haven't checked it, but I'm pretty sure many parameters is faster. (will try to add a benchmark for that in my benchmark repo 👀 )
| outcome = | ||
| outcomeFromExpectations (config.run ()) | ||
| -- The unnecessary-looking tuple here ensures that `getAndClearDebugLogs` | ||
| -- runs _after_ the thunk. |
There was a problem hiding this comment.
You could also do
let
( expectation, duration ) =
runWithDuration (\() -> Runner.runUnitTest unitTest)
-- ...
in
sendUnitTestResult testId unitTest cachedExpectation duration (getAndClearDebugLogs False) model.testReporteror
let
( expectation, duration ) =
runWithDuration (\() -> Runner.runUnitTest unitTest)
in
let
debugLogs =
getAndClearDebugLogs False
-- ...
in
-- ...In both cases, this is a clearer sign that getAndClearDebugLogs will be called after runWithDuration. The order of computation of a tuple seems too incidental to rely on comfortably I'd say. (Also, one less tuple allocation)
I think a comment indicating that getAndClearDebugLogs has to be computed afterwards because it relies on side-effects from runWithDuration would be welcome still.
| cachedExpectation = | ||
| case expectation of | ||
| UnitTestPass -> | ||
| CachedUnitTestPass |
There was a problem hiding this comment.
I feel like the conversion a custom type is unnecessary, especially as it gets reconverted to something else right away in sendUnitTestResult
There was a problem hiding this comment.
It is this way because sendUnitTestResult is also called in a different place – where we read test expectations from cache instead of running tests.
| Nothing | ||
|
|
||
| else | ||
| Just (Debug.toString expectation) |
There was a problem hiding this comment.
What is the output of this? Would it start with CachedUnitTestFail ...? If so, that feels a bit odd.
There was a problem hiding this comment.
Yes, for example:
CachedUnitTestFail { description = "Expect.equal", reason = Equality "\" blah\"" "\"blah\"" }It can also be CachedUnitTestPass if there are debug logs.
Why does it feel a bit odd?
There was a problem hiding this comment.
Maybe I should mention that it is used for codegen:ing the cache file.
| ) | ||
| .replace( | ||
| getAndClearDebugLogsDefinition, | ||
| '$1 = paused => { var logs = _Json_wrap(_Debug_logs); _Debug_logs = []; _Debug_logPaused = paused; return logs; }' |
There was a problem hiding this comment.
Use function(paused) instead of => to keep compiling to ES5?
| getAndClearDebugLogs True | ||
| |> (\_ -> |
There was a problem hiding this comment.
Seems like there's a number of places where we ignre the returned logs. Should there be a variant of getAndClearDebugLogs that simply clears Debug.logs?
| * @returns { void } | ||
| */ | ||
| function makeAcyclicStep(graph) { | ||
| const scc = Tarjan.stronglyConnectedComponents({ |
There was a problem hiding this comment.
Do you know if these chains are reduced to their smallest possible cycles? (Similar to the Elm import cycle sometimes including unrelated modules)
There was a problem hiding this comment.
I don’t. All I know is that I naively “solved” recursive function chains myself, and kept finding cases where it broke. Then I read up on it and learned that it is a well-known computer science graph problem, and that Tarjan’s algorithm can solve it. Then I found an implementation of it on npm with lots of dependents that looked good. Since I started using it I haven’t run into issues.
Co-authored-by: Jeroen Engels <jfm.engels@gmail.com>
In elm-explorations/test, run In node-test-runner:
To test it on some other project’s test suite:
|
Use
Test.RunnerV2from elm-explorations/test#260, and implement everything that unlocks.More info coming soon.