Skip to content

Commit

Permalink
Chore: use semver public API's. (#99)
Browse files Browse the repository at this point in the history
Add a '<' before the minimum version of features to make semver range
representing all versions that do not support the feature.  Add '>='
before the version if provided through options to produce a semver
range.  If the two ranges intersect then report use of an unsupported
feature.
  • Loading branch information
coreyfarrell authored and mysticatea committed Dec 7, 2017
1 parent d5a8985 commit 846e677
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 72 deletions.
83 changes: 15 additions & 68 deletions lib/rules/no-unsupported-features.js
Expand Up @@ -38,7 +38,6 @@ const VERSION_SCHEMA = {
],
}
const DEFAULT_VERSION = "4.0.0"
const MINIMUM_VERSION = "0.0.0"
const OPTIONS = Object.keys(features)
const FUNC_TYPE = /^(?:Arrow)?Function(?:Declaration|Expression)$/
const CLASS_TYPE = /^Class(?:Declaration|Expression)$/
Expand Down Expand Up @@ -84,39 +83,11 @@ const PROPERTY_TEST_TARGETS = {
],
}

/**
* Get the smaller value of the given 2 semvers.
* @param {string|null} a A semver to compare.
* @param {string} b Another semver to compare.
* @returns {string} The smaller value.
*/
function min(a, b) {
return (
a == null ? b :
semver.lt(a, b) ? a :
/* otherwise */ b
)
}

/**
* Get the larger value of the given 2 semvers.
* @param {string|null} a A semver to compare.
* @param {string} b Another semver to compare.
* @returns {string} The larger value.
*/
function max(a, b) {
return (
a == null ? b :
semver.gt(a, b) ? a :
/* otherwise */ b
)
}

/**
* Gets default version configuration of this rule.
*
* This finds and reads 'package.json' file, then parses 'engines.node' field.
* If it's nothing, this returns '4'.
* If it's nothing, this returns null.
*
* @param {string} filename - The file name of the current linting file.
* @returns {string} The default version configuration.
Expand All @@ -125,38 +96,7 @@ function getDefaultVersion(filename) {
const info = getPackageJson(filename)
const nodeVersion = info && info.engines && info.engines.node

try {
const range = new semver.Range(nodeVersion)
const comparators = Array.prototype.concat.apply([], range.set)
const ret = comparators.reduce(
(lu, comparator) => {
const op = comparator.operator
const v = comparator.semver

if (op === "" || op === ">=") {
lu.lower = min(lu.lower, `${v.major}.${v.minor}.${v.patch}`)
}
else if (op === ">") {
lu.lower = min(lu.lower, `${v.major}.${v.minor}.${v.patch + 1}`)
}

if (op === "" || op === "<=" || op === "<") {
lu.upper = max(lu.upper, `${v.major}.${v.minor}.${v.patch}`)
}

return lu
},
{lower: null, upper: null}
)

if (ret.lower == null && ret.upper != null) {
return MINIMUM_VERSION
}
return ret.lower || DEFAULT_VERSION
}
catch (_err) {
return DEFAULT_VERSION
}
return nodeVersion ? semver.validRange(nodeVersion) : null
}

/**
Expand Down Expand Up @@ -199,7 +139,8 @@ function isIgnored(key, ignores) {
* @returns {object} Parsed value.
*/
function parseOptions(options, defaultVersion) {
let version = defaultVersion
let version = defaultVersion ? null : DEFAULT_VERSION
let range = null
let ignores = []

if (typeof options === "number") {
Expand All @@ -211,10 +152,16 @@ function parseOptions(options, defaultVersion) {
else if (typeof options === "object") {
version = (typeof options.version === "number")
? VERSION_MAP.get(options.version)
: options.version || defaultVersion
: options.version

ignores = options.ignores || []
}

range = semver.validRange(version ? `>=${version}` : defaultVersion)
if (!version) {
version = defaultVersion
}

return Object.freeze({
version,
features: Object.freeze(OPTIONS.reduce(
Expand All @@ -233,8 +180,8 @@ function parseOptions(options, defaultVersion) {
retv[key] = Object.freeze({
name: feature.name,
singular: Boolean(feature.singular),
supported: semver.gte(version, feature.node),
supportedInStrict: semver.gte(version, feature.node),
supported: !semver.intersects(range, `<${feature.node}`),
supportedInStrict: !semver.intersects(range, `<${feature.node}`),
})
}
else {
Expand All @@ -244,11 +191,11 @@ function parseOptions(options, defaultVersion) {
supported:
feature.node != null &&
feature.node.sloppy != null &&
semver.gte(version, feature.node.sloppy),
!semver.intersects(range, `<${feature.node.sloppy}`),
supportedInStrict:
feature.node != null &&
feature.node.strict != null &&
semver.gte(version, feature.node.strict),
!semver.intersects(range, `<${feature.node.strict}`),
})
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -29,7 +29,7 @@
"ignore": "^3.3.6",
"minimatch": "^3.0.4",
"resolve": "^1.3.3",
"semver": "5.3.0"
"semver": "^5.4.1"
},
"devDependencies": {
"codecov": "^2.2.0",
Expand Down
6 changes: 3 additions & 3 deletions tests/lib/rules/no-unsupported-features.js
Expand Up @@ -1186,7 +1186,7 @@ ruleTester.run("no-unsupported-features", rule, [
filename: fixture("gte-0.12.8/a.js"),
code: "var a = () => 1",
env: {es6: true},
errors: ["Arrow functions are not supported yet on Node 0.12.8."],
errors: ["Arrow functions are not supported yet on Node >=0.12.8."],
},
{
filename: fixture("invalid/a.js"),
Expand All @@ -1200,7 +1200,7 @@ ruleTester.run("no-unsupported-features", rule, [
code: "var a = () => 1",
parserOptions: {ecmaVersion: 2017},
env: {es6: true},
errors: ["Arrow functions are not supported yet on Node 0.0.0."],
errors: ["Arrow functions are not supported yet on Node <6.0.0."],
},
{
filename: fixture("nothing/a.js"),
Expand All @@ -1213,7 +1213,7 @@ ruleTester.run("no-unsupported-features", rule, [
filename: fixture("gte-7.5.0/a.js"),
code: "var a = async () => 1",
parserOptions: {ecmaVersion: 2017},
errors: ["Async functions are not supported yet on Node 7.5.0."],
errors: ["Async functions are not supported yet on Node >=7.5.0."],
},
{
code: "var a = async () => 1",
Expand Down

0 comments on commit 846e677

Please sign in to comment.