Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add property based tests to DataBus #454

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@types/node": "^14.14.34",
"@types/qs": "^6.9.4",
"@types/string.prototype.matchall": "^4.0.1",
"fast-check": "^3.6.3",
"jest": "^29.2.2",
"jest-environment-jsdom": "^29.2.2",
"mockjs": "1.1.0",
Expand Down
124 changes: 124 additions & 0 deletions packages/core/src/databus/__tests__/databus-fast-check.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { MockDataBus, resetDataLoader } from './mock.databus';
import { ResourceType } from 'types';
import { CollaCommandName, } from 'commands';

Check warning

Code scanning / ESLint

require or disallow trailing commas

Unexpected trailing comma.
import { ExecuteResult } from 'command_manager';
import * as fc from 'fast-check';
import { mockGetViewInfo } from './mock.view';
import * as console from 'console';

const db = MockDataBus.getDatabase();

beforeAll(resetDataLoader);

describe('fast check try', () => {
const contains = (text: string, pattern: string) => {
if (text.length > 3) {
return text.substr(1).indexOf(pattern) === -1;
} else {
return text.indexOf(pattern) >= 0;
}
Comment on lines +17 to +19

Check warning

Code scanning / ESLint

disallow `else` blocks after `return` statements in `if` statements

Unnecessary 'else' after 'return'.
};

test('should always contain itself', () => {
fc.assert(fc.asyncProperty(fc.string(), (text: string) => {
return new Promise(resolve => {
resolve(contains(text, text));
});
}), { verbose: true });
});

});

