migrating tests

This commit is contained in:
Val Erastov (xibyte) 2020-03-25 00:29:10 -07:00
parent a7ad8e2a3e
commit 0631525ace
7 changed files with 176 additions and 244 deletions

View file

@ -18,7 +18,7 @@ export function defineCypressTests(groupName, module) {
name: camelCaseSplitToStr(key.substring("test".length)),
funcName: key,
func,
...ModesConfig[module.TEST_MODE]
...ModesConfig[module.TEST_MODE],
};
});
@ -33,11 +33,25 @@ export function defineCypressTests(groupName, module) {
cy.window().then(win => {
return new Promise((resolve, reject) => {
const subject = test.testSubject(win);
const testEnv = new TestEnv(() => {
const onDone = () => {
cy.log("took: " + durationFormat(testEnv.took));
resolve();
});
win.__CAD_APP.streams.lifecycle.projectLoaded.attach(ready => {
};
const navigate = url => {
return new Promise((resolve) => {
cy.visit(url, {
onLoad: (contentWindow) => {
resolve(contentWindow);
}
});
});
};
const testEnv = new TestEnv(test.startPage, navigate, onDone);
test.loadStream(win).attach(ready => {
if (ready) {
test.func(testEnv, subject);
}

View file

@ -1,13 +1,16 @@
import modellerUISubject from "./subjects/modellerTPI";
import {createSketcherSubject} from "./subjects/sketcherTPI";
import {createSketcherTPI} from "./subjects/sketcherTPI";
import {constant} from "lstream";
export const ModesConfig = {
modellerUI: {
testSubject: win => modellerUISubject(win.__CAD_APP),
startPage: 'http://localhost:3000/index.html#TestProject'
startPage: 'http://localhost:3000/index.html#TestProject',
loadStream: win => win.__CAD_APP.streams.lifecycle.projectLoaded
},
sketcherUI: {
testSubject: win => createSketcherSubject(win.__CAD_APP),
startPage: 'http://localhost:3000/sketcher.html#TestProject'
testSubject: win => createSketcherTPI(win.__CAD_APP),
startPage: 'http://localhost:3000/sketcher.html#TestProject',
loadStream: win => constant(true)
},
};

View file

@ -20,21 +20,21 @@ export function createSubjectFromInPlaceSketcher(ctx) {
actions
};
return createSketcherSubject(oldStyleSketcherApp);
return createSketcherTPI(oldStyleSketcherApp);
}
export function createSketcherSubject(sketcherApp) {
export function createSketcherTPI(context) {
const viewer = sketcherApp.viewer;
const viewer = context.viewer;
viewer.parametricManager.messageSink = msg => console.log(msg);
const addSegment = sketcher_utils.addSegmentInModel.bind(this, sketcherApp);
const addArc = sketcher_utils.addArc.bind(this, sketcherApp);
const addCircle = sketcher_utils.addCircle.bind(this, sketcherApp);
const addEllipse = sketcher_utils.addEllipse.bind(this, sketcherApp);
const addEllipticalArc = sketcher_utils.addEllipticalArc.bind(this, sketcherApp);
const addBezier = sketcher_utils.addBezier.bind(this, sketcherApp);
const move = sketcher_utils.moveInModel.bind(this, sketcherApp);
const addSegment = sketcher_utils.addSegmentInModel.bind(this, context);
const addArc = sketcher_utils.addArc.bind(this, context);
const addCircle = sketcher_utils.addCircle.bind(this, context);
const addEllipse = sketcher_utils.addEllipse.bind(this, context);
const addEllipticalArc = sketcher_utils.addEllipticalArc.bind(this, context);
const addBezier = sketcher_utils.addBezier.bind(this, context);
const move = sketcher_utils.moveInModel.bind(this, context);
function addRectangle(x0, y0, x1, y1) {
return [
addSegment(x0, y0, x1, y0),
@ -82,24 +82,32 @@ export function createSketcherSubject(sketcherApp) {
function click(modelX, modelY, attrs) {
let [x, y] = sketcher_utils.modelToScreen(viewer, modelX, modelY);
sketcher_utils.clickXY(sketcherApp, x, y, attrs);
sketcher_utils.clickXY(context, x, y, attrs);
}
function select(objects, inclusive) {
sketcherApp.viewer.select(objects, !inclusive);
context.viewer.select(objects, !inclusive);
}
function runAction(id) {
sketcherApp.actions[id].action();
function runAction(id, actionContext) {
const action = context.actions[id];
if (!action ) {
throw `action ${id} doesn't exist`;
}
action.invoke(context, actionContext);
}
function toModel(x, y) {
return sketcher_utils.toModel(sketcherApp, x, y);
return sketcher_utils.toModel(context, x, y);
}
function toScreen(x, y) {
return sketcher_utils.modelToScreen(context.viewer, x, y);
}
return {
addSegment, addRectangle, addArc, addCircle, addEllipse, addEllipticalArc, addSerpinski, addBezier, addPolygon,
move, changeLayer, changeToConstructionLayer, changeToDefaultLayer, toModel,
move, changeLayer, changeToConstructionLayer, changeToDefaultLayer, toModel, toScreen,
click, select, runAction,
viewer
}

View file

@ -1,14 +1,21 @@
export class TestEnv {
constructor(callback) {
constructor(startingPage, navigate, callback) {
this.currentPage = startingPage;
this.navigateImpl = navigate;
this.callback = callback;
this.failed = false;
this.finished = false;
this.error = undefined;
this.callback = callback;
this.took = performance.now()
}
navigate(page) {
this.currentPage = page;
return this.navigateImpl(page);
}
done() {
if (this.finished) {
return;
@ -18,123 +25,9 @@ export class TestEnv {
this.callback(this);
}
fail(msg, optionalMsg) {
this.failed = true;
this.error = msg + (optionalMsg === undefined ? '' : ' ' + optionalMsg);
this.done();
throw assert.fail(this.error);
}
terminateOnError(error) {
this.failed = true;
this.error = error + "";
this.done();
throw error;
}
test(testBlock) {
const env = this;
return function() {
try {
testBlock.apply(this, arguments);
} catch (e) {
if (!env.finished) {
env.terminateOnError(e);
}
console.error(e);
}
}
testBlock.apply(this, arguments);
}
assertTrue(stmt, msg) {
if (!stmt) {
this.fail('assertTrue fails.', msg);
}
}
assertEmpty(array, msg) {
if (array.length !== 0) {
this.fail('assertEmpty fails. Array length = ' + array.length, msg);
}
}
assertFalse(stmt, msg) {
if (stmt) {
this.fail('assertFalse fails.', msg);
}
}
assertEquals(expected, actual, msg) {
if (expected !== actual) {
this.fail('assertEquals: Expected: ' + expected + ' but was ' + actual, msg);
}
}
assertFloatEquals(expected, actual, msg) {
if (Math.abs(expected - actual) >= 1E-6) {
this.fail('assertFloatEquals: Expected: ' + expected + ' but was ' + actual, msg);
}
}
assertPointXY2DEquals(expectedX, expectedY, actual, msg) {
if (actual.x !== expectedX || actual.y !== expectedY) {
this.fail('assertPoint2DEquals: Expected: (' + expectedX + ', ' + expectedY + ') but was (' + actual.x + ', ' + actual.y + ')' , msg);
}
}
assertPoint2DEquals(expected, actial, msg) {
this.assertPointXY2DEquals(expected.x, expected.y, actial, msg);
}
assertData(expected, actual) {
const expectedJSON = JSON.stringify(expected).replace(/\s/g, '');
const actualJSON = JSON.stringify(actual).replace(/\s/g, '');
if (actualJSON !== expectedJSON) {
console.log('EXPECTED:');
console.log(this.prettyJSON(expected));
console.log('ACTUAL:');
console.log(this.prettyJSON(actual));
if (checkSimilarity(expected, actual)) {
console.log("The data is similar(has same number of faces, loops and half-edges). Most likely it the test needs to be updated.");
} else {
console.warn("The data isn't similar(has different number of faces, loops or half-edges). Most likely something is really broken.");
}
this.fail('expected data different from actual. ^^see log above^^');
}
}
prettyJSON(obj) {
return JSON.stringify(obj, null, 0);
}
}
function checkSimilarity(data1, data2) {
function edgesCount(data) {
let count = 0;
for (let face of data.faces) {
face.forEach((loop) => count += loop.length);
}
return count;
}
function loopsCount(data) {
let count = 0;
for (let face of data.faces) {
face.forEach(() => count ++);
}
return count;
}
function info(data) {
const loops = loopsCount(data);
const edges = edgesCount(data);
return `faces: ${data.faces.length}; loops: ${loops}; half-edges: ${edges}`;
}
const info1 = info(data1);
const info2 = info(data2);
console.log(info1 + " : " + info2);
return info1 === info2;
}

View file

@ -1,31 +1,41 @@
import Vector from 'math/vector';
import {assertEquals, assertPoint2DEquals} from "../utils/asserts";
import {createSketcherTPI} from "../subjects/sketcherTPI";
export const TEST_MODE = 'sketcherUI';
export function testSegmentWizard(env, tpi) {
env.assertEquals(0, tpi.viewer.activeLayer.objects.length);
assertEquals(0, tpi.viewer.activeLayer.objects.length);
tpi.addSegment(10, 10, 100, 100);
assertEquals(1, tpi.viewer.activeLayer.objects.length);
const segment = tpi.viewer.activeLayer.objects[0];
assertEquals('TCAD.TWO.Segment', segment._class);
assertPoint2DEquals(tpi.toModel(10, 10), segment.a);
assertPoint2DEquals(tpi.toModel(100, 100), segment.b);
const [asx, asy] = tpi.toScreen(10, 10);
const [bsx, bsy] = tpi.toScreen(100, 100);
assertPoint2DEquals(tpi.toModel(asx, asy), segment.a);
assertPoint2DEquals(tpi.toModel(bsx, bsy), segment.b);
env.done();
}
//
// function testSaveLoad(env, tpi) {
// env.assertEquals(0, app.viewer.activeLayer.objects.length);
// tpi.addSegment(10, 10, 100, 100);
// app.actions['save'].action();
// test.sketch(env.test((win, app) => {
// env.assertEquals(1, app.viewer.activeLayer.objects.length);
// const segment = app.viewer.activeLayer.objects[0];
// env.assertEquals('TCAD.TWO.Segment', segment._class);
// env.done();
// }));
// },
export function testSaveLoad(env, tpi) {
assertEquals(0, tpi.viewer.activeLayer.objects.length);
tpi.addSegment(10, 10, 100, 100);
tpi.runAction('Save');
cy.visit('http://localhost:3000');
cy.window().then(win => {
env.done();
});
// env.navigate('http://google.com').then(win => {
// const tpi = createSketcherTPI(win.__CAD_APP);
// assertEquals(1, tpi.viewer.activeLayer.objects.length);
// const segment = tpi.viewer.activeLayer.objects[0];
// assertEquals('TCAD.TWO.Segment', segment._class);
//
// });
}
testSaveLoad.only = true;
//
// testSelection: function(env) {
// test.emptySketch(env.test((win, app) => {

View file

@ -1,43 +1,43 @@
import {TestMouseEvent} from './mouseEvent'
import Vector from 'math/vector';
export function toModel(app, x, y) {
return app.viewer._screenToModel(x, y);
export function toModel(ctx, x, y) {
return ctx.viewer._screenToModel(x, y);
}
export function toModelP(app, point) {
return app.viewer._screenToModel(point.x, point.y);
export function toModelP(ctx, point) {
return ctx.viewer._screenToModel(point.x, point.y);
}
export function getConstraints(app) {
return app.viewer.parametricManager.system.constraints;
export function getConstraints(ctx) {
return ctx.viewer.parametricManager.system.constraints;
}
export function click(app, point, attrs) {
clickXY(app, point.x, point.y, attrs);
export function click(ctx, point, attrs) {
clickXY(ctx, point.x, point.y, attrs);
}
export function clickXY(app, x, y, attrs) {
app.viewer.toolManager.tool.mousedown(new TestMouseEvent(x, y, 'mousedown', attrs));
app.viewer.toolManager.tool.mouseup(new TestMouseEvent(x, y, 'mouseup', attrs));
export function clickXY(ctx, x, y, attrs) {
ctx.viewer.toolManager.tool.mousedown(new TestMouseEvent(x, y, 'mousedown', attrs));
ctx.viewer.toolManager.tool.mouseup(new TestMouseEvent(x, y, 'mouseup', attrs));
}
export function moveAndClickXY(app, x, y, attrs) {
app.viewer.toolManager.tool.mousemove(new TestMouseEvent(x, y, 'mousedown', attrs));
clickXY(app, x, y, attrs);
export function moveAndClickXY(ctx, x, y, attrs) {
ctx.viewer.toolManager.tool.mousemove(new TestMouseEvent(x, y, 'mousedown', attrs));
clickXY(ctx, x, y, attrs);
}
export function move(app, from, to) {
const toolManager = app.viewer.toolManager;
export function move(ctx, from, to) {
const toolManager = ctx.viewer.toolManager;
toolManager.tool.mousedown(new TestMouseEvent(from.x, from.y));
toolManager.tool.mousemove(new TestMouseEvent(to.x, to.y));
toolManager.tool.mouseup(new TestMouseEvent(to.x, to.y));
}
export function moveInModel(app, fromX, fromY, toX, toY) {
const toolManager = app.viewer.toolManager;
[fromX, fromY] = modelToScreen(app.viewer, fromX, fromY);
[toX, toY] = modelToScreen(app.viewer, toX, toY);
export function moveInModel(ctx, fromX, fromY, toX, toY) {
const toolManager = ctx.viewer.toolManager;
[fromX, fromY] = modelToScreen(ctx.viewer, fromX, fromY);
[toX, toY] = modelToScreen(ctx.viewer, toX, toY);
toolManager.tool.mousemove(new TestMouseEvent(fromX, fromY));
toolManager.tool.mousedown(new TestMouseEvent(fromX, fromY));
@ -46,94 +46,94 @@ export function moveInModel(app, fromX, fromY, toX, toY) {
}
export function addSegment(app, aX, aY, bX, bY) {
app.actions.SegmentTool.invoke(app.context);
const tool = app.viewer.toolManager.tool;
export function addSegment(ctx, aX, aY, bX, bY) {
ctx.actions.SegmentTool.invoke(ctx);
const tool = ctx.viewer.toolManager.tool;
tool.mousemove(new TestMouseEvent(aX, aY));
tool.mousedown(new TestMouseEvent(aX, aY));
tool.mouseup(new TestMouseEvent(aX, aY));
tool.mousemove(new TestMouseEvent(bX, bY));
const segment = tool.line;
tool.mouseup(new TestMouseEvent(bX, bY));
app.viewer.toolManager.releaseControl();
ctx.viewer.toolManager.releaseControl();
return segment;
}
export function addSegmentInModel(app, aX, aY, bX, bY) {
export function addSegmentInModel(ctx, aX, aY, bX, bY) {
[aX, aY] = modelToScreen(app.viewer, aX, aY);
[bX, bY] = modelToScreen(app.viewer, bX, bY);
[aX, aY] = modelToScreen(ctx.viewer, aX, aY);
[bX, bY] = modelToScreen(ctx.viewer, bX, bY);
return addSegment(app, aX, aY, bX, bY);
return addSegment(ctx, aX, aY, bX, bY);
}
export function addArc(app, cX, cY, aX, aY, bX, bY) {
export function addArc(ctx, cX, cY, aX, aY, bX, bY) {
[aX, aY] = modelToScreen(app.viewer, aX, aY);
[bX, bY] = modelToScreen(app.viewer, bX, bY);
[cX, cY] = modelToScreen(app.viewer, cX, cY);
[aX, aY] = modelToScreen(ctx.viewer, aX, aY);
[bX, bY] = modelToScreen(ctx.viewer, bX, bY);
[cX, cY] = modelToScreen(ctx.viewer, cX, cY);
app.actions['addArc'].action();
ctx.actions['addArc'].action();
moveAndClickXY(app, cX, cY);
moveAndClickXY(app, aX, aY);
let arc = app.viewer.toolManager.tool.arc;
moveAndClickXY(app, bX, bY);
app.viewer.toolManager.releaseControl();
moveAndClickXY(ctx, cX, cY);
moveAndClickXY(ctx, aX, aY);
let arc = ctx.viewer.toolManager.tool.arc;
moveAndClickXY(ctx, bX, bY);
ctx.viewer.toolManager.releaseControl();
return arc;
}
export function addCircle(app, cX, cY, R) {
let [rX, rY] = modelToScreen(app.viewer, cX + R, cY);
[cX, cY] = modelToScreen(app.viewer, cX, cY);
app.actions['addCircle'].action();
moveAndClickXY(app, cX, cY);
let circle = app.viewer.toolManager.tool.circle;
moveAndClickXY(app, rX, rY);
app.viewer.toolManager.releaseControl();
export function addCircle(ctx, cX, cY, R) {
let [rX, rY] = modelToScreen(ctx.viewer, cX + R, cY);
[cX, cY] = modelToScreen(ctx.viewer, cX, cY);
ctx.actions['addCircle'].action();
moveAndClickXY(ctx, cX, cY);
let circle = ctx.viewer.toolManager.tool.circle;
moveAndClickXY(ctx, rX, rY);
ctx.viewer.toolManager.releaseControl();
return circle;
}
export function addEllipse(app, aX, aY, bX, bY, rX, rY) {
[aX, aY] = modelToScreen(app.viewer, aX, aY);
[bX, bY] = modelToScreen(app.viewer, bX, bY);
[rX, rY] = modelToScreen(app.viewer, rX, rY);
app.actions['addEllipse'].action();
moveAndClickXY(app, aX, aY);
let ellipse = app.viewer.toolManager.tool.ellipse;
moveAndClickXY(app, bX, bY);
moveAndClickXY(app, rX, rY);
app.viewer.toolManager.releaseControl();
export function addEllipse(ctx, aX, aY, bX, bY, rX, rY) {
[aX, aY] = modelToScreen(ctx.viewer, aX, aY);
[bX, bY] = modelToScreen(ctx.viewer, bX, bY);
[rX, rY] = modelToScreen(ctx.viewer, rX, rY);
ctx.actions['addEllipse'].action();
moveAndClickXY(ctx, aX, aY);
let ellipse = ctx.viewer.toolManager.tool.ellipse;
moveAndClickXY(ctx, bX, bY);
moveAndClickXY(ctx, rX, rY);
ctx.viewer.toolManager.releaseControl();
return ellipse;
}
export function addEllipticalArc(app, aX, aY, bX, bY, rX, rY) {
[aX, aY] = modelToScreen(app.viewer, aX, aY);
[bX, bY] = modelToScreen(app.viewer, bX, bY);
[rX, rY] = modelToScreen(app.viewer, rX, rY);
app.actions['addEllipticalArc'].action();
moveAndClickXY(app, aX, aY);
let ellipse = app.viewer.toolManager.tool.ellipse;
moveAndClickXY(app, bX, bY);
moveAndClickXY(app, rX, rY);
app.viewer.toolManager.releaseControl();
export function addEllipticalArc(ctx, aX, aY, bX, bY, rX, rY) {
[aX, aY] = modelToScreen(ctx.viewer, aX, aY);
[bX, bY] = modelToScreen(ctx.viewer, bX, bY);
[rX, rY] = modelToScreen(ctx.viewer, rX, rY);
ctx.actions['addEllipticalArc'].action();
moveAndClickXY(ctx, aX, aY);
let ellipse = ctx.viewer.toolManager.tool.ellipse;
moveAndClickXY(ctx, bX, bY);
moveAndClickXY(ctx, rX, rY);
ctx.viewer.toolManager.releaseControl();
return ellipse;
}
export function addBezier(app, aX, aY, bX, bY) {
[aX, aY] = modelToScreen(app.viewer, aX, aY);
[bX, bY] = modelToScreen(app.viewer, bX, bY);
app.actions['addBezierCurve'].action();
moveAndClickXY(app, aX, aY);
let curve = app.viewer.toolManager.tool.curve;
moveAndClickXY(app, bX, bY);
app.viewer.toolManager.releaseControl();
export function addBezier(ctx, aX, aY, bX, bY) {
[aX, aY] = modelToScreen(ctx.viewer, aX, aY);
[bX, bY] = modelToScreen(ctx.viewer, bX, bY);
ctx.actions['addBezierCurve'].action();
moveAndClickXY(ctx, aX, aY);
let curve = ctx.viewer.toolManager.tool.curve;
moveAndClickXY(ctx, bX, bY);
ctx.viewer.toolManager.releaseControl();
return curve;
}
export function polyLine(app) {
app.actions['addMultiSegment'].action();
const tool = app.viewer.toolManager.tool;
export function polyLine(ctx) {
ctx.actions['addMultiSegment'].action();
const tool = ctx.viewer.toolManager.tool;
for (let i = 1; i < arguments.length; ++i) {
let p = arguments[i];
tool.mousemove(new TestMouseEvent(p.x, p.y));
@ -141,7 +141,7 @@ export function polyLine(app) {
tool.mouseup(new TestMouseEvent(p.x, p.y));
}
tool.cancelSegment();
app.viewer.toolManager.releaseControl();
ctx.viewer.toolManager.releaseControl();
}
@ -161,17 +161,11 @@ export class TestSegment {
return this.a.plus(half);
}
add(app) {
return addSegment(app, this.a.x, this.a.y, this.b.x, this.b.y);
add(ctx) {
return addSegment(ctx, this.a.x, this.a.y, this.b.x, this.b.y);
}
}
export function modelToScreen(viewer, x, y) {
if (viewer.screenToModelMatrix) {
let modelToScreenMx = viewer.screenToModelMatrix.invert();
[x, y] = modelToScreenMx.apply3([x, y, 0]);
}
x /= viewer.retinaPxielRatio;
y = (viewer.canvas.height - y) / viewer.retinaPxielRatio;
return [x, y];
return viewer.modelToScreen(x, y);
}

View file

@ -357,6 +357,16 @@ class Viewer {
return out;
};
modelToScreen(x, y) {
if (this.screenToModelMatrix) {
let modelToScreenMx = this.screenToModelMatrix.invert();
[x, y] = modelToScreenMx.apply3([x, y, 0]);
}
x /= this.retinaPxielRatio;
y = (this.canvas.height - y) / this.retinaPxielRatio;
return [x, y];
}
accept = visitor => {
for (let layer of this.layers) {
for (let object of layer.objects) {