Skip to content
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

WIP: Add source map spec tests #505

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

takikawa
Copy link
Contributor

This is a draft PR for issue #504.

The PR adds integration to run the in-development source map specification tests. The tests are accessed via a git submodule, though the current location of the tests is likely not their final official location. The tests are still under development as well.

This commit adds a submodule for the draft source map spec test repo and adds a
new test file that runs each of the test cases. Some test cases that have known
failures are skipped, with a comment explaining why.
In an indexed map, the offset line & column are stored 1-based. However, the
lookup for originalPositionFor was not incrementing the 0-based column from the
API argument.
Comment on lines +21 to +50
// Known failures due to intentional implementation choices or due to bugs.
const skippedTests = [
// Versions are explicitly checked a bit loosely.
"versionNumericString",
// Stricter sources array checking isn't implemented.
"sourcesNotStringOrNull",
"sourcesAndSourcesContentBothNull",
// Stricter names array checking isn't implemented.
"namesMissing",
"namesNotString",
// This check isn't as strict in this library.
"invalidMappingNotAString1",
// A mapping segment with no fields is technically invalid in the spec.
"invalidMappingSegmentWithZeroFields",
// These tests fail due to imprecision in the spec about the 32-bit limit.
"invalidMappingSegmentWithColumnExceeding32Bits",
"invalidMappingSegmentWithOriginalLineExceeding32Bits",
"invalidMappingSegmentWithOriginalColumnExceeding32Bits",
// A large VLQ that should parse, but currently does not.
"validMappingLargeVLQ",
// The library currently doesn't check the types of offset lines/columns.
"indexMapOffsetLineWrongType",
"indexMapOffsetColumnWrongType",
// The spec is not totally clear about this case.
"indexMapInvalidBaseMappings",
// The spec's definition of overlap can be refined
"indexMapInvalidOverlap",
// Not clear if this test makes sense, but spec isn't clear on behavior
"validMappingNullSources"
]
Copy link
Collaborator

@bomsy bomsy May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these skipped tests specific to the mozilla sourcemap implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for example the "versionNumericString" test is skipped because this library specifically accepts the case where the version field is a number in a string. Other implementations have different behavior (e.g., the source map validator uses this library but layers more strict checking on top).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok thanks. that makes sense. Fixing these will help align to the spec.

exports[`test from source map spec tests, name: ${testCase.name}`] =
async function (assert) {
const json = await readJSON(`./source-map-tests/resources/${testCase.sourceMapFile}`);
let sourceMapFailed = false;
Copy link
Collaborator

@bomsy bomsy May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem to be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching that, I think it was a vestige of an earlier attempt. I'll remove it next time I update the patch.

@bomsy
Copy link
Collaborator

bomsy commented May 8, 2024

Thanks for this patch. this is looking great. I just had a quick look. I'll be testing it in a little bit

@takikawa
Copy link
Contributor Author

takikawa commented May 9, 2024

Note: I updated the patch with support for checking generated->original mapping (before it just checked original->generated). Now it depends on PR #507 as well.

I also updated it with checking for transitive mapping. Both of these are pretty localized changes.

map.eachMapping(() => {});
map.destroy();
} catch (exn) {
if (testCase.sourceMapIsValid)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (testCase.sourceMapIsValid)
if (testCase.sourceMapShouldBeValid)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not related directly to this patch but it just a tiny suggestion while trying the understanding the code.
sourceMapShouldBeValid might make it clearer what the expectation is.

if (!testCase.sourceMapIsValid)
assert.fail("Expected invalid source map but loaded successfully");
if (testCase.testActions) {
for (let testAction of testCase.testActions) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (let testAction of testCase.testActions) {
for (const testAction of testCase.testActions) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could use const since testAction is not reassigned.

column: action.generatedColumn,
});

for (let intermediateMapPath of action.intermediateMaps) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (let intermediateMapPath of action.intermediateMaps) {
for (const intermediateMapPath of action.intermediateMaps) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since intermediateMapPath is not reassigned

return SourceMapConsumer.with(rawSourceMap, null, (consumer) => {
let mappedPosition = consumer.generatedPositionFor({
source: action.originalSource,
line: action.originalLine + 1,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
line: action.originalLine + 1,
line: mapLine(action.originalLine),
function mapLine(line) {
  return line + 1;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we seem to be adding 1 to all the lines in most places here, we can have a util function which adds the line.

@bomsy
Copy link
Collaborator

bomsy commented May 30, 2024

Thanks @takikawa. I tested out the patch and it works nicely. I've added a few inline comments.

Once the tests have been moved to the main repo we can updated and land this patch. Do you know the timeline for this?

Also could we automate the update of the git sub-module by adding the command to the npm task for running tests in the package.json
This simple task seems to work for me.

"test": "git submodule update --init --recursive; node test/run-tests.js",

This is a basic inital solution, it can be improved with followups later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants