Skip to content

Commit 029341d

Browse files
committed
fix: avoid throw for invalid cases when not needed
1 parent d17aebf commit 029341d

File tree

8 files changed

+112
-17
lines changed

8 files changed

+112
-17
lines changed

benchmarks/bench-inc.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict'
2+
3+
const Benchmark = require('benchmark')
4+
const invalidVersions = require('../test/fixtures/invalid-versions')
5+
const inc = require('../functions/inc')
6+
const validVersions = require('../test/fixtures/valid-versions')
7+
const suite = new Benchmark.Suite()
8+
9+
const cases = validVersions.map(invalid => invalid[0])
10+
const invalidCases = invalidVersions.map(invalid => invalid[0])
11+
12+
for (const test of cases) {
13+
suite.add(`inc(${test})`, function () {
14+
inc(test, 'release')
15+
})
16+
}
17+
18+
for (const test of invalidCases) {
19+
suite.add(`invalid inc(${test})`, function () {
20+
inc(test, 'release')
21+
})
22+
}
23+
24+
suite
25+
.on('cycle', function (event) {
26+
console.log(String(event.target))
27+
})
28+
.run({ async: false })

benchmarks/bench-parse.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
const Benchmark = require('benchmark')
44
const parse = require('../functions/parse')
5-
const { MAX_SAFE_INTEGER } = require('../internal/constants')
5+
const validVersions = require('../test/fixtures/valid-versions')
6+
const invalidVersions = require('../test/fixtures/invalid-versions')
67
const suite = new Benchmark.Suite()
78

8-
const cases = ['1.2.1', '1.2.2-4', '1.2.3-pre']
9-
const invalidCases = [`${MAX_SAFE_INTEGER}0.0.0`, 'hello, world', 'xyz']
9+
const cases = validVersions.map(invalid => invalid[0])
10+
const invalidCases = invalidVersions.map(invalid => invalid[0])
1011

