Skip to content

Commit

Permalink
Merge pull request #47 from superfaceai/feat/version-utils
Browse files Browse the repository at this point in the history
feat: more version utils
  • Loading branch information
Jakub-Vacek authored May 11, 2021
2 parents 0ed6ed7 + c57b6fa commit e76ccef
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superfaceai/ast",
"version": "0.0.23",
"version": "0.0.25",
"description": "Superface profile and map language ASTs, https://superface.ai",
"main": "dist/language.js",
"source": "src/index.ts",
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/ast/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './map-ast.utils';
export * from './profile-ast';
export * from './profile-ast.utils';
export * from './utils';
export * from './split';
122 changes: 122 additions & 0 deletions src/interfaces/ast/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {
extractVersion,
extractVersionString,
isValidDocumentName,
isValidIdentifier,
isValidProviderName,
isValidVersionString,
parseVersionNumber,
} from './utils';

describe('utils', () => {
Expand Down Expand Up @@ -43,6 +46,7 @@ describe('utils', () => {
expect(isValidVersionString('test')).toEqual(false);
expect(isValidVersionString('1.t.0')).toEqual(false);
expect(isValidVersionString('1.0.t')).toEqual(false);
expect(isValidVersionString('1')).toEqual(true);
expect(isValidVersionString('1.0')).toEqual(true);
expect(isValidVersionString('0.0.1')).toEqual(true);
expect(isValidVersionString('1.0.0')).toEqual(true);
Expand All @@ -52,4 +56,122 @@ describe('utils', () => {
expect(isValidVersionString('1.0.0-t.t')).toEqual(false);
});
});

describe('when extracting version string', () => {
it('extracts version correctly', () => {
expect(() => extractVersionString('')).toThrow(
new Error(`Invalid empty version string`)
);
expect(() => extractVersionString('@')).toThrow(
new Error(`Invalid version string in "@"`)
);
expect(() => extractVersionString('test@test')).toThrow(
new Error(`Invalid version string in "test@test"`)
);
expect(() => extractVersionString('[email protected]')).toThrow(
new Error(`Invalid version string in "[email protected]"`)
);
expect(() => extractVersionString('1,[email protected]')).toThrow(
new Error(`Invalid version string in "1,[email protected]"`)
);
expect(extractVersionString('[email protected]')).toEqual('1.0');
expect(extractVersionString('[email protected]')).toEqual('0.0.1');
expect(extractVersionString('@1.0.0')).toEqual('1.0.0');
expect(extractVersionString('+:@9.9.9')).toEqual('9.9.9');
expect(extractVersionString(' @1.0.0-label')).toEqual('1.0.0-label');
expect(() => extractVersionString('[email protected]')).toThrow(
new Error(`Invalid version string in "[email protected]"`)
);
expect(() => extractVersionString('[email protected]')).toThrow(
new Error(`Invalid version string in "[email protected]"`)
);
});
});

describe('when parsing version stfing', () => {
it('parses version correctly', () => {
expect(() => parseVersionNumber('')).toThrow(
new Error(`Unable to parse version string ""`)
);
expect(() => parseVersionNumber('@')).toThrow(
new Error(`Unable to parse version string "@"`)
);
expect(() => parseVersionNumber('T')).toThrow(
new Error(`Unable to parse version string "T"`)
);
expect(() => parseVersionNumber('0T')).toThrow(
new Error(`Unable to parse version string "0T"`)
);
expect(parseVersionNumber('99')).toEqual(99);
expect(parseVersionNumber('1')).toEqual(1);
expect(parseVersionNumber(' 8')).toEqual(8);
expect(parseVersionNumber('7 ')).toEqual(7);
expect(parseVersionNumber('0')).toEqual(0);
});
});

describe('when extracting version object', () => {
it('extracts version correctly', () => {
expect(() => extractVersion('')).toThrow(
new Error(`Unable to parse version string ""`)
);
expect(() => extractVersion('@')).toThrow(
new Error(`Unable to parse version string "@"`)
);
expect(() => extractVersion('1.E.6')).toThrow(
new Error(`Unable to parse version string "E"`)
);
expect(() => extractVersion('E.!.1')).toThrow(
new Error(`Unable to parse version string "E"`)
);
expect(() => extractVersion('1.0.t')).toThrow(
new Error(`Unable to parse version string "t"`)
);
expect(() => extractVersion('1.')).toThrow(
new Error(`Unable to parse version string ""`)
);
expect(() => extractVersion('1.0.0-!ab3l')).toThrow(
new Error(`Invalid version label "!ab3l"`)
);
expect(() => extractVersion('1.0.0-Lab3l')).toThrow(
new Error(`Invalid version label "Lab3l"`)
);

expect(extractVersion('1')).toEqual({ major: 1 });
expect(extractVersion('1.0')).toEqual({ major: 1, minor: 0 });
expect(extractVersion('0.0.1')).toEqual({ major: 0, minor: 0, patch: 1 });
expect(extractVersion('1.0.0')).toEqual({ major: 1, minor: 0, patch: 0 });
expect(extractVersion('9.9.9')).toEqual({ major: 9, minor: 9, patch: 9 });
expect(extractVersion('1.0.0-label')).toEqual({
major: 1,
minor: 0,
patch: 0,
label: 'label',
});
expect(extractVersion('1.0.0-lab3l')).toEqual({
major: 1,
minor: 0,
patch: 0,
label: 'lab3l',
});
expect(extractVersion('1.0.0-la-b3l')).toEqual({
major: 1,
minor: 0,
patch: 0,
label: 'la-b3l',
});
expect(extractVersion('1.0.0-lab3l')).toEqual({
major: 1,
minor: 0,
patch: 0,
label: 'lab3l',
});
expect(extractVersion('1.0.0-la_b3l')).toEqual({
major: 1,
minor: 0,
patch: 0,
label: 'la_b3l',
});
});
});
});
88 changes: 88 additions & 0 deletions src/interfaces/ast/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ export function isValidProviderName(input: string): boolean {
return PROVIDER_NAME_RE.test(input);
}

