diff --git a/lib/helpers/regexs.js b/lib/helpers/regexs.js new file mode 100644 index 0000000..dea828c --- /dev/null +++ b/lib/helpers/regexs.js @@ -0,0 +1,13 @@ +// source: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string +export const semVerRegex = new RegExp( + /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/, +); + +export const regularVersionRegex = composeSemverRegex(/\bversion:\s*"/, /"/); +export const attributeVersionRegex = composeSemverRegex(/@version\s+"/, /"/); + +function composeSemverRegex(head, tail) { + return new RegExp( + head.source + semVerRegex.source.replace(/[\^$]/g, "") + tail.source, + ); +} diff --git a/tests/fixtures/regexs.fixture.js b/tests/fixtures/regexs.fixture.js new file mode 100644 index 0000000..43e99bb --- /dev/null +++ b/tests/fixtures/regexs.fixture.js @@ -0,0 +1,76 @@ +export const validSemVers = [ + "0.0.4", + "1.2.3", + "10.20.30", + "1.1.2-prerelease+meta", + "1.1.2+meta", + "1.1.2+meta-valid", + "1.0.0-alpha", + "1.0.0-beta", + "1.0.0-alpha.beta", + "1.0.0-alpha.beta.1", + "1.0.0-alpha.1", + "1.0.0-alpha0.valid", + "1.0.0-alpha.0valid", + "1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay", + "1.0.0-rc.1+build.1", + "2.0.0-rc.1+build.123", + "1.2.3-beta", + "10.2.3-DEV-SNAPSHOT", + "1.2.3-SNAPSHOT-123", + "1.0.0", + "2.0.0", + "1.1.7", + "2.0.0+build.1848", + "2.0.1-alpha.1227", + "1.0.0-alpha+beta", + "1.2.3----RC-SNAPSHOT.12.9.1--.12+788", + "1.2.3----R-S.12.9.1--.12+meta", + "1.2.3----RC-SNAPSHOT.12.9.1--.12", + "1.0.0+0.build.1-rc.10000aaa-kk-0.1", + "99999999999999999999999.999999999999999999.99999999999999999", + "1.0.0-0A.is.legal", +]; + +export const invalidSemVers = [ + "1", + "1.2", + "1.2.3-0123", + "1.2.3-0123.0123", + "1.1.2+.123", + "+invalid", + "-invalid", + "-invalid+invalid", + "-invalid.01", + "alpha", + "alpha.beta", + "alpha.beta.1", + "alpha.1", + "alpha+beta", + "alpha_beta", + "alpha.", + "alpha..", + "beta", + "1.0.0-alpha_beta", + "-alpha.", + "1.0.0-alpha..", + "1.0.0-alpha..1", + "1.0.0-alpha...1", + "1.0.0-alpha....1", + "1.0.0-alpha.....1", + "1.0.0-alpha......1", + "1.0.0-alpha.......1", + "01.1.1", + "1.01.1", + "1.1.01", + "1.2", + "1.2.3.DEV", + "1.2-SNAPSHOT", + "1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788", + "1.2-RC-SNAPSHOT", + "-1.0.3-gamma+b7718", + "+justmeta", + "9.8.7+meta+meta", + "9.8.7-whatever+meta+meta", + "99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12", +]; diff --git a/tests/regexs.test.js b/tests/regexs.test.js new file mode 100644 index 0000000..0f61e3b --- /dev/null +++ b/tests/regexs.test.js @@ -0,0 +1,86 @@ +import { + attributeVersionRegex, + regularVersionRegex, + semVerRegex, +} from "../lib/helpers/regexs"; +import { invalidSemVers, validSemVers } from "./fixtures/regexs.fixture"; + +describe("semVerRegex", () => { + it("should match valid values", () => { + // eslint-disable-next-line jest/prefer-expect-assertions + expect.assertions(validSemVers.length); + + for (let semVer of validSemVers) { + expect(semVer).toMatch(new RegExp("^" + semVerRegex.source + "$")); + } + }); + + it("should not match invalid values", () => { + // eslint-disable-next-line jest/prefer-expect-assertions + expect.assertions(invalidSemVers.length); + + for (let semVer of invalidSemVers) { + expect(semVer).not.toMatch(new RegExp("^" + semVerRegex.source + "$")); + } + }); +}); + +describe("regularVersionRegex", () => { + it("should match valid values", () => { + // eslint-disable-next-line jest/prefer-expect-assertions + expect.assertions(validSemVers.length * 3); + + for (let semVer of validSemVers) { + expect(`version:"${semVer}"`).toMatch(regularVersionRegex); + expect(` version: "${semVer}" ,`).toMatch(regularVersionRegex); + expect(` version: "${semVer}" ,`).toMatch(regularVersionRegex); + } + }); + + it("should not match invalid values", () => { + // eslint-disable-next-line jest/prefer-expect-assertions + expect.assertions(validSemVers.length * 5 + invalidSemVers.length); + + for (let semVer of validSemVers) { + expect(`version: ${semVer}`).not.toMatch(regularVersionRegex); + expect(`version "${semVer}"`).not.toMatch(regularVersionRegex); + expect(`versin: "${semVer}",`).not.toMatch(regularVersionRegex); + expect(`"~> ${semVer}"`).not.toMatch(regularVersionRegex); + expect(`tag: "${semVer}",`).not.toMatch(regularVersionRegex); + } + + for (let semVer of invalidSemVers) { + expect(`version: "${semVer}"`).not.toMatch(regularVersionRegex); + } + }); +}); + +describe("attributeVersionRegex", () => { + it("should match valid values", () => { + // eslint-disable-next-line jest/prefer-expect-assertions + expect.assertions(validSemVers.length * 3); + + for (let semVer of validSemVers) { + expect(`@version "${semVer}"`).toMatch(attributeVersionRegex); + expect(` @version "${semVer}"`).toMatch(attributeVersionRegex); + expect(` @version "${semVer}"`).toMatch(attributeVersionRegex); + } + }); + + it("should not match invalid values", () => { + // eslint-disable-next-line jest/prefer-expect-assertions + expect.assertions(validSemVers.length * 5 + invalidSemVers.length); + + for (let semVer of validSemVers) { + expect(`@version ${semVer}`).not.toMatch(attributeVersionRegex); + expect(`@version"${semVer}"`).not.toMatch(attributeVersionRegex); + expect(`@versin "${semVer}"`).not.toMatch(attributeVersionRegex); + expect(`"~> ${semVer}"`).not.toMatch(attributeVersionRegex); + expect(`@tag "${semVer}"`).not.toMatch(attributeVersionRegex); + } + + for (let semVer of invalidSemVers) { + expect(`@version "${semVer}"`).not.toMatch(attributeVersionRegex); + } + }); +});