-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(testing): fix tests on windows #131
Conversation
b6aa6f3
to
f7f2298
Compare
0a895df
to
8f34d19
Compare
941f27d
to
c6155df
Compare
c6155df
to
c9a589c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really great to have this fixed finally, so that the codebase is now usable on Windows 😅
As discussed, I created a follow-up for automatically checking it: #141
const osAuditOutput = | ||
platform() === 'win32' | ||
? JSON.stringify(audits) | ||
: "'" + JSON.stringify(audits) + "'"; | ||
|
||
const filePath = join(process.cwd(), 'tmp/report.json'); | ||
const unixFilePath = toUnixPath(filePath); | ||
|
||
expect(createFileWriteRunnerConfig(audits, filePath)).toStrictEqual({ | ||
command: 'echo', | ||
args: [osAuditOutput, '>', unixFilePath], | ||
outputFile: unixFilePath, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test code is basically the same as the function it's testing. If we're gonna test this (not sure it makes sense to test a testing utility 🤔), I would have different test cases per OS (mock os.platform()
value).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I did that, I would then be testing the unix path function which already has separate tests. Removed.
args: [auditOutput, '>', toUnixPath(outputFilePath)], | ||
outputFile: toUnixPath(outputFilePath), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be UNIX paths on Windows? 🤨
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe path.join or path.normalize could be used instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just outputFile: outputFilePath
should be fine, the file path should be platform-dependant.
The toUnixPath
function is needed by the ESLint plugin, because it emits source file issues and needs to convert them from absolute platform-dependant paths to relative Git paths. I'm not aware of any other use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you say so. I wanted to make sure that the resulting path would be safe but if that is the responsibility of the caller, sure.
@@ -7,6 +7,7 @@ | |||
"dependencies": { | |||
"@code-pushup/models": "*", | |||
"@code-pushup/core": "*", | |||
"@code-pushup/utils": "*", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, @code-pushup/utils
is imported only in test files and packages/cli/code-pushup.config.ts
. So I don't think this dependency should be here. The lint rule takes only imports in "production" files into account, which are configured here in nx.json
.
I believe we're just missing a glob which will exclude the config files (since we're only using those for testing) - probably something like ['**/*/code-pushup.config.*.ts', '**/*/code-pushup.config.*.js', '**/*/code-pushup.config.*.mjs']
.
Alternatively, we can rename this file to code-pushup.config.mock.ts
and then it should be excluded without changing the configuration. Maybe that's better, because it's explicitly marked as testing-only 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement of testing! Left some comments.
'--verbose', | ||
'--persist.format=stdout', | ||
], | ||
args: [cliPath, 'collect', '--verbose', '--persist.format=stdout'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to generate the args in a more maintainable way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was written by @matejchalk, I merely extracted one of the arguments to a variable. What do you think about this suggestion?
From my point of view, having arguments as an explicit array increases the test readability which is what you want in test code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't see the point of objectToCliArgs
, to be honest. This CLI notation is what the user sees, which makes it more fitting for an E2E test, the wrapper function just obfuscates it.
}, | ||
], | ||
)}')`, | ||
runner: createFileWriteRunnerConfig( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have mock functions in models for that situation living in the test/fixture
folder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a function that is reusable for multiple tests (currently in cli and lighthouse plugin) and otherwise would need to be duplicated. In one of my new issues, I plan to address this by extracting reusable functions to a separate package instead of duplicating logic in multiple packages.
import { AuditOutputs, PluginConfig } from '@code-pushup/models'; | ||
import { createFileWriteRunnerConfig } from '@code-pushup/utils'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets move this into models/test/fixtures/runner.config.mock.ts
please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, this function cannot live in the models
package as it would cause a circular dependency. Until a separate testing utils package is created, Matthew advised me to add it to utils
and account for one separate usage by duplicating the function logic.
@@ -17,6 +17,7 @@ | |||
"skipDefaultLibCheck": true, | |||
"baseUrl": ".", | |||
"resolveJsonModule": true, | |||
"allowSyntheticDefaultImports": true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what code do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to mock platform for unit tests, I needed to create a spy for the os.platform()
which required import directly from os
. Unfortunately, this caused a default export TS error and I had to override it with this option.
There were too many conflicts so I created a new branch and PR #165 |
In this PR, I identified and fixed various issue while running tests in the Windows environment: - shell needs to be specified to run programs in command shell on Windows, as described [here](https://stackoverflow.com/questions/60386867/node-spawn-child-process-not-working-in-windows) - path notation on Windows is different - JSON formatting is different for UNIX and Windows - writing into files replaced by echo command which works seamlessly on Windows - glob patterns require extra quotation marks for argument expansion on Linux - recreating tmp folder caused issues for me so I partially fixed it via adding the recursive option Note: This is the same scope as #131. Unfortunately, merging changes from the test refactor did not go well so I started off a clean branch and re-applied the changes.
In this PR, I identified and fixed various issue while running tests in the Windows environment:
echo
command which works seamlessly on WindowsI also extracted the runner config for writing report into a file to a separate function (there was a lot of duplicate code to keep consistent).