Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,22 @@ jobs:
run: npm run build -- -f
- name: Run ${{ matrix.suite }} tests
run: npm run test -- -c node -s ${{ matrix.suite }}
ts:
runs-on: ubuntu-latest
name: TS tests
strategy:
fail-fast: false
matrix:
node-version: [18.x]
ts: [4.0, 4.9]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- name: Build
run: npm run build -- -f
- name: Run tests
run: npm run test -- -s ts
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ before_commit
/scripts/cli_cache.json
/dist/
/lib/
/test/
test/*
!/test/ts
30 changes: 30 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"busboy": "^1.6.0",
"chalk": "^2.4.1",
"commander": "^9.1.0",
"conditional-type-checks": "^1.0.6",
"deep-object-diff": "^1.1.7",
"eslint": "^8.23.1",
"eslint-config-prettier": "^8.5.0",
Expand All @@ -104,6 +105,7 @@
"ps-list": "^8.1.0",
"qunit": "^2.17.2",
"rollup": "^2.75.6",
"rollup-plugin-no-emit": "^0.0.1",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-ts": "^3.0.2",
"source-map-support": "^0.5.21",
Expand Down
11 changes: 8 additions & 3 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { terser } from 'rollup-plugin-terser';
import ts from 'rollup-plugin-ts';
import json from '@rollup/plugin-json';
import noEmit from 'rollup-plugin-no-emit';

const input = process.env.BUILD_INPUT?.split(',') || ['./index.js'];
const outputType = input.length > 1 ? 'dir' : 'file';

// https://rollupjs.org/guide/en/#configuration-files
export default {
input: process.env.BUILD_INPUT?.split(',') || ['./index.js'],
input,
output: [
{
file: process.env.BUILD_OUTPUT || './dist/fabric.js',
[outputType]: process.env.BUILD_OUTPUT || './dist/fabric.js',
name: 'fabric',
format: 'cjs',
sourcemap: true,
},
Number(process.env.MINIFY)
Number(process.env.MINIFY) && outputType === 'file'
? {
file: process.env.BUILD_MIN_OUTPUT || './dist/fabric.min.js',
name: 'fabric',
Expand All @@ -26,5 +30,6 @@ export default {
ts({
/* Plugin options */
}),
noEmit({ emit: !Number(process.env.NO_EMIT) }),
],
};
28 changes: 19 additions & 9 deletions scripts/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,27 @@ import { wd } from './dirname.mjs';
* @see https://rollupjs.org/guide/en/#--watchonstart-cmd---watchonbundlestart-cmd---watchonbundleend-cmd---watchonend-cmd---watchonerror-cmd
* @param {*} options
*/
export function build({ watch, fast, input, output } = {}) {
export function build({
watch,
fast,
input,
output,
report = true,
emit = true,
} = {}) {
const cmd = [
'rollup',
'-c',
watch ? '--watch' : '',
'--no-watch.clearScreen',
...['onStart', 'onError', 'onEnd'].map(
(type) =>
`--watch.${type} "node ./scripts/buildReporter.mjs ${type
.toLowerCase()
.slice(2)}"`
),
...(report
? [('onStart', 'onError', 'onEnd')].map(
(type) =>
`--watch.${type} "node ./scripts/buildReporter.mjs ${type
.toLowerCase()
.slice(2)}"`
)
: []),
].join(' ');
const processOptions = {
stdio: 'inherit',
Expand All @@ -30,15 +39,16 @@ export function build({ watch, fast, input, output } = {}) {
env: {
...process.env,
MINIFY: Number(!fast),
BUILD_INPUT: input,
BUILD_INPUT: Array.isArray(input) ? input.join(',') : input,
BUILD_OUTPUT: output,
BUILD_MIN_OUTPUT:
output && !fast
output && !Array.isArray(input) && !fast
? path.resolve(
path.dirname(output),
`${path.basename(output, '.js')}.min.js`
)
: undefined,
NO_EMIT: Number(!emit),
},
};
if (watch) {
Expand Down
83 changes: 45 additions & 38 deletions scripts/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ import process from 'node:process';
import os from 'os';
import { build } from './build.mjs';
import { awaitBuild } from './buildLock.mjs';
import { CLI_CACHE, wd } from './dirname.mjs';
import { CLI_CACHE, dumpsPath, wd } from './dirname.mjs';
import { listFiles, transform as transformFiles } from './transform_files.mjs';

const program = new commander.Command();

const websiteDir = path.resolve(wd, '../fabricjs.com');

const TEST_SUITES = ['unit', 'visual', 'ts'];

function execGitCommand(cmd) {
return cp
.execSync(cmd, { cwd: wd })
Expand Down Expand Up @@ -294,14 +296,27 @@ async function runTestem({

/**
*
* @param {'unit' | 'visual'} suite
* @param {'unit' | 'visual' | 'ts'} suite
* @param {string[] | null} tests file paths
* @param {{debug?:boolean,recreate?:boolean,verbose?:boolean,filter?:string}} [options]
* @returns {Promise<boolean | undefined>} true if some tests failed
*/
async function test(suite, tests, options = {}) {
let failed = false;
await awaitBuild();

if (suite === 'ts') {
console.log(chalk.bold(chalk.blue(`running TS test suite`)));
build({
fast: true,
input: tests || listTestFiles('ts').map((file) => `test/ts/${file}`),
output: path.resolve(dumpsPath, 'ts_tests'),
report: false,
emit: false,
});
return false;
}

const qunitEnv = {
QUNIT_DEBUG_VISUAL_TESTS: Number(options.debug),
QUNIT_RECREATE_VISUAL_REFS: Number(options.recreate),
Expand All @@ -326,7 +341,7 @@ async function test(suite, tests, options = {}) {
cwd: wd,
env: {
...env,
// browser takes precendence in golden ref generation
// browser takes precedence in golden ref generation
...(browserContexts.length === 0 ? qunitEnv : {}),
},
shell: true,
Expand Down Expand Up @@ -360,7 +375,7 @@ async function test(suite, tests, options = {}) {

/**
*
* @param {'unit'|'visual'} type correspondes to the test directories
* @param {'unit'|'visual'|'ts'} type corresponds to the test directories
* @returns
*/
function listTestFiles(type) {
Expand Down Expand Up @@ -427,11 +442,8 @@ async function selectFileToTransform() {

async function selectTestFile() {
const selected = readCLIFile();
const unitTests = listTestFiles('unit').map((file) =>
createChoiceData('unit', file)
);
const visualTests = listTestFiles('visual').map((file) =>
createChoiceData('visual', file)
const testChoices = TEST_SUITES.map((suite) =>
listTestFiles(suite).map((file) => createChoiceData(suite, file))
);
const { tests: filteredTests } = await inquirer.prompt([
{
Expand All @@ -444,32 +456,24 @@ async function selectTestFile() {
pageSize: Math.max(10, selected.length),
source(answersSoFar, input = '') {
return new Promise((resolve) => {
const tests = _.concat(unitTests, visualTests);
const tests = _.concat(...Object.values(testChoices));
const value = _.map(this.getCurrentValue(), (value) =>
createChoiceData(value.type, value.file)
);
if (value.length > 0) {
if (
value.find(
(v) => v.value && v.value.type === 'unit' && !v.value.file
)
) {
_.pullAll(tests, unitTests);
}
if (
value.find(
(v) => v.value && v.value.type === 'visual' && !v.value.file
)
) {
_.pullAll(tests, visualTests);
}
}
const unitChoice = createChoiceData('unit', '');
const visualChoice = createChoiceData('visual', '');
!value.find((v) => _.isEqual(v, unitChoice)) &&
value.push(unitChoice);
!value.find((v) => _.isEqual(v, visualChoice)) &&
value.push(visualChoice);
value.length > 0 &&
TEST_SUITES.forEach((suite) => {
if (
value.find(
(v) => v.value && v.value.type === suite && !v.value.file
)
) {
_.pullAll(tests, testChoices[suite]);
}
});
TEST_SUITES.forEach((suite) => {
const choice = createChoiceData(suite, '');
!value.find((v) => _.isEqual(v, choice)) && value.push(choice);
});
if (value.length > 0) {
value.unshift(new inquirer.Separator());
value.push(new inquirer.Separator());
Expand All @@ -488,7 +492,7 @@ async function selectTestFile() {
return filteredTests;
}

async function runIntreactiveTestSuite(options) {
async function runInteractiveTestSuite(options) {
// some tests fail because of some pollution when run from the same context
// test(_.map(await selectTestFile(), curr => `test/${curr.type}/${curr.file}`))
const tests = _.reduce(
Expand All @@ -501,7 +505,10 @@ async function runIntreactiveTestSuite(options) {
}
return acc;
},
{ unit: [], visual: [] }
_.zipObject(
TEST_SUITES,
TEST_SUITES.map(() => [])
)
);
return Promise.all(
_.map(tests, (files, suite) => {
Expand Down Expand Up @@ -556,7 +563,7 @@ program
.description('run test suite')
.addOption(
new commander.Option('-s, --suite <suite...>', 'test suite to run').choices(
['unit', 'visual']
TEST_SUITES
)
)
.option('-f, --file <file>', 'run a specific test file')
Expand Down Expand Up @@ -585,7 +592,7 @@ program
fs.removeSync(CLI_CACHE);
}
if (options.all) {
options.suite = ['unit', 'visual'];
options.suite = TEST_SUITES;
}
const results = [];
if (options.suite) {
Expand All @@ -599,13 +606,13 @@ program
} else if (options.file) {
results.push(
await test(
options.file.startsWith('visual') ? 'visual' : 'unit',
options.file.split(/\\|\//)[0],
[`test/${options.file}`],
options
)
);
} else {
results.push(...(await runIntreactiveTestSuite(options)));
results.push(...(await runInteractiveTestSuite(options)));
}
if (_.some(results)) {
// inform ci that tests have failed
Expand Down
5 changes: 5 additions & 0 deletions test/ts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { fabric } from '../..';
import { IsAny, assert } from 'conditional-type-checks';

assert<IsAny<typeof fabric>>(false);
assert<IsAny<typeof fabric.util>>(false);