From b9e574088f53052c6d13fc0c212896184dc45a2f Mon Sep 17 00:00:00 2001 From: nlf Date: Mon, 11 Sep 2023 08:54:15 -0700 Subject: [PATCH] fix: allow semver arguments to be reversed (#31) these changes allow the static semver value provided to the `:semver` pseudo selector to be placed in either the first or second parameter. that information is then used when calling the `subset` semver function to allow users to reverse the parameters. --- lib/index.js | 60 +- tap-snapshots/test/index.js.test.cjs | 959 +++++++++++++++++++++++++-- test/index.js | 24 + 3 files changed, 970 insertions(+), 73 deletions(-) diff --git a/lib/index.js b/lib/index.js index 9373a4f..c7888d5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -85,31 +85,57 @@ const fixupNestedPseudo = astNode => { transformAst(newRootNode) } -// :semver(, [selector], [function]) +// :semver(, [version|range|selector], [function]) +// note: the first or second parameter must be a static version or range const fixupSemverSpecs = astNode => { - // the first child node contains the version or range, most likely as a tag and a series of - // classes. we combine them into a single string here. this is the only required input. - const children = astNode.nodes.shift().nodes - const value = children.reduce((res, i) => `${res}${String(i)}`, '') - - // next, if we have 2 nodes left then the user called us with a total of 3. that means the - // last one tells us what specific semver function the user is requesting, so we pull that out - let semverFunc - if (astNode.nodes.length === 2) { + // if we have three nodes, the last is the semver function to use, pull that out first + if (astNode.nodes.length === 3) { const funcNode = astNode.nodes.pop().nodes[0] if (funcNode.type === 'tag') { - semverFunc = funcNode.value + astNode.semverFunc = funcNode.value + } else if (funcNode.type === 'string') { + // a string is always in some type of quotes, we don't want those so slice them off + astNode.semverFunc = funcNode.value.slice(1, -1) + } else { + // anything that isn't a tag or a string isn't a function name + throw Object.assign( + new Error('`:semver` pseudo-class expects a function name as last value'), + { code: 'ESEMVERFUNC' } + ) + } + } + + // now if we have 1 node, it's a static value + // istanbul ignore else + if (astNode.nodes.length === 1) { + const semverNode = astNode.nodes.pop() + astNode.semverValue = semverNode.nodes.reduce((res, next) => `${res}${String(next)}`, '') + } else if (astNode.nodes.length === 2) { + // and if we have two nodes, one of them is a static value and we need to determine which it is + for (let i = 0; i < astNode.nodes.length; ++i) { + const type = astNode.nodes[i].nodes[0].type + // the type of the first child may be combinator for ranges, such as >14 + if (type === 'tag' || type === 'combinator') { + const semverNode = astNode.nodes.splice(i, 1)[0] + astNode.semverValue = semverNode.nodes.reduce((res, next) => `${res}${String(next)}`, '') + astNode.semverPosition = i + break + } + } + + if (typeof astNode.semverValue === 'undefined') { + throw Object.assign( + new Error('`:semver` pseudo-class expects a static value in the first or second position'), + { code: 'ESEMVERVALUE' } + ) } } - // now if there's a node left, that node is our selector. since that is the last remaining - // child node, we call fixupAttr on ourselves so that the attribute selectors get parsed + // if we got here, the last remaining child should be attribute selector if (astNode.nodes.length === 1) { fixupAttr(astNode) } else { - // we weren't provided a selector, so we default to `[version]`. note, there's no default - // operator here. that's because we don't know yet if the user has provided us a version - // or range to assert against + // if we don't have a selector, we default to `[version]` astNode.attributeMatcher = { insensitive: false, attribute: 'version', @@ -118,8 +144,6 @@ const fixupSemverSpecs = astNode => { astNode.lookupProperties = [] } - astNode.semverFunc = semverFunc - astNode.semverValue = value astNode.nodes.length = 0 } diff --git a/tap-snapshots/test/index.js.test.cjs b/tap-snapshots/test/index.js.test.cjs index 37234aa..64d2b5a 100644 --- a/tap-snapshots/test/index.js.test.cjs +++ b/tap-snapshots/test/index.js.test.cjs @@ -444,7 +444,6 @@ exports[`test/index.js TAP > #a, #bar:semver(2), #foo 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_3>, - "semverFunc": undefined, "semverValue": "2", "source": Object { "end": Object { @@ -761,7 +760,6 @@ exports[`test/index.js TAP > #bar:semver(*) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "*", "source": Object { "end": Object { @@ -857,7 +855,6 @@ exports[`test/index.js TAP > #bar:semver(1 || 2) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "1||2", "source": Object { "end": Object { @@ -953,7 +950,6 @@ exports[`test/index.js TAP > #bar:semver(1 || 2.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "1||2.0.0", "source": Object { "end": Object { @@ -1054,6 +1050,7 @@ exports[`test/index.js TAP > #bar:semver(1.0.0, :attr(engines, [node]), satisfie "nodes": Array [], "parent": <*ref_1>, "semverFunc": "satisfies", + "semverPosition": 0, "semverValue": "1.0.0", "source": Object { "end": Object { @@ -1149,7 +1146,6 @@ exports[`test/index.js TAP > #bar:semver(1.4.0 || 2) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "1.4.0||2", "source": Object { "end": Object { @@ -1245,7 +1241,6 @@ exports[`test/index.js TAP > #bar:semver(1||2) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "1||2", "source": Object { "end": Object { @@ -1341,7 +1336,6 @@ exports[`test/index.js TAP > #bar:semver(2 - 3) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2 - 3", "source": Object { "end": Object { @@ -1437,7 +1431,6 @@ exports[`test/index.js TAP > #bar:semver(2) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2", "source": Object { "end": Object { @@ -1533,7 +1526,6 @@ exports[`test/index.js TAP > #bar:semver(2), #foo 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2", "source": Object { "end": Object { @@ -1671,7 +1663,6 @@ exports[`test/index.js TAP > #bar:semver(2.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2.0", "source": Object { "end": Object { @@ -1767,7 +1758,6 @@ exports[`test/index.js TAP > #bar:semver(2.0.0 - 3.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2.0.0 - 3.0.0", "source": Object { "end": Object { @@ -1863,7 +1853,6 @@ exports[`test/index.js TAP > #bar:semver(2.x) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2.x", "source": Object { "end": Object { @@ -1959,7 +1948,6 @@ exports[`test/index.js TAP > #bar:semver(2.x.x) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2.x.x", "source": Object { "end": Object { @@ -2055,7 +2043,6 @@ exports[`test/index.js TAP > #bar:semver(<3.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "<3.0.0", "source": Object { "end": Object { @@ -2151,7 +2138,6 @@ exports[`test/index.js TAP > #bar:semver(=2.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "=2.0.0", "source": Object { "end": Object { @@ -2247,7 +2233,6 @@ exports[`test/index.js TAP > #bar:semver(>1.5.0 <3.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": ">1.5.0 <3.0.0", "source": Object { "end": Object { @@ -2343,7 +2328,6 @@ exports[`test/index.js TAP > #bar:semver(>=2.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": ">=2.0.0", "source": Object { "end": Object { @@ -2444,6 +2428,7 @@ exports[`test/index.js TAP > #bar:semver(^1.0.0, :attr(engines, [node]), interse "nodes": Array [], "parent": <*ref_1>, "semverFunc": "intersects", + "semverPosition": 0, "semverValue": "^1.0.0", "source": Object { "end": Object { @@ -2539,7 +2524,6 @@ exports[`test/index.js TAP > #bar:semver(^2.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "^2.0.0", "source": Object { "end": Object { @@ -2635,7 +2619,6 @@ exports[`test/index.js TAP > #bar:semver(^2.0.0-beta.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "^2.0.0-beta.0", "source": Object { "end": Object { @@ -2731,7 +2714,6 @@ exports[`test/index.js TAP > #bar:semver(~2.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "~2.0.0", "source": Object { "end": Object { @@ -6701,7 +6683,6 @@ exports[`test/index.js TAP > :is(*:semver(2.0.0), :semver(=2.0.0-beta.45)) 1`] = "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2.0.0", "source": Object { "end": Object { @@ -6752,7 +6733,6 @@ exports[`test/index.js TAP > :is(*:semver(2.0.0), :semver(=2.0.0-beta.45)) 1`] = "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_3>, - "semverFunc": undefined, "semverValue": "=2.0.0-beta.45", "source": Object { "end": Object { @@ -8284,7 +8264,6 @@ exports[`test/index.js TAP > :root #bar:semver(1) > * 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "1", "source": Object { "end": Object { @@ -8470,7 +8449,6 @@ exports[`test/index.js TAP > :root #bar:semver(1) ~ * 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "1", "source": Object { "end": Object { @@ -11312,7 +11290,6 @@ exports[`test/index.js TAP > :semver() 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "", "source": Object { "end": Object { @@ -11388,7 +11365,6 @@ exports[`test/index.js TAP > :semver(*) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "*", "source": Object { "end": Object { @@ -11468,7 +11444,7 @@ exports[`test/index.js TAP > :semver(1.0.0, :attr(engines, [node])) 1`] = ` ], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, + "semverPosition": 0, "semverValue": "1.0.0", "source": Object { "end": Object { @@ -11548,7 +11524,89 @@ exports[`test/index.js TAP > :semver(1.0.0, :attr(engines, [node]), "satisfies") ], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, + "semverFunc": "satisfies", + "semverPosition": 0, + "semverValue": "1.0.0", + "source": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver(1.0.0, :attr(engines, [node]), 'satisfies') 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "node", + "operator": undefined, + "qualifiedAttribute": "node", + "value": undefined, + }, + "lookupProperties": Array [ + Symbol(arrayDelimiter), + "engines", + ], + "nodes": Array [], + "parent": <*ref_1>, + "semverFunc": "satisfies", + "semverPosition": 0, "semverValue": "1.0.0", "source": Object { "end": Object { @@ -11629,6 +11687,7 @@ exports[`test/index.js TAP > :semver(1.0.0, :attr(engines, [node]), satisfies) 1 "nodes": Array [], "parent": <*ref_1>, "semverFunc": "satisfies", + "semverPosition": 0, "semverValue": "1.0.0", "source": Object { "end": Object { @@ -11705,7 +11764,7 @@ exports[`test/index.js TAP > :semver(1.0.0, [version]) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, + "semverPosition": 0, "semverValue": "1.0.0", "source": Object { "end": Object { @@ -11783,6 +11842,7 @@ exports[`test/index.js TAP > :semver(1.0.0, [version], satisfies) 1`] = ` "nodes": Array [], "parent": <*ref_1>, "semverFunc": "satisfies", + "semverPosition": 0, "semverValue": "1.0.0", "source": Object { "end": Object { @@ -11858,7 +11918,6 @@ exports[`test/index.js TAP > :semver(1.4.0 || 2.2.2) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "1.4.0||2.2.2", "source": Object { "end": Object { @@ -11934,7 +11993,6 @@ exports[`test/index.js TAP > :semver(2 - 3) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2 - 3", "source": Object { "end": Object { @@ -12010,7 +12068,6 @@ exports[`test/index.js TAP > :semver(2.0.0) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "2.0.0", "source": Object { "end": Object { @@ -12067,7 +12124,7 @@ exports[`test/index.js TAP > :semver(2.0.0) 1`] = ` } ` -exports[`test/index.js TAP > :semver(=1.4.0) 1`] = ` +exports[`test/index.js TAP > :semver(:attr(engines, [node]), 1.0.0) 1`] = ` &ref_2 Root { "_error": Function (message, errorOptions), "indexes": Object {}, @@ -12079,18 +12136,22 @@ exports[`test/index.js TAP > :semver(=1.4.0) 1`] = ` "nodes": Array [ Pseudo { "attributeMatcher": Object { - "attribute": "version", - "insensitive": false, - "qualifiedAttribute": "version", + "attribute": "node", + "operator": undefined, + "qualifiedAttribute": "node", + "value": undefined, }, - "lookupProperties": Array [], + "lookupProperties": Array [ + Symbol(arrayDelimiter), + "engines", + ], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, - "semverValue": "=1.4.0", + "semverPosition": 1, + "semverValue": "1.0.0", "source": Object { "end": Object { - "column": 15, + "column": 38, "line": 1, }, "start": Object { @@ -12110,7 +12171,7 @@ exports[`test/index.js TAP > :semver(=1.4.0) 1`] = ` "parent": <*ref_2>, "source": Object { "end": Object { - "column": 15, + "column": 38, "line": 1, }, "start": Object { @@ -12127,7 +12188,7 @@ exports[`test/index.js TAP > :semver(=1.4.0) 1`] = ` ], "source": Object { "end": Object { - "column": 15, + "column": 38, "line": 1, }, "start": Object { @@ -12143,7 +12204,7 @@ exports[`test/index.js TAP > :semver(=1.4.0) 1`] = ` } ` -exports[`test/index.js TAP > :semver(>=2) 1`] = ` +exports[`test/index.js TAP > :semver(:attr(engines, [node]), 1.0.0, "satisfies") 1`] = ` &ref_2 Root { "_error": Function (message, errorOptions), "indexes": Object {}, @@ -12155,18 +12216,23 @@ exports[`test/index.js TAP > :semver(>=2) 1`] = ` "nodes": Array [ Pseudo { "attributeMatcher": Object { - "attribute": "version", - "insensitive": false, - "qualifiedAttribute": "version", + "attribute": "node", + "operator": undefined, + "qualifiedAttribute": "node", + "value": undefined, }, - "lookupProperties": Array [], + "lookupProperties": Array [ + Symbol(arrayDelimiter), + "engines", + ], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, - "semverValue": ">=2", + "semverFunc": "satisfies", + "semverPosition": 1, + "semverValue": "1.0.0", "source": Object { "end": Object { - "column": 12, + "column": 51, "line": 1, }, "start": Object { @@ -12186,7 +12252,7 @@ exports[`test/index.js TAP > :semver(>=2) 1`] = ` "parent": <*ref_2>, "source": Object { "end": Object { - "column": 12, + "column": 51, "line": 1, }, "start": Object { @@ -12203,7 +12269,789 @@ exports[`test/index.js TAP > :semver(>=2) 1`] = ` ], "source": Object { "end": Object { - "column": 12, + "column": 51, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver(:attr(engines, [node]), 1.0.0, 'satisfies') 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "node", + "operator": undefined, + "qualifiedAttribute": "node", + "value": undefined, + }, + "lookupProperties": Array [ + Symbol(arrayDelimiter), + "engines", + ], + "nodes": Array [], + "parent": <*ref_1>, + "semverFunc": "satisfies", + "semverPosition": 1, + "semverValue": "1.0.0", + "source": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 51, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver(:attr(engines, [node]), 1.0.0, satisfies) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "node", + "operator": undefined, + "qualifiedAttribute": "node", + "value": undefined, + }, + "lookupProperties": Array [ + Symbol(arrayDelimiter), + "engines", + ], + "nodes": Array [], + "parent": <*ref_1>, + "semverFunc": "satisfies", + "semverPosition": 1, + "semverValue": "1.0.0", + "source": Object { + "end": Object { + "column": 49, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 49, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 49, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver(:attr(engines, [node]), ^1.0.0) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "node", + "operator": undefined, + "qualifiedAttribute": "node", + "value": undefined, + }, + "lookupProperties": Array [ + Symbol(arrayDelimiter), + "engines", + ], + "nodes": Array [], + "parent": <*ref_1>, + "semverPosition": 1, + "semverValue": "^1.0.0", + "source": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 39, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver(:attr(engines, [node]), satisfies) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "node", + "operator": undefined, + "qualifiedAttribute": "node", + "value": undefined, + }, + "lookupProperties": Array [ + Symbol(arrayDelimiter), + "engines", + ], + "nodes": Array [], + "parent": <*ref_1>, + "semverPosition": 1, + "semverValue": "satisfies", + "source": Object { + "end": Object { + "column": 42, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 42, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 42, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver(=1.4.0) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "version", + "insensitive": false, + "qualifiedAttribute": "version", + }, + "lookupProperties": Array [], + "nodes": Array [], + "parent": <*ref_1>, + "semverValue": "=1.4.0", + "source": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver(>=2) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "version", + "insensitive": false, + "qualifiedAttribute": "version", + }, + "lookupProperties": Array [], + "nodes": Array [], + "parent": <*ref_1>, + "semverValue": ">=2", + "source": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver([version], 1.0.0) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "version", + "operator": undefined, + "qualifiedAttribute": "version", + "value": undefined, + }, + "lookupProperties": Array [], + "nodes": Array [], + "parent": <*ref_1>, + "semverPosition": 1, + "semverValue": "1.0.0", + "source": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 25, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver([version], 1.0.0, satisfies) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "version", + "operator": undefined, + "qualifiedAttribute": "version", + "value": undefined, + }, + "lookupProperties": Array [], + "nodes": Array [], + "parent": <*ref_1>, + "semverFunc": "satisfies", + "semverPosition": 1, + "semverValue": "1.0.0", + "source": Object { + "end": Object { + "column": 36, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 36, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 36, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver([version], ^1.0.0) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "version", + "operator": undefined, + "qualifiedAttribute": "version", + "value": undefined, + }, + "lookupProperties": Array [], + "nodes": Array [], + "parent": <*ref_1>, + "semverPosition": 1, + "semverValue": "^1.0.0", + "source": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "root", +} +` + +exports[`test/index.js TAP > :semver([version], ^1.0.0, satisfies) 1`] = ` +&ref_2 Root { + "_error": Function (message, errorOptions), + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + &ref_1 Selector { + "indexes": Object {}, + "lastEach": 1, + "nodes": Array [ + Pseudo { + "attributeMatcher": Object { + "attribute": "version", + "operator": undefined, + "qualifiedAttribute": "version", + "value": undefined, + }, + "lookupProperties": Array [], + "nodes": Array [], + "parent": <*ref_1>, + "semverFunc": "satisfies", + "semverPosition": 1, + "semverValue": "^1.0.0", + "source": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "sourceIndex": 0, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "pseudo", + "value": ":semver", + }, + ], + "parent": <*ref_2>, + "source": Object { + "end": Object { + "column": 37, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "spaces": Object { + "after": "", + "before": "", + }, + "type": "selector", + }, + ], + "source": Object { + "end": Object { + "column": 37, "line": 1, }, "start": Object { @@ -12242,7 +13090,7 @@ exports[`test/index.js TAP > :semver(^1.0.0, :attr(engines, [node])) 1`] = ` ], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, + "semverPosition": 0, "semverValue": "^1.0.0", "source": Object { "end": Object { @@ -12323,6 +13171,7 @@ exports[`test/index.js TAP > :semver(^1.0.0, :attr(engines, [node]), satisfies) "nodes": Array [], "parent": <*ref_1>, "semverFunc": "satisfies", + "semverPosition": 0, "semverValue": "^1.0.0", "source": Object { "end": Object { @@ -12399,7 +13248,7 @@ exports[`test/index.js TAP > :semver(^1.0.0, [version]) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, + "semverPosition": 0, "semverValue": "^1.0.0", "source": Object { "end": Object { @@ -12477,6 +13326,7 @@ exports[`test/index.js TAP > :semver(^1.0.0, [version], satisfies) 1`] = ` "nodes": Array [], "parent": <*ref_1>, "semverFunc": "satisfies", + "semverPosition": 0, "semverValue": "^1.0.0", "source": Object { "end": Object { @@ -12552,7 +13402,6 @@ exports[`test/index.js TAP > :semver(~2.0.x) 1`] = ` "lookupProperties": Array [], "nodes": Array [], "parent": <*ref_1>, - "semverFunc": undefined, "semverValue": "~2.0.x", "source": Object { "end": Object { diff --git a/test/index.js b/test/index.js index b6d22b6..72a6f95 100644 --- a/test/index.js +++ b/test/index.js @@ -87,14 +87,25 @@ const checks = [ [':semver(=1.4.0)'], [':semver(1.4.0 || 2.2.2)'], [':semver(1.0.0, [version])'], + [':semver([version], 1.0.0)'], [':semver(^1.0.0, [version])'], + [':semver([version], ^1.0.0)'], [':semver(1.0.0, [version], satisfies)'], + [':semver([version], 1.0.0, satisfies)'], [':semver(^1.0.0, [version], satisfies)'], + [':semver([version], ^1.0.0, satisfies)'], [':semver(1.0.0, :attr(engines, [node]))'], + [':semver(:attr(engines, [node]), 1.0.0)'], [':semver(^1.0.0, :attr(engines, [node]))'], + [':semver(:attr(engines, [node]), ^1.0.0)'], [':semver(1.0.0, :attr(engines, [node]), satisfies)'], + [':semver(:attr(engines, [node]), 1.0.0, satisfies)'], [':semver(^1.0.0, :attr(engines, [node]), satisfies)'], + [':semver(:attr(engines, [node]), satisfies)'], [':semver(1.0.0, :attr(engines, [node]), "satisfies")'], + [':semver(:attr(engines, [node]), 1.0.0, "satisfies")'], + [":semver(1.0.0, :attr(engines, [node]), 'satisfies')"], + [":semver(:attr(engines, [node]), 1.0.0, 'satisfies')"], // attr pseudo-class [':attr([name=dasher])'], @@ -183,3 +194,16 @@ t.throws( { code: 'EQUERYATTR' }, 'should throw on missing attribute matcher on :attr pseudo-class' ) + +// bogus third param to :semver +t.throws( + () => parser(':semver(14, [version], [version])'), + { code: 'ESEMVERFUNC' }, + 'should throw when third :semver param is not a tag or string' +) + +t.throws( + () => parser(':semver([version], [version])'), + { code: 'ESEMVERVALUE' }, + 'should throw when neither of the first :semver params is a static value' +)