describe('fast check doCommand Operation', () => {

test('check revision and datasheet pros after a AddRecords doCommand operation', async() => {
const dst1 = await db.getDatasheet('dst1', {});
expect(dst1).toBeTruthy();

const oldRevision = dst1!.revision;
expect(oldRevision).toStrictEqual(12);
let expectRevisionChangedCount = 0;

await fc.assert(fc.asyncProperty(fc.integer(),
async(aInt: number) => {
const result = await dst1!.doCommand(
{
cmd: CollaCommandName.AddRecords,
viewId: 'viw1',
index: 3,
count: aInt % 10,
},
{},
);
// check Revision change count. only the result is success will call saveOps
if (result.result === ExecuteResult.Success) {
expectRevisionChangedCount += 1;
}

// the id, name, and type field of the Datasheet are not changed.
const prosEq = (dst1!.id === 'dst1' && dst1!.type === ResourceType.Datasheet && dst1!.name === 'datasheet 1');
expect(dst1!.id).toStrictEqual('dst1');
expect(dst1!.type).toStrictEqual(ResourceType.Datasheet);
expect(dst1!.name).toStrictEqual('datasheet 1');
return new Promise(resolve => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A simple return prosEq is enough.

resolve(prosEq);
});
}), { verbose: true, timeout: 30000 },
);
expect(dst1?.revision).toBe(expectRevisionChangedCount + oldRevision);
});

test('check datasheet\'s field count after a AddFields doCommand operation', async() => {
const dst1 = await db.getDatasheet('dst1', {});
expect(dst1).toBeTruthy();
if (dst1 == null) {
return;
}
const dstId = dst1?.id || '';
const view1 = await dst1!.getView({
getViewInfo: mockGetViewInfo('dst1', 'viw1'),
});
const oldViewColumnCount = view1?.columns.length || 0;
expect(oldViewColumnCount).toStrictEqual(2);
let expectFieldAddedCount = 0;
await fc.assert(fc.asyncProperty(fc.string(), fc.integer({min: 2 , max: 200}),

Check warning

Code scanning / ESLint

enforce consistent spacing inside braces

A space is required after '{'.

Check warning

Code scanning / ESLint

enforce consistent spacing inside braces

A space is required before '}'.
async (aStr: string, aInt: number) => {

Check warning

Code scanning / ESLint

enforce consistent spacing before `function` definition opening parenthesis

Unexpected space before function parentheses.
const oldFieldCount = Object.keys(dst1.fields).length;
const result = await dst1!.doCommand(
{
cmd: CollaCommandName.AddFields,
data: [{
data: {
id: aStr,
name: aStr,
property: null,
type: 1,
},
index: aInt,
viewId: 'viw1',
}],
copyCell: false,
datasheetId: dstId,
},
{},
);
// check Revision change count. only the result is success will call saveOps
if (result.result === ExecuteResult.Success) {
expectFieldAddedCount += 1;
}else {
console.error('some error happens');
}

const fieldCount = Object.keys(dst1.fields).length;
return new Promise(resolve => {
resolve(fieldCount >= (oldFieldCount + 1));
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing assertions inside this function

}), { verbose: true, timeout: 30000 },
);
const view2 = await dst1!.getView({
getViewInfo: mockGetViewInfo('dst1', 'viw1'),
});
expect(view2?.columns.length).toStrictEqual(oldViewColumnCount + expectFieldAddedCount);
});

});
6 changes: 6 additions & 0 deletions packages/core/src/databus/__tests__/mock.data.loader.saver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { IDataSaver, ISaveOpsOptions } from 'databus/data.saver.interface';
import { IBaseDatasheetPack, Selectors, StoreActions } from 'exports/store';
import { IDataLoader } from '../data.loader.interface';
import { mockDatasheetMap } from './mock.datasheets';
import { ResourceType } from '../../types';

export class MockDataLoaderSaver implements IDataLoader, IDataSaver {
datasheets!: Record<string, IBaseDatasheetPack>;
Expand All @@ -46,6 +47,11 @@ export class MockDataLoaderSaver implements IDataLoader, IDataSaver {
changesets.forEach(cs => {
store.dispatch(StoreActions.applyJOTOperations(cs.operations, cs.resourceType, cs.resourceId));

// Every time change happens, we should add the value of the Revision here.
// It should be noted that only the return result is the SUCCESS timing code.
if (cs.baseRevision !== undefined) {
store.dispatch(StoreActions.updateRevision(cs.baseRevision + 1, cs.resourceId, ResourceType.Datasheet));
}
this.datasheets[cs.resourceId] = {
datasheet: Selectors.getDatasheet(store.getState())!,
snapshot: Selectors.getSnapshot(store.getState())!,
Expand Down
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ __metadata:
axios: 0.21.2
color: ^3.1.3
dayjs: ^1.11.7
fast-check: ^3.6.3
fuse.js: ^6.4.1
immer: 9.0.16
jest: ^29.2.2
Expand Down Expand Up @@ -23238,6 +23239,15 @@ __metadata:
languageName: node
linkType: hard

"fast-check@npm:^3.6.3":
version: 3.6.3
resolution: "fast-check@npm:3.6.3"
dependencies:
pure-rand: ^6.0.0
checksum: c3732011ceef2c3a999678a932cf051946a484d564a73bac695066a255510b2e6a1102bd5cacc189919326ea5c7a515e0247b376416f348c3bc323ee4f4ec7c8
languageName: node
linkType: hard

"fast-csv@npm:^3.4.0":
version: 3.7.0
resolution: "fast-csv@npm:3.7.0"
Expand Down Expand Up @@ -37219,6 +37229,13 @@ fsevents@^1.2.7:
languageName: node
linkType: hard

"pure-rand@npm:^6.0.0":
version: 6.0.0
resolution: "pure-rand@npm:6.0.0"
checksum: ad1378d0a4859482d053a5264b2b485b445ece4bbc56f8959c233ea678b81ac2d613737925d496ded134eff5f29cc5546bf7492b6bce319ee27bebbad8a0c612
languageName: node
linkType: hard

"q@npm:^1.5.1":
version: 1.5.1
resolution: "q@npm:1.5.1"
Expand Down