Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(postcss-reduce-initial): refactor and add tests for acquire …
…script (#1169) * refactor(postcss-reduce-initial): make acquire script testable and easier to maintain - Separate main concerns into different files - Replace comments with more readable code - Refactor with testability in mind - Replace dependencies with more up-to-date and lightweight alternatives * test(postcss-reduce-initial): add tests for acquire script * fixup! refactor(postcss-reduce-initial): make acquire script testable and easier to maintain * fixup! test(postcss-reduce-initial): add tests for acquire script Co-authored-by: Ludovico Fischer <43557+ludofischer@users.noreply.github.com>
- Loading branch information
1 parent
506a823
commit ca5246d
Showing
11 changed files
with
505 additions
and
381 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
58 changes: 58 additions & 0 deletions
58
packages/postcss-reduce-initial/src/script/__tests__/io.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import fetch from 'node-fetch'; | ||
import { handleError, toJSONString, write, generate } from '../lib/io.mjs'; | ||
import testData from './sampleProperties.json'; | ||
|
||
jest.mock('node-fetch'); | ||
|
||
// Selectively bypass mocking to use a real Response obj | ||
const { Response } = jest.requireActual('node-fetch'); | ||
|
||
describe('toJSONString', () => { | ||
const rawData = { | ||
foo: 'bar', | ||
'baz-qux': 'quux', | ||
quuz: 'corge', | ||
garply: 'waldo', | ||
'fred-plugh': 'xyzzy-thud', | ||
}; | ||
|
||
test('should produce parsable JSON', () => { | ||
expect(JSON.parse(toJSONString(rawData))).toEqual(rawData); | ||
}); | ||
}); | ||
|
||
describe('Smoke tests', () => { | ||
const data = { | ||
fromInitial: { foo: 'bar', baz: 'qux' }, | ||
toInitial: { qux: 'baz', bar: 'foo' }, | ||
}; | ||
const paths = { fromInitial: '/foo.json', toInitial: '/bar.json' }; | ||
|
||
test.each([ | ||
['fromInitial', paths.fromInitial, data.fromInitial], | ||
['toInitial', paths.toInitial, data.toInitial], | ||
])('should write JSON file based on key (%p)', (key, path, expected) => { | ||
const err = expect.any(Function); | ||
const fileFunc = jest.fn(); | ||
|
||
write(fileFunc, paths, data, key); | ||
|
||
expect(fileFunc).toHaveBeenCalledWith(path, toJSONString(expected), err); | ||
}); | ||
|
||
test('should handle file operation errors', () => { | ||
expect(handleError).not.toThrowError(); | ||
expect(() => handleError(new Error('something went wrong'))).toThrowError(); | ||
}); | ||
|
||
test('should make it through promise chain with sample data and write 2 files', async () => { | ||
const fileFunc = jest.fn(); | ||
fetch.mockReturnValue( | ||
Promise.resolve(new Response(JSON.stringify(testData))) | ||
); | ||
|
||
await generate(fileFunc, paths, 'https://example.com/properties.json'); | ||
|
||
expect(fileFunc).toHaveBeenCalledTimes(2); | ||
}); | ||
}); |
122 changes: 122 additions & 0 deletions
122
packages/postcss-reduce-initial/src/script/__tests__/mdnCssProps.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { | ||
isUserAgentDependent, | ||
isComplexSyntax, | ||
isUnpredictable, | ||
toPlainText, | ||
reduceInitial, | ||
validate, | ||
} from '../lib/mdnCssProps.mjs'; | ||
|
||
import testData from './sampleProperties.json'; | ||
|
||
describe('should recognise user agent dependent flags', () => { | ||
test.each([ | ||
['dependsOnUserAgent', true], | ||
['noPracticalInitialValue', true], | ||
['noneButOverriddenInUserAgentCSS', true], | ||
['variesFromBrowserToBrowser', true], | ||
['invertOrCurrentColor', true], | ||
['startOrNamelessValueIfLTRRightIfRTL', true], | ||
['autoForSmartphoneBrowsersSupportingInflation', true], | ||
['experimental', false], | ||
['normal', false], | ||
])('isUserAgentDependent(%p) expected: %p', (flag, expected) => { | ||
expect(isUserAgentDependent(flag)).toBe(expected); | ||
}); | ||
}); | ||
|
||
describe('should recognise properties with complex syntax', () => { | ||
test.each([ | ||
[['foo', 'bar'], 'text-align', true], | ||
[['foo', 'bar'], '--*', true], | ||
['normal', '--*', true], | ||
['normal', 'word-wrap', false], | ||
['100%', 'text-align', false], | ||
])('isComplexSyntax(%p, %p) expected: %p', (initial, key, expected) => { | ||
expect(isComplexSyntax(initial, key)).toBe(expected); | ||
}); | ||
}); | ||
|
||
describe('should recognise properties with unpredictable behavior', () => { | ||
test.each([ | ||
['nonstandard', 'align-items', true], | ||
['nonstandard', 'display', true], | ||
['standard', 'display', true], | ||
['standard', 'align-items', false], | ||
['experimental', 'aspect-ratio', false], | ||
])('isUnpredictable(%p, %p) expected: %p', (status, key, expected) => { | ||
expect(isUnpredictable(status, key)).toBe(expected); | ||
}); | ||
}); | ||
|
||
describe('should strip HTML, but leave relevant chars and separating spaces', () => { | ||
test.each([ | ||
['<script>foo</script>', ''], | ||
['<script type="text/javascript">bar<script>', ''], | ||
['<script src="myscripts.js">baz</script>', ''], | ||
['Hello & Goodbye', 'Hello & Goodbye'], | ||
['Eye<br>glasses', 'Eyeglasses'], | ||
['Hand<p>writing</p>', 'Handwriting'], | ||
['No space at end ', 'No space at end'], | ||
['padding-box', 'padding-box'], | ||
['50% 50% 0', '50% 50% 0'], | ||
['0% 0%', '0% 0%'], | ||
['100%', '100%'], | ||
['auto', 'auto'], | ||
])('toPlainText(%p) expected: %p', (string, expected) => { | ||
expect(toPlainText(string)).toBe(expected); | ||
}); | ||
}); | ||
|
||
describe('Reduce and validate sample data', () => { | ||
let processedData = ''; | ||
|
||
beforeAll(() => { | ||
processedData = reduceInitial(testData); | ||
}); | ||
|
||
test('should reduce to expected object structure', () => { | ||
expect(processedData).toEqual( | ||
expect.objectContaining({ | ||
fromInitial: expect.any(Object), | ||
toInitial: expect.any(Object), | ||
}) | ||
); | ||
}); | ||
|
||
test('should reduce to expected number of fromInitial items', () => { | ||
expect(Object.keys(processedData.fromInitial)).toHaveLength(5); | ||
}); | ||
|
||
test('should reduce to expected number of toInitial items', () => { | ||
expect(Object.keys(processedData.toInitial)).toHaveLength(3); | ||
}); | ||
|
||
test('should validate and return sample data as resolved promise', async () => { | ||
expect.assertions(1); | ||
await expect(validate(processedData)).resolves.toEqual(processedData); | ||
}); | ||
|
||
test('should fail validation on missing data', async () => { | ||
expect.assertions(1); | ||
await expect(validate(undefined)).rejects.toThrow(Error); | ||
}); | ||
|
||
test('should fail validation on missing fromInitial', async () => { | ||
const partialData = JSON.parse(JSON.stringify(processedData)); | ||
|
||
delete partialData.fromInitial; | ||
|
||
expect.assertions(1); | ||
await expect(validate(partialData)).rejects.toThrow(Error); | ||
}); | ||
|
||
test('should fail validation on missing toInitial', async () => { | ||
const partialData = JSON.parse(JSON.stringify(processedData)); | ||
|
||
delete partialData.toInitial; | ||
|
||
expect.assertions(1); | ||
await expect(validate(partialData)).rejects.toThrow(Error); | ||
}); | ||
}); |
Oops, something went wrong.