Skip to content

Commit

Permalink
test(util): add coverage (#1851)
Browse files Browse the repository at this point in the history
- cover remaining utilities in EDS _utils
  • Loading branch information
booc0mtaco authored Feb 22, 2024
1 parent 7bffc1a commit 59267c3
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 2 deletions.
7 changes: 5 additions & 2 deletions bin/_util.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = {

// If no config exists, fail
if (!settings) {
throw new Error(
throw new ReferenceError(
'Please add EDS config to your project before continuing (specify "src" and "dest" target paths)',
);
}
Expand Down Expand Up @@ -80,13 +80,14 @@ module.exports = {
* @param {object} base The tokens theme file stored in the EDS project
* @param {object} theme The project theme file stored in the app code (same format as bas)
* @param {Array} path The base path, stored as an array of object key names (default [])
* @returns {boolean} true when is strict subset
* @throws Error when there are tokens in theme that aren't in base
*/
isStrictSubset: function (base, theme, path = []) {
for (const name in theme) {
if (typeof theme[name] === 'object') {
if (base[name] === undefined) {
throw new Error(
throw new ReferenceError(
`Local themeable value does not exist in base theme: --${path.join(
'-',
)}.${name}"`,
Expand All @@ -99,6 +100,8 @@ module.exports = {
);
}
}

return true;
},
/**
* Flatten token names such that any "root-tokens" do not include `@` in the resulting token name.
Expand Down
192 changes: 192 additions & 0 deletions bin/_util.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,198 @@
jest.mock('lilconfig');

const lilconfig = require('lilconfig');
const identity = require('lodash/identity');
const utils = require('./_util');

describe('utils', function () {
describe('minifyDictionaryUsingFormat', () => {
const base = {
eds: {
theme: {
color: {
test: {
value: '#000000',
},
test2: {
value: '#00FF00',
},
},
},
},
};
it('bypasses parsing when object is not an object', () => {
const emptyArray = [];

expect(utils.minifyDictionaryUsingFormat(emptyArray)).toEqual([]);
});

it('allows interpretation of parsed values as identity', () => {
expect(utils.minifyDictionaryUsingFormat(base, identity)).toEqual(base);
});

it('allows flattening of value objects', () => {
const expected = {
eds: {
theme: {
color: {
test: '#000000',
test2: '#00FF00',
},
},
},
};
expect(
utils.minifyDictionaryUsingFormat(base, (obj) => obj.value),
).toEqual(expected);
});
});

describe('formatEdsTokens', () => {
const base = {
neutral: {
default: {
'@': 'var(--eds-theme-color-border-neutral-default)',
hover: 'var(--eds-theme-color-border-neutral-default-hover)',
},
},
};

it('can strip out any at-symbols from input style-dictionary object', () => {
// since this function edits in place, clone the values then compare to expected
const input = {
...base,
};
const expected = {
neutral: {
default: {
hover: 'var(--eds-theme-color-border-neutral-default-hover)',
},
},
'neutral-default': 'var(--eds-theme-color-border-neutral-default)',
};

utils.formatEdsTokens(input);

expect(input).toEqual(expected);
});
});

describe('isStrictSubset', () => {
const base = {
eds: {
theme: {
color: {
test: {
value: '#000000',
},
test2: {
value: '#00FF00',
},
},
},
},
};

it('allows exact matching themes', () => {
const theme = {
...base,
};

expect(utils.isStrictSubset(base, theme)).toBeTruthy();
});

it('allows theme to be a subset of base', () => {
const theme = {
...base,
};
delete theme.eds.theme.color.test2;

expect(utils.isStrictSubset(base, theme)).toBeTruthy();
});

it('throws when the theme has things not in the base theme file', () => {
const theme = {
...base,
color: {
test: {
value: '#FFOOFF',
},
},
};

const assertThrow = () => {
utils.isStrictSubset(base, theme);
};

expect(assertThrow).toThrow(ReferenceError);
});
});

describe('getConfig', function () {
// Silence console output AND hook up for counting in tests
let origWarn;
beforeEach(() => {
origWarn = console.warn;
console.warn = jest.fn();
});

afterEach(() => {
console.warn = origWarn;
});

describe('with no settings read', () => {
it('throws when no settings are defined', async () => {
lilconfig.lilconfig.mockImplementation(() => {
return {
search: function () {
// https://www.npmjs.com/package/cosmiconfig#result
return Promise.resolve(undefined);
},
};
});

const test = async () => {
await utils.getConfig();
};

// We expect it to reject because it will also throw and throwing rejects
await expect(test()).rejects.toThrow(ReferenceError);
});
});

describe('with settings read', () => {
it('converts json key to src key', async () => {
lilconfig.lilconfig.mockImplementation(() => {
return {
search: function () {
// https://www.npmjs.com/package/cosmiconfig#result
return Promise.resolve({
config: {
json: 'a/b/c',
css: '1/2/3',
},
});
},
};
});
const test = async () => {
return await utils.getConfig();
};

// This ex expected to duplicate the keys currently.
// In the future, we will deprecate the preservation of the old keys
await expect(test()).resolves.toEqual({
css: '1/2/3',
src: 'a/b/c',
json: 'a/b/c',
dest: '1/2/3',
});

expect(console.warn).toHaveBeenCalledTimes(2);
});
});
});

describe('getWritePath', function () {
const exampleTheme = {
eds: {
Expand Down

0 comments on commit 59267c3

Please sign in to comment.