/**
* Checks if input string is valid version string.
*
* Example:
* ```
* isValidVersionString('1.2.3') // true
* isValidVersionString('1.2.3-test') // true
* ```
*/
export function isValidVersionString(version: string): boolean {
const [restVersion, label] = splitLimit(version, '-', 1);
const [majorStr, minorStr, patchStr] = splitLimit(restVersion, '.', 2);
Expand All @@ -42,3 +51,82 @@ export function isValidVersionString(version: string): boolean {

return true;
}

/**
* Tries to extract valid version string from input string contining @.
*
* Example:
* ```
* extractVersionString('test/[email protected]') // '1.2.3'
* ```
*/
export function extractVersionString(input: string): string {
if (input === '') {
throw new Error('Invalid empty version string');
}
const [, version] = splitLimit(input, '@', 1);
if (!isValidVersionString(version)) {
throw new Error(`Invalid version string in "${input}"`);
}

return version;
}

/**
* Tries to parse numeric string (0-9) to number.
*
* Example:
* ```
* parseVersionNumber('3') // 3
* parseVersionNumber(' 3 ') // 3
* ```
*/
export function parseVersionNumber(str: string): number {
const value = str.trim();
if (!VERSION_NUMBER_RE.test(value)) {
throw new Error(`Unable to parse version string "${str}"`);
}

return parseInt(value, 10);
}

/**
* Tries to extract version object from version string.
*
* Example:
* ```
* parseVersionNumber('1.2.3') // {major: 1, minor: 2, patch: 3}
* parseVersionNumber('1.2.3-test') // {major: 1, minor: 2, patch: 3, label: 'test'}
* ```
*/
export function extractVersion(
versionString: string
): {
major: number;
minor?: number;
patch?: number;
label?: string;
} {
const [version, label] = splitLimit(versionString, '-', 1);
const [majorStr, minorStr, patchStr] = splitLimit(version, '.', 2);

const major = parseVersionNumber(majorStr);

let minor = undefined;
if (minorStr !== undefined) {
minor = parseVersionNumber(minorStr);
}

let patch = undefined;
if (patchStr !== undefined) {
patch = parseVersionNumber(patchStr);
}

if (label !== undefined) {
if (!isValidDocumentName(label)) {
throw new Error(`Invalid version label "${label}"`);
}
}

return { major, minor, patch, label };
}

0 comments on commit e76ccef

Please sign in to comment.