1112
for (const test of cases) {
1213
suite.add(`parse(${test})`, function () {

benchmarks/bench-valid.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict'
2+
3+
const Benchmark = require('benchmark')
4+
const invalidVersions = require('../test/fixtures/invalid-versions')
5+
const valid = require('../functions/valid')
6+
const validVersions = require('../test/fixtures/valid-versions')
7+
const suite = new Benchmark.Suite()
8+
9+
const cases = validVersions.map(invalid => invalid[0])
10+
const invalidCases = invalidVersions.map(invalid => invalid[0])
11+
12+
for (const test of cases) {
13+
suite.add(`valid(${test})`, function () {
14+
valid(test)
15+
})
16+
}
17+
18+
for (const test of invalidCases) {
19+
suite.add(`invalid valid(${test})`, function () {
20+
valid(test)
21+
})
22+
}
23+
24+
suite
25+
.on('cycle', function (event) {
26+
console.log(String(event.target))
27+
})
28+
.run({ async: false })

classes/semver.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,17 @@ const { safeRe: re, t } = require('../internal/re')
66

77
const parseOptions = require('../internal/parse-options')
88
const { compareIdentifiers } = require('../internal/identifiers')
9+
10+
function handleErrorOnSemver (semver, errorMessage, throwErrors) {
11+
if (throwErrors) {
12+
throw new TypeError(errorMessage)
13+
} else {
14+
semver.errorMessage = errorMessage
15+
}
16+
}
17+
918
class SemVer {
10-
constructor (version, options) {
19+
constructor (version, options, throwErrors = true) {
1120
options = parseOptions(options)
1221

1322
if (version instanceof SemVer) {
@@ -18,13 +27,11 @@ class SemVer {
1827
version = version.version
1928
}
2029
} else if (typeof version !== 'string') {
21-
throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`)
30+
return handleErrorOnSemver(this, `Invalid version. Must be a string. Got type "${typeof version}".`, throwErrors)
2231
}
2332

2433
if (version.length > MAX_LENGTH) {
25-
throw new TypeError(
26-
`version is longer than ${MAX_LENGTH} characters`
27-
)
34+
return handleErrorOnSemver(this, `version is longer than ${MAX_LENGTH} characters`, throwErrors)
2835
}
2936

3037
debug('SemVer', version, options)
@@ -37,7 +44,7 @@ class SemVer {
3744
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
3845

3946
if (!m) {
40-
throw new TypeError(`Invalid Version: ${version}`)
47+
return handleErrorOnSemver(this, `Invalid Version: ${version}`, throwErrors)
4148
}
4249

4350
this.raw = version
@@ -48,15 +55,15 @@ class SemVer {
4855
this.patch = +m[3]
4956

5057
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
51-
throw new TypeError('Invalid major version')
58+
return handleErrorOnSemver(this, 'Invalid major version', throwErrors)
5259
}
5360

5461
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
55-
throw new TypeError('Invalid minor version')
62+
return handleErrorOnSemver(this, 'Invalid minor version', throwErrors)
5663
}
5764

5865
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
59-
throw new TypeError('Invalid patch version')
66+
return handleErrorOnSemver(this, 'Invalid patch version', throwErrors)
6067
}
6168

6269
// numberify any prerelease numeric ids

functions/inc.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const SemVer = require('../classes/semver')
4+
const parse = require('./parse')
45

56
const inc = (version, release, options, identifier, identifierBase) => {
67
if (typeof (options) === 'string') {
@@ -9,11 +10,14 @@ const inc = (version, release, options, identifier, identifierBase) => {
910
options = undefined
1011
}
1112

13+
const parsed = parse(version instanceof SemVer ? version.version : version, options)
14+
15+
if (parsed === null) {
16+
return null
17+
}
18+
1219
try {
13-
return new SemVer(
14-
version instanceof SemVer ? version.version : version,
15-
options
16-
).inc(release, identifier, identifierBase).version
20+
return parsed.inc(release, identifier, identifierBase).version
1721
} catch (er) {
1822
return null
1923
}

functions/parse.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const parse = (version, options, throwErrors = false) => {
55
if (version instanceof SemVer) {
66
return version
77
}
8+
89
try {
910
return new SemVer(version, options)
1011
} catch (er) {

test/classes/semver.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ test('invalid version numbers', (t) => {
9797
t.end()
9898
})
9999

100+
test('invalid version numbers without throw', (t) => {
101+
['1.2.3.4', 'NOT VALID', 1.2, null, 'Infinity.NaN.Infinity'].forEach((v) => {
102+
const parsed = new SemVer(v, undefined, false)
103+
104+
t.strictSame(parsed.errorMessage, typeof v === 'string'
105+
? `Invalid Version: ${v}`
106+
: `Invalid version. Must be a string. Got type "${typeof v}".`
107+
)
108+
})
109+
110+
t.end()
111+
})
112+
100113
test('incrementing', t => {
101114
t.plan(increments.length)
102115
increments.forEach(([

test/functions/inc.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const increments = require('../fixtures/increments.js')
88
test('increment versions test', (t) => {
99
increments.forEach(([pre, what, wanted, options, id, base]) => {
1010
const found = inc(pre, what, options, id, base)
11-
const cmd = `inc(${pre}, ${what}, ${id}, ${base})`
11+
const cmd = `inc(${pre}, ${what}, ${options}, ${id}, ${base})`
1212
t.equal(found, wanted, `${cmd} === ${wanted}`)
1313

1414
const parsed = parse(pre, options)
@@ -45,3 +45,16 @@ test('increment versions test', (t) => {
4545

4646
t.end()
4747
})
48+
49+
test('special increment version test', (t) => {
50+
[
51+
['1.2.3', 'prepatch', '1.2.4-foo.1', 'foo', '1', undefined],
52+
['1.2.3', 'prepatch', '1.2.4-foo.1', {}, 'foo', '1'],
53+
].forEach(([pre, what, wanted, options, id, base]) => {
54+
const found = inc(pre, what, options, id, base)
55+
const cmd = `inc(${pre}, ${what}, ${options}, ${id}, ${base})`
56+
t.equal(found, wanted, `${cmd} === ${wanted}`)
57+
})
58+
59+
t.end()
60+
})

0 commit comments

Comments
 (0)