Skip to content

Commit

Permalink
onDemand loading of unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rinick committed Feb 8, 2021
1 parent eea43c3 commit 4c3e6ea
Show file tree
Hide file tree
Showing 8 changed files with 1,740 additions and 1,819 deletions.
27 changes: 16 additions & 11 deletions bin/test-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ const packagesToTest = ['./src/core', './src/express', './src/node', './src/http
describe: 'Start the test server',
type: 'boolean',
},
onDemandLoad: {
default: false,
describe: 'Load test when its enabled, and unload it when disabled',
type: 'boolean',
},
quitOnFinish: {
default: false,
describe: 'End the test process when all tests are finished',
Expand All @@ -40,12 +45,12 @@ const packagesToTest = ['./src/core', './src/express', './src/node', './src/http
},
})
.help();
let argv = parser.parse();
let {onDemandLoad, serve, port, run, quitOnSuccess, quitOnFinish} = parser.parse();

await Root.instance.setStorage(new TestLoader(packagesToTest));
await Root.instance.setStorage(new TestLoader(packagesToTest, {onDemandLoad}));

let app = Express();
if (argv.serve) {
if (serve) {
connectTiclo(app, '/ticlo');
}
routeTiclo(app, '/ticlo');
Expand All @@ -54,29 +59,29 @@ const packagesToTest = ['./src/core', './src/express', './src/node', './src/http
res.end();
});

let server = app.listen(argv.port, () => {
console.log(`listening on ${argv.port}`);
if (argv.serve) {
console.log(getEditorUrl(`ws://127.0.0.1:${argv.port}/ticlo`, 'example'));
let server = app.listen(port, () => {
console.log(`listening on ${port}`);
if (serve) {
console.log(getEditorUrl(`ws://127.0.0.1:${port}/ticlo`, 'example'));
}
});

if (argv.run) {
if (run) {
let testRunner = new TestRunner(
Root.instance.getValue('tests') as FlowTestGroup,
() => {
if (argv.quitOnFinish || (argv.quitOnSuccess && testRunner.failed === 0)) {
if (quitOnFinish || (quitOnSuccess && testRunner.failed === 0)) {
if (testRunner.failed > 0) {
process.exit(3);
} else {
process.exit(0);
}
}
},
argv.serve // allow editing when editing server is enabled
serve // allow editing when editing server is enabled
);
testRunner.run();
} else if (!argv.serve) {
} else if (!serve) {
console.error('at least one of these flag is needed: --run , --serve ');
process.exit(1);
}
Expand Down
48 changes: 24 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,60 +12,60 @@
},
"license": "MPL-2.0",
"dependencies": {
"denque": "^1.4.1",
"i18next": "^19.8.4",
"denque": "^1.5.0",
"i18next": "^19.8.7",
"jsonesc": "^0.4.11",
"lodash": "^4.17.20",
"moment": "^2.29.1",
"moment-timezone": "^0.5.32",
"qs": "^6.9.4",
"moment-timezone": "^0.5.33",
"qs": "^6.9.6",
"yargs": "^16.2.0"
},
"devDependencies": {
"@ant-design/icons": "^4.3.0",
"@babel/core": "^7.12.10",
"@ant-design/icons": "^4.4.0",
"@babel/core": "^7.12.13",
"@types/body-parser": "^1.19.0",
"@types/chai": "^4.2.14",
"@types/codemirror": "^0.0.106",
"@types/dompurify": "^2.1.0",
"@types/express": "^4.17.9",
"@types/codemirror": "^0.0.108",
"@types/dompurify": "^2.2.1",
"@types/express": "^4.17.11",
"@types/express-ws": "^3.0.0",
"@types/glob": "^7.1.3",
"@types/karma": "^5.0.1",
"@types/marked": "^1.2.1",
"@types/karma": "^6.1.0",
"@types/marked": "^1.2.2",
"@types/mocha": "^8.2.0",
"@types/node": "^14.14.16",
"@types/node": "^14.14.25",
"@types/qs": "^6.9.5",
"@types/react": "^17.0.0",
"@types/react": "^17.0.1",
"@types/react-color": "^3.0.4",
"@types/react-dom": "^17.0.0",
"@types/shelljs": "^0.8.8",
"@types/tinycolor2": "^1.4.2",
"@types/ws": "^7.4.0",
"@types/yargs": "^15.0.12",
"antd": "^4.10.0",
"@types/yargs": "^16.0.0",
"antd": "^4.12.2",
"axios": "^0.21.1",
"body-parser": "^1.19.0",
"chai": "^4.2.0",
"codemirror": "^5.59.0",
"chai": "^4.3.0",
"codemirror": "^5.59.2",
"coveralls": "^3.1.0",
"cross-env": "^7.0.3",
"dompurify": "^2.2.6",
"express": "^4.17.1",
"express-ws": "^4.0.0",
"glob": "^7.1.6",
"karma": "^5.2.3",
"karma": "^6.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-mocha": "^2.0.1",
"karma-typescript": "^5.2.0",
"less": "^4.0.0",
"marked": "^1.2.7",
"less": "^4.1.1",
"marked": "^1.2.9",
"mocha": "^8.2.1",
"nyc": "^15.1.0",
"parcel": "2.0.0-nightly.535",
"parcel": "2.0.0-nightly.574",
"prettier": "^2.2.1",
"rc-dock": "^3.0.0",
"rc-trigger": "^5.2.0",
"rc-dock": "^3.0.2",
"rc-trigger": "^5.2.1",
"react": "^17.0.1",
"react-codemirror2": "^7.2.1",
"react-color": "^2.19.3",
Expand All @@ -78,7 +78,7 @@
"tslint": "^6.1.3",
"tslint-react": "^5.0.0",
"typescript": "^4.1.3",
"ws": "^7.4.1",
"ws": "^7.4.3",
"yaml": "^1.10.0"
},
"resolutions": {
Expand Down
30 changes: 23 additions & 7 deletions src/core/block/Flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ import {Functions} from './Functions';
import {Storage} from './Storage';
import {FlowHistory} from './FlowHistory';

export enum FlowState {
enabled,
disabled,
destroyed,
}
export interface FlowLoader {
createFlow?(prop: BlockProperty): Flow;
applyChange?(data: DataMap): boolean;
onDestroy?(): void;
onStateChange?(flow: Flow, state: FlowState): void;
}

export class Flow extends Block {
Expand Down Expand Up @@ -73,6 +78,7 @@ export class Flow extends Block {

_disableBlock() {
this._applyFuncid(null);
this._onStateChange?.(this, FlowState.disabled);
for (let [key, prop] of this._props) {
let val = prop._value;
if (val instanceof Block && val._prop === prop) {
Expand All @@ -83,6 +89,7 @@ export class Flow extends Block {

_enabledBlock() {
this._applyFuncid(this._funcId);
this._onStateChange?.(this, FlowState.enabled);
for (let [key, prop] of this._props) {
let val = prop._value;
if (val instanceof Block && val._prop === prop) {
Expand Down Expand Up @@ -136,9 +143,14 @@ export class Flow extends Block {
}

_applyChange: (data: DataMap) => boolean;
_onDestory: () => void;

load(src: DataMap, funcId?: string, applyChange?: (data: DataMap) => boolean, onDestory?: () => void): boolean {
_onStateChange: (flow: Flow, state: FlowState) => void;

load(
src: DataMap,
funcId?: string,
applyChange?: (data: DataMap) => boolean,
onStateChange?: (flow: Flow, state: FlowState) => void
): boolean {
this._loading = true;
let loaded = false;
if (funcId) {
Expand Down Expand Up @@ -173,11 +185,15 @@ export class Flow extends Block {
}
if (loaded) {
this._applyChange = applyChange;
this._onDestory = onDestory;
this._onStateChange = onStateChange;
}
this._loading = false;
return loaded;
}
// load data but not update applyChange or onStateChange
loadData(data: DataMap) {
this.load(data, null, this._applyChange, this._onStateChange);
}

_loadFlowData(map: DataMap, funcId?: string) {
super._load(map);
Expand Down Expand Up @@ -276,7 +292,7 @@ export class Flow extends Block {
this._history = null;
}

this._onDestory?.();
this._onStateChange?.(this, FlowState.destroyed);
super.destroy();
}
}
Expand Down Expand Up @@ -416,7 +432,7 @@ export class Root extends Flow {
if (!data) {
data = {};
}
newFlow.load(data, null, loader.applyChange, loader.onDestroy);
newFlow.load(data, null, loader.applyChange, loader.onStateChange);
if (this._storage?.inited && Object.keys(data).length) {
this._storage.saveFlow(path, newFlow, data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/block/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export interface Storage {
inited?: boolean;
init(root: Root): any; // void or promise

// return [applyChange,onDestroy] of a flow
// return [applyChange,onStateChange] of a flow
getFlowLoader(name: string, prop: BlockProperty): FlowLoader;
}
44 changes: 39 additions & 5 deletions src/node/storage/FileStorage.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
import Fs from 'fs';
import Path from 'path';
import {Flow, Root, encodeSorted, decode, DataMap, Storage, BlockProperty} from '../../../src/core';
import {BlockProperty, DataMap, decode, encodeSorted, Flow, Root, Storage} from '../../../src/core';
import {WorkerFunction} from '../../../src/core/worker/WorkerFunction';
import {FlowLoader} from '../../../src/core/block/Flow';
import {FlowLoader, FlowState} from '../../../src/core/block/Flow';

export class FlowIOTask {
current?: 'write' | 'delete';
current?: 'write' | 'delete' | 'read';
next?: 'write' | 'delete';
reading: Promise<string>;
_resolveReading: Function;
nextData: string;

constructor(public loader: FileStorage, public name: string, public path: string) {}

read() {
if (!this.reading) {
this.reading = new Promise<string>((resolve) => {
this._resolveReading = resolve;
});
}
if (!this.current) {
this.current = 'read';
Fs.readFile(this.path, 'utf8', this.onRead);
}
return this.reading;
}
onRead = (err: NodeJS.ErrnoException | null, data: string) => {
if (this._resolveReading) {
this._resolveReading(data);
}
this.reading = null;
this._resolveReading = null;
this.onDone();
};

write(data: string) {
if (this.next || this.current) {
this.next = 'write';
Expand Down Expand Up @@ -39,11 +62,12 @@ export class FlowIOTask {
}

onDone = () => {
this.current = null;
if (this.next) {
let {next, nextData} = this;
this.next = null;
this.nextData = null;
this.current = null;

switch (next) {
case 'delete':
this.delete();
Expand All @@ -52,6 +76,8 @@ export class FlowIOTask {
this.write(nextData);
return;
}
} else if (this.reading) {
let ignoredPromise = this.read();
} else {
this.loader.taskDone(this);
}
Expand Down Expand Up @@ -89,10 +115,18 @@ export class FileStorage implements Storage {
this.saveFlow(name, null, data);
return true;
},
onDestroy: () => this.deleteFlow(name),
onStateChange: (flow: Flow, state: FlowState) => this.flowStateChanged(flow, name, state),
};
}

flowStateChanged(flow: Flow, name: string, state: FlowState) {
switch (state) {
case FlowState.destroyed:
this.deleteFlow(name);
break;
}
}

deleteFlow(name: string) {
this.getTask(name).delete();
}
Expand Down

0 comments on commit 4c3e6ea

Please sign in to comment.