diff --git a/config/scripts.yaml b/config/scripts.yaml index e6492df9797..7ff69749c2d 100644 --- a/config/scripts.yaml +++ b/config/scripts.yaml @@ -25,7 +25,7 @@ components: test: *notests core: report: 'nyc report --reporter=html' - test: 'nyc -x node_modules -x tests/fixtures -x bin-pack npx mocha tests/*.test.js' + test: 'nyc -x node_modules -x tests -x bin-pack npx mocha tests/*.test.js' testci: "nyc --silent npx mocha tests/*.test.js --reporter ../../tests/reporters/terse.js && nyc report --reporter=json" testonly: 'npx mocha tests/*.test.js' i18n: diff --git a/packages/core/package.json b/packages/core/package.json index 89fd1a6d735..8fedebc13ec 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -32,7 +32,7 @@ "clean": "rimraf dist", "mbuild": "NO_MINIFY=1 node build.js", "symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -", - "test": "nyc -x node_modules -x tests/fixtures -x bin-pack npx mocha tests/*.test.js", + "test": "nyc -x node_modules -x tests -x bin-pack npx mocha tests/*.test.js", "vbuild": "VERBOSE=1 node build.js", "lab": "cd ../../sites/lab && yarn start", "tips": "node ../../scripts/help.mjs", diff --git a/packages/core/src/path.js b/packages/core/src/path.js index 710fa01f2fe..3ae6b21ac91 100644 --- a/packages/core/src/path.js +++ b/packages/core/src/path.js @@ -90,7 +90,7 @@ Path.prototype.curve_ = function (cp1, to) { if (to instanceof Point !== true) this.raise.warning('Called `Path.curve_(cp1, to)` but `to` is not a `Point` object') if (cp1 instanceof Point !== true) - this.raise.warning('Called `Path.curve_(cp1, to)` but `cp2` is not a `Point` object') + this.raise.warning('Called `Path.curve_(cp1, to)` but `cp1` is not a `Point` object') let cp2 = to.copy() this.ops.push({ type: 'curve', cp1, cp2, to }) @@ -599,7 +599,6 @@ Path.prototype.edge = function (side) { return curveEdge(curve, side) } } - this.raise.error(`Unable to find \`Path.edge(side)\` for side ${side}`) } function edgeCurveAsBezier(op) { diff --git a/packages/core/tests/path.test.js b/packages/core/tests/path.test.js index 8a9bae20b31..920acf409ef 100644 --- a/packages/core/tests/path.test.js +++ b/packages/core/tests/path.test.js @@ -183,6 +183,15 @@ it("Should shift along a line", () => { expect(a.paths.line.shiftAlong(20).y).to.equal(20); }); +it("Should not shift along a path/line if we end up on the end point", () => { + let pattern = new freesewing.Pattern(); + pattern.parts.a = new pattern.Part(); + let a = pattern.parts.a; + + a.paths.line = new a.Path().move(new a.Point(0, 0)).line(new a.Point(10, 0)); + expect(a.paths.line.shiftAlong(10).x).to.equal(10); +}); + it("Should shift along lines", () => { let pattern = new freesewing.Pattern(); pattern.parts.a = new pattern.Part(); @@ -796,3 +805,356 @@ it("Should move along a path even if it lands just on a joint", () => { a.points.test = a.paths.curve.shiftAlong(121.36690836797631) expect(a.points.test).to.be.instanceOf(a.Point) }) + +it("Should add raise methods to a path", () => { + const raise = () => 'hello' + const p1 = new freesewing.Path(10, 20).withRaise(raise); + expect(p1.raise()).to.equal('hello'); +}); + +it("Should add raise methods to a path", () => { + const raise = () => 'hello' + const p1 = new freesewing.Path().withRaise(raise); + expect(p1.raise()).to.equal('hello'); +}); + +it("Should set render to true/false", () => { + const p1 = new freesewing.Path().setRender(false) + expect(p1.render).to.equal(false); +}); + +it("Should set class with setClass", () => { + const p1 = new freesewing.Path().setClass('fabric') + p1.setClass() + expect(p1.attributes.get('class')).to.equal('fabric'); +}); + +it("Should raise a warning when moving to a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + expect(invalid).to.equal(false); + try { + p1.move('a') + } + catch (err) { + expect(''+err).to.contain("check is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a line to a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + expect(invalid).to.equal(false); + try { + p1.line('a') + } + catch (err) { + expect(''+err).to.contain("check is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a curve to a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const a = new freesewing.Point(0,0) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b).curve(a, b, 'c') + } + catch (err) { + expect(''+err).to.contain("check is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a curve with a Cp1 that is a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const a = new freesewing.Point(0,0) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b).curve(a, 'x', b) + } + catch (err) { + expect(''+err).to.contain("check is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a curve with a Cp1 that is a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b).curve('a', b, b) + } + catch (err) { + expect(''+err).to.contain("copy is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a curve with a Cp2 that is a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b).curve(b, 'a', b) + } + catch (err) { + expect(''+err).to.contain("copy is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a _curve with a To that is a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b)._curve(b, 'a') + } + catch (err) { + expect(''+err).to.contain("copy is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a _curve with a Cp2 that is a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b)._curve('a', b) + } + catch (err) { + expect(''+err).to.contain("copy is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a curve_ with a To that is a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b).curve_(b, 'a') + } + catch (err) { + expect(''+err).to.contain("copy is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when drawing a curve_ with a Cp2 that is a non-point", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const p1 = new freesewing.Path().withRaise(raise) + const b = new freesewing.Point(10,10) + expect(invalid).to.equal(false); + try { + p1.move(b).curve_('a', b) + } + catch (err) { + expect(''+err).to.contain("copy is not a function") + } + expect(invalid).to.equal(true); +}); + +it("Should add a noop operation", () => { + const p1 = new freesewing.Path().noop() + expect(p1.ops.length).to.equal(1); + expect(p1.ops[0].type).to.equal('noop'); +}); + +it("Should handle an insop operation", () => { + const a = new freesewing.Point(0,0) + const b = new freesewing.Point(10,10) + const p1 = new freesewing.Path().move(a).line(b) + const p2 = new freesewing.Path().noop('test').insop('test', p1) + expect(p2.ops.length).to.equal(2); + expect(p1.ops[0].type).to.equal('move'); + expect(p1.ops[1].type).to.equal('line'); +}); + +it("Should raise a warning when an insop operation used an falsy ID", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const a = new freesewing.Point(0,0) + const b = new freesewing.Point(10,10) + const p1 = new freesewing.Path().move(a).line(b) + expect(invalid).to.equal(false); + const p2 = new freesewing.Path().withRaise(raise).noop('test').insop(false, p1) + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when an insop operation used an falsy ID", () => { + let invalid = false + const raise = { warning: () => invalid = true } + const a = new freesewing.Point(0,0) + const b = new freesewing.Point(10,10) + const p1 = new freesewing.Path().move(a).line(b) + expect(invalid).to.equal(false); + try { + new freesewing.Path().withRaise(raise).noop('test').insop('test') + } + catch (err) { + expect(''+err).to.contain("Cannot read property 'ops") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when setting an attribute without a name", () => { + let invalid = false + const raise = { warning: () => invalid = true } + expect(invalid).to.equal(false); + const p1 = new freesewing.Path().withRaise(raise).attr() + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when setting an attribute without a value", () => { + let invalid = false + const raise = { warning: () => invalid = true } + expect(invalid).to.equal(false); + const p1 = new freesewing.Path().withRaise(raise).attr('test') + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when calling offset without a distance", () => { + const pattern = new freesewing.Pattern(); + pattern.parts.a = new pattern.Part(); + const { Path, Point, points, paths } = pattern.parts.a.shorthand() + points.a = new Point(0,0) + points.b = new Point(10,10) + paths.a = new Path().move(points.a).line(points.b) + paths.b = paths.a.offset() + expect(pattern.events.error.length).to.equal(1) + expect(pattern.events.error[0]).to.equal("Called `Path.offset(distance)` but `distance` is not a number") +}); + +it("Should raise a warning when calling join without a path", () => { + const pattern = new freesewing.Pattern(); + pattern.parts.a = new pattern.Part(); + const { Path, Point, points, paths } = pattern.parts.a.shorthand() + points.a = new Point(0,0) + points.b = new Point(10,10) + try { + paths.a = new Path().move(points.a).line(points.b).join() + } + catch (err) { + expect(''+err).to.contain("Cannot read property 'ops") + } + expect(pattern.events.error.length).to.equal(1) + expect(pattern.events.error[0]).to.equal("Called `Path.join(that)` but `that` is not a `Path` object") +}); + +it("Should raise a warning when calling start on a path without drawing operations", () => { + let invalid = false + const raise = { error: () => invalid = true } + expect(invalid).to.equal(false); + try { + new freesewing.Path().withRaise(raise).start() + } + catch (err) { + expect(''+err).to.contain("TypeError: Cannot read property") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when calling end on a path without drawing operations", () => { + let invalid = false + const raise = { error: () => invalid = true } + expect(invalid).to.equal(false); + try { + new freesewing.Path().withRaise(raise).end() + } + catch (err) { + expect(''+err).to.contain("TypeError: Cannot read property") + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when calling shiftAlong but distance is not a number", () => { + let invalid = false + const raise = { error: () => invalid = true } + expect(invalid).to.equal(false); + new freesewing.Path() + .withRaise(raise) + .move(new freesewing.Point(0,0)) + .line(new freesewing.Point(10,10)) + .shiftAlong() + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when calling shiftFractionalong but fraction is not a number", () => { + let invalid = false + const raise = { error: () => invalid = true } + expect(invalid).to.equal(false); + new freesewing.Path() + .withRaise(raise) + .move(new freesewing.Point(0,0)) + .line(new freesewing.Point(10,10)) + .shiftFractionAlong() + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when splitting a path on a non-point", () => { + let invalid = false + const raise = { error: () => invalid = true } + const from = new freesewing.Point(0,0).withRaise(raise) + const cp1 = new freesewing.Point(10,0).withRaise(raise) + const cp2 = new freesewing.Point(90,0).withRaise(raise) + const to = new freesewing.Point(100,0).withRaise(raise) + const path = new freesewing.Path() + .withRaise(raise) + .move(from) + .curve(cp1, cp2, to) + .line(from) + try { + path.split() + } + catch (err) { + console.log(err) + } + expect(invalid).to.equal(true); +}); + +it("Should raise a warning when splitting a path on a non-point", () => { + let invalid = false + const raise = { error: () => invalid = true } + const from = new freesewing.Point(0,0).withRaise(raise) + const cp1 = new freesewing.Point(10,0).withRaise(raise) + const cp2 = new freesewing.Point(90,0).withRaise(raise) + const to = new freesewing.Point(100,0).withRaise(raise) + const path = new freesewing.Path() + .withRaise(raise) + .move(from) + .curve(cp1, cp2, to) + .line(from) + try { + path.split() + } + catch (err) { + console.log(err) + } + expect(invalid).to.equal(true); +}); +