mirror of
https://github.com/xodio/xod.git
synced 2026-03-07 01:06:53 +01:00
379 lines
14 KiB
JavaScript
379 lines
14 KiB
JavaScript
import * as R from 'ramda';
|
|
import { assert } from 'chai';
|
|
import { explodeMaybe } from 'xod-func-tools';
|
|
|
|
import * as CONST from '../src/constants';
|
|
import { BINDABLE_CUSTOM_TYPES } from '../src/custom-types';
|
|
import * as PatchPathUtils from '../src/patchPathUtils';
|
|
|
|
import * as Helper from './helpers';
|
|
|
|
describe('PatchPathUtils', () => {
|
|
describe('getBaseName', () => {
|
|
it('should return base name extracted from path', () => {
|
|
const baseName = 'test';
|
|
const path = `@/folder/${baseName}`;
|
|
const result = PatchPathUtils.getBaseName(path);
|
|
assert.equal(result, baseName);
|
|
});
|
|
});
|
|
|
|
describe('isValidIdentifier', () => {
|
|
it('should ensure that Identifier is alphanumeric, in lowercase and kebabcase', () => {
|
|
assert.isTrue(PatchPathUtils.isValidIdentifier('a'));
|
|
assert.isTrue(PatchPathUtils.isValidIdentifier('1'));
|
|
assert.isTrue(PatchPathUtils.isValidIdentifier('a-1'));
|
|
assert.isTrue(PatchPathUtils.isValidIdentifier('1-a'));
|
|
assert.isTrue(PatchPathUtils.isValidIdentifier('lower'));
|
|
assert.isTrue(PatchPathUtils.isValidIdentifier('lower-kebab'));
|
|
assert.isTrue(PatchPathUtils.isValidIdentifier('lower-kebab-123'));
|
|
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier(''));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('A'));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('@'));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('snake_case'));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('camelCase'));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('foo/bar'));
|
|
});
|
|
it('should ensure that Identifier does not start or end with hypen', () => {
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('-'));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('-something'));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('something-'));
|
|
});
|
|
it('should ensure that Identifier does not contain more than one hypen in a row', () => {
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('foo--bar'));
|
|
assert.isFalse(PatchPathUtils.isValidIdentifier('foo---bar'));
|
|
});
|
|
});
|
|
|
|
describe('isValidPatchBasename', () => {
|
|
it('should ensure that PatchBasename is valid Identifier and could contain valid type specification', () => {
|
|
// Valid common patch basenames
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('a'));
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('a-1'));
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('a-b'));
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('lower-kebab-123'));
|
|
|
|
// Valid basenames with types
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('a(string)'));
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('a-b(string)'));
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('foo(string,number)'));
|
|
assert.isTrue(
|
|
PatchPathUtils.isValidPatchBasename('foo(super-string,number)')
|
|
);
|
|
|
|
// Valid basenames with variadic level
|
|
assert.isTrue(PatchPathUtils.isValidPatchBasename('lower-kebab-123-$3'));
|
|
assert.isTrue(
|
|
PatchPathUtils.isValidPatchBasename('foo(super-string,number)-$2')
|
|
);
|
|
|
|
// Invalid common patch basenames
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('-'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a-'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('-a'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('foo--bar'));
|
|
|
|
// Invalid basenames with types
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a-(string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a-string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a(string'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a(string,)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a(string)lala'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a(string,number-)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('a(string,-number)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('foo--bar(string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('(string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('(string,number)'));
|
|
|
|
// Invalid basenames with variadic level
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('foo-$'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchBasename('foo-$a'));
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchBasename('foo(super-string,number)-$')
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchBasename('foo(super-string,number)-$a')
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('isExpandedVariadicPatchBasename', () => {
|
|
it('should ensure that it is a valid basename that contains variadic level suffix', () => {
|
|
assert.isTrue(PatchPathUtils.isExpandedVariadicPatchBasename('join-$5'));
|
|
assert.isTrue(
|
|
PatchPathUtils.isExpandedVariadicPatchBasename('sp(number,string)-$5')
|
|
);
|
|
|
|
assert.isFalse(
|
|
PatchPathUtils.isExpandedVariadicPatchBasename('my-regular-patch-123')
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isExpandedVariadicPatchBasename(
|
|
'some-specialization(number,string)'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isExpandedVariadicPatchBasename(
|
|
'not-even-a-valid-basename-$b'
|
|
)
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('isValidPatchPath', () => {
|
|
it('should accept local paths', () => {
|
|
assert.isTrue(PatchPathUtils.isValidPatchPath('@/some-identifier'));
|
|
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/notAValidIdentifier'));
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath('@/not_a_valid_identifier')
|
|
);
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/extra/slashes'));
|
|
});
|
|
it('should accept local paths with types', () => {
|
|
assert.isTrue(PatchPathUtils.isValidPatchPath('@/foo(string)'));
|
|
assert.isTrue(PatchPathUtils.isValidPatchPath('@/foo(string,number)'));
|
|
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@(string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/(string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/AA(string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/a(string,)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/a(string,'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/a-(string)'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('@/a-string)'));
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath('@/extra/slashes(string)')
|
|
);
|
|
});
|
|
it('should accept library paths', () => {
|
|
assert.isTrue(PatchPathUtils.isValidPatchPath('a/b/c'));
|
|
assert.isTrue(
|
|
PatchPathUtils.isValidPatchPath('author/lib-name/some-identifier')
|
|
);
|
|
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('//'));
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'invalid@author/lib-name/some-identifier'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'author/@invalid@libname@/some-identifier'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath('author/lib-name/invalid@identifier')
|
|
);
|
|
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('not-enough/slashes'));
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('way/too/much/slashes'));
|
|
});
|
|
it('should accept library paths with types', () => {
|
|
assert.isTrue(PatchPathUtils.isValidPatchPath('a/b/c(string)'));
|
|
assert.isTrue(PatchPathUtils.isValidPatchPath('a/b/c(string,boolean)'));
|
|
assert.isTrue(
|
|
PatchPathUtils.isValidPatchPath('author/a-b/some-identifier(string)')
|
|
);
|
|
assert.isTrue(
|
|
PatchPathUtils.isValidPatchPath('author/a-b/foo-bar(string,number)')
|
|
);
|
|
|
|
assert.isFalse(PatchPathUtils.isValidPatchPath('//(string)'));
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'author/lib-name/some-identifier-(string)'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'author/lib-name/some-identifier(string,)'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'author/lib-name/some-identifier(string'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'author/lib-name/some-identifier-string)'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'author/lib-name/some-identifier(string)lala'
|
|
)
|
|
);
|
|
assert.isFalse(
|
|
PatchPathUtils.isValidPatchPath(
|
|
'invalid@author/lib-name/some-identifier(string)'
|
|
)
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('validatePath', () => {
|
|
it('should be Either.Left for not valid paths', () => {
|
|
const err1 = PatchPathUtils.validatePath('');
|
|
const err2 = PatchPathUtils.validatePath('dots.in.names');
|
|
|
|
assert.isTrue(PatchPathUtils.validatePath('кириллица').isLeft);
|
|
assert.isTrue(PatchPathUtils.validatePath('spa ce').isLeft);
|
|
assert.isTrue(PatchPathUtils.validatePath('spçiålÇhÅr$').isLeft);
|
|
|
|
assert.isTrue(
|
|
PatchPathUtils.validatePath('@/folder/subfolder/patchName').isLeft
|
|
);
|
|
assert.isTrue(
|
|
PatchPathUtils.validatePath('@/patch_name_underscored').isLeft
|
|
);
|
|
|
|
Helper.expectEitherError('INVALID_PATCH_PATH {"patchPath":""}', err1);
|
|
Helper.expectEitherError(
|
|
'INVALID_PATCH_PATH {"patchPath":"dots.in.names"}',
|
|
err2
|
|
);
|
|
});
|
|
it('should be Either.Right for valid paths', () => {
|
|
assert.isTrue(PatchPathUtils.validatePath('@/patch-name').isRight);
|
|
assert.isTrue(
|
|
PatchPathUtils.validatePath('author-name/library-name/patch-name')
|
|
.isRight
|
|
);
|
|
});
|
|
it('should be Either.Right should containt correct value', () => {
|
|
const path = '@/patch-name';
|
|
const result = PatchPathUtils.validatePath(path);
|
|
assert.isTrue(result.isRight);
|
|
|
|
/* istanbul ignore next */
|
|
Helper.expectEitherRight(val => {
|
|
assert.equal(val, path);
|
|
}, result);
|
|
});
|
|
});
|
|
|
|
describe('isPathLocal', () => {
|
|
const localPath = '@/test';
|
|
const libPath = 'vasya/super-library/test';
|
|
|
|
it('should return true for localPath', () => {
|
|
const result = PatchPathUtils.isPathLocal(localPath);
|
|
assert.isTrue(result);
|
|
});
|
|
it('should return false for not a path', () => {
|
|
const result = PatchPathUtils.isPathLocal({});
|
|
assert.isFalse(result);
|
|
});
|
|
it('should return false for libPath', () => {
|
|
const result = PatchPathUtils.isPathLocal(libPath);
|
|
assert.isFalse(result);
|
|
});
|
|
});
|
|
describe('isPathLibrary', () => {
|
|
const localPath = '@/test';
|
|
const libPath = 'vasya/super-library/test';
|
|
|
|
it('should return true for libPath', () => {
|
|
const result = PatchPathUtils.isPathLibrary(libPath);
|
|
assert.isTrue(result);
|
|
});
|
|
it('should return false for not a path', () => {
|
|
const result = PatchPathUtils.isPathLocal({});
|
|
assert.isFalse(result);
|
|
});
|
|
it('should return false for localPath', () => {
|
|
const result = PatchPathUtils.isPathLibrary(localPath);
|
|
assert.isFalse(result);
|
|
});
|
|
});
|
|
|
|
describe('getLibraryName', () => {
|
|
const localPath = '@/test';
|
|
const libName = 'vasya/super-library';
|
|
const libPath = `${libName}/test`;
|
|
|
|
it('should return library name for libPath', () => {
|
|
const result = PatchPathUtils.getLibraryName(libPath);
|
|
assert.equal(result, libName);
|
|
});
|
|
it('should return @ for localPath', () => {
|
|
const result = PatchPathUtils.getLibraryName(localPath);
|
|
assert.equal(result, '@');
|
|
});
|
|
});
|
|
|
|
describe('resolvePatchPath', () => {
|
|
it('if both paths is local, it returns the same path', () => {
|
|
assert.equal(
|
|
PatchPathUtils.resolvePatchPath('@/local1', '@/local2'),
|
|
'@/local1'
|
|
);
|
|
});
|
|
it('if both paths is library, it returns the same path', () => {
|
|
assert.equal(
|
|
PatchPathUtils.resolvePatchPath(
|
|
'xod/lib/local1',
|
|
'xod/another-lib/local2'
|
|
),
|
|
'xod/lib/local1'
|
|
);
|
|
});
|
|
it('if first path is local, but second is libraty it should return new resolved path', () => {
|
|
assert.equal(
|
|
PatchPathUtils.resolvePatchPath('@/local1', 'xod/lib/local2'),
|
|
'xod/lib/local1'
|
|
);
|
|
});
|
|
it('if first path is library, but second is local it returns the same library path', () => {
|
|
assert.equal(
|
|
PatchPathUtils.resolvePatchPath('xod/lib/local1', '@/local2'),
|
|
'xod/lib/local1'
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('Cast patch utils', () => {
|
|
describe('getCastPatchPath', () => {
|
|
it('should return patch paths that are recognised as cast paths', () => {
|
|
const testData = [
|
|
PatchPathUtils.getCastPatchPath(
|
|
CONST.PIN_TYPE.BOOLEAN,
|
|
CONST.PIN_TYPE.NUMBER
|
|
),
|
|
PatchPathUtils.getCastPatchPath(
|
|
CONST.PIN_TYPE.BOOLEAN,
|
|
CONST.PIN_TYPE.STRING
|
|
),
|
|
PatchPathUtils.getCastPatchPath(
|
|
CONST.PIN_TYPE.NUMBER,
|
|
CONST.PIN_TYPE.BOOLEAN
|
|
),
|
|
PatchPathUtils.getCastPatchPath(
|
|
BINDABLE_CUSTOM_TYPES.COLOR,
|
|
CONST.PIN_TYPE.STRING
|
|
),
|
|
];
|
|
const expected = [
|
|
'xod/core/cast-to-number(boolean)',
|
|
'xod/core/cast-to-string(boolean)',
|
|
'xod/core/cast-to-boolean(number)',
|
|
'xod/color/format-color',
|
|
];
|
|
R.addIndex(R.forEach)((maybePatchPath, idx) => {
|
|
Helper.expectMaybeJust(maybePatchPath);
|
|
const patchPath = explodeMaybe(
|
|
'Expected Maybe.Just, but got Maybe.Nothing',
|
|
maybePatchPath
|
|
);
|
|
assert.strictEqual(patchPath, expected[idx]);
|
|
}, testData);
|
|
});
|
|
});
|
|
});
|
|
});
|