wip(core): Work on porting unit tests to v3
This commit is contained in:
parent
3671f44e90
commit
ba7c663941
13 changed files with 4392 additions and 4470 deletions
|
@ -6,37 +6,39 @@ const expect = chai.expect
|
|||
const newAttr = () => new Point(0, 0).attributes;
|
||||
|
||||
const a = newAttr();
|
||||
it("Should set an attribute", () => {
|
||||
|
||||
describe('Attributes', () => {
|
||||
it("Should set an attribute", () => {
|
||||
a.set('hold', 'me')
|
||||
expect(a.get("hold")).to.equal('me');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should remove an attribute", () => {
|
||||
it("Should remove an attribute", () => {
|
||||
a.remove('hold')
|
||||
expect(a.get("hold")).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should only set an unset attribute", () => {
|
||||
it("Should only set an unset attribute", () => {
|
||||
a.setIfUnset('hold', 'me')
|
||||
expect(a.get("hold")).to.equal('me');
|
||||
a.setIfUnset('hold', 'thatDudeOverThere')
|
||||
expect(a.get("hold")).to.equal('me');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return false when getting an unset attribute", () => {
|
||||
it("Should return false when getting an unset attribute", () => {
|
||||
let a = newAttr();
|
||||
expect(a.get("test")).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render attributes correctly", () => {
|
||||
it("Should render attributes correctly", () => {
|
||||
let a = newAttr()
|
||||
.set("class", "test")
|
||||
.add("class", "render")
|
||||
.set("transform", "scale(1)");
|
||||
expect(a.render()).to.equal(' class="test render" transform="scale(1)"');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render attributes with given prefix only", () => {
|
||||
it("Should render attributes with given prefix only", () => {
|
||||
let a = newAttr()
|
||||
.set("class", "test")
|
||||
.add("class", "render")
|
||||
|
@ -45,9 +47,9 @@ it("Should render attributes with given prefix only", () => {
|
|||
.add("data-mode", "test")
|
||||
.set("transform", "scale(1)");
|
||||
expect(a.renderIfPrefixIs("data-")).to.equal(' text="foo bar" mode="test"');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return attributes as array", () => {
|
||||
it("Should return attributes as array", () => {
|
||||
let a = newAttr()
|
||||
.set("class", "test")
|
||||
.add("class", "render");
|
||||
|
@ -55,16 +57,16 @@ it("Should return attributes as array", () => {
|
|||
JSON.stringify(["test", "render"])
|
||||
);
|
||||
expect(a.getAsArray("nope")).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render attributes as CSS", () => {
|
||||
it("Should render attributes as CSS", () => {
|
||||
let a = newAttr()
|
||||
.set("line-height", 1.2)
|
||||
.add("border", "1px solid red");
|
||||
expect(a.renderAsCss()).to.equal(" line-height:1.2; border:1px solid red;");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return attributes as props and filter a prefix", () => {
|
||||
it("Should return attributes as props and filter a prefix", () => {
|
||||
const a = newAttr()
|
||||
.set("line-height", 1.2)
|
||||
.add("border", "1px solid red")
|
||||
|
@ -73,11 +75,12 @@ it("Should return attributes as props and filter a prefix", () => {
|
|||
const props = a.asPropsIfPrefixIs('data-')
|
||||
expect(props.text).to.equal("This is a test");
|
||||
expect(props['text-class']).to.equal("center");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return attributes as props and handle special class case", () => {
|
||||
it("Should return attributes as props and handle special class case", () => {
|
||||
const a = newAttr().set("class", "fabric");
|
||||
const props = a.asPropsIfPrefixIs('')
|
||||
expect(props.className).to.equal("fabric");
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ import freesewing from "./dist/index.mjs"
|
|||
|
||||
const expect = chai.expect
|
||||
|
||||
it("Design constructor should return pattern constructor", () => {
|
||||
let design = new freesewing.Design({
|
||||
describe('Design', () => {
|
||||
it("Design constructor should return pattern constructor", () => {
|
||||
const design = new freesewing.Design({
|
||||
foo: "bar",
|
||||
options: {
|
||||
constant: 2,
|
||||
|
@ -12,7 +13,7 @@ it("Design constructor should return pattern constructor", () => {
|
|||
}
|
||||
});
|
||||
|
||||
let pattern = new design();
|
||||
const pattern = new design();
|
||||
expect(pattern.width).to.equal(0);
|
||||
expect(pattern.height).to.equal(0);
|
||||
expect(pattern.settings.complete).to.equal(true);
|
||||
|
@ -21,25 +22,9 @@ it("Design constructor should return pattern constructor", () => {
|
|||
expect(pattern.config.foo).to.equal("bar");
|
||||
expect(pattern.settings.options.constant).to.equal(2);
|
||||
expect(pattern.settings.options.percentage).to.equal(0.3);
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor should load single plugin (legacy)", () => {
|
||||
let plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
hooks: {
|
||||
preRender: function(svg, attributes) {
|
||||
svg.attributes.add("freesewing:plugin-example", version);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let design = new freesewing.Design({}, plugin);
|
||||
let pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||
});
|
||||
|
||||
it("Design constructor should load single plugin (2022)", () => {
|
||||
it("Design constructor should load single plugin", () => {
|
||||
let plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
|
@ -53,34 +38,9 @@ it("Design constructor should load single plugin (2022)", () => {
|
|||
let design = new freesewing.Design({plugins: plugin});
|
||||
let pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor should load array of plugins (legacy)", () => {
|
||||
let plugin1 = {
|
||||
name: "example1",
|
||||
version: 1,
|
||||
hooks: {
|
||||
preRender: function(svg, attributes) {
|
||||
svg.attributes.add("freesewing:plugin-example1", version);
|
||||
}
|
||||
}
|
||||
};
|
||||
let plugin2 = {
|
||||
name: "example2",
|
||||
version: 2,
|
||||
hooks: {
|
||||
preRender: function(svg, attributes) {
|
||||
svg.attributes.add("freesewing:plugin-example2", version);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let design = new freesewing.Design({}, [plugin1, plugin2]);
|
||||
let pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(2);
|
||||
});
|
||||
|
||||
it("Design constructor should load array of plugins (2022)", () => {
|
||||
it("Design constructor should load array of plugins", () => {
|
||||
let plugin1 = {
|
||||
name: "example1",
|
||||
version: 1,
|
||||
|
@ -103,25 +63,9 @@ it("Design constructor should load array of plugins (2022)", () => {
|
|||
let design = new freesewing.Design( { plugins: [plugin1, plugin2] });
|
||||
let pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor should load conditional plugin (legacy)", () => {
|
||||
const plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
hooks: {
|
||||
preRender: function(svg, attributes) {
|
||||
svg.attributes.add("freesewing:plugin-example", version);
|
||||
}
|
||||
}
|
||||
};
|
||||
const condition = () => true
|
||||
const design = new freesewing.Design({}, [], { plugin, condition });
|
||||
const pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||
});
|
||||
|
||||
it("Design constructor should load conditional plugin (2022)", () => {
|
||||
it("Design constructor should load conditional plugin", () => {
|
||||
const plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
|
@ -135,25 +79,9 @@ it("Design constructor should load conditional plugin (2022)", () => {
|
|||
const design = new freesewing.Design({ conditionalPlugins: { plugin, condition } });
|
||||
const pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor should not load conditional plugin (legacy)", () => {
|
||||
const plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
hooks: {
|
||||
preRender: function(svg, attributes) {
|
||||
svg.attributes.add("freesewing:plugin-example", version);
|
||||
}
|
||||
}
|
||||
};
|
||||
const condition = () => false
|
||||
const design = new freesewing.Design({}, [], { plugin, condition });
|
||||
const pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(0);
|
||||
});
|
||||
|
||||
it("Design constructor should not load conditional plugin (2022)", () => {
|
||||
it("Design constructor should not load conditional plugin", () => {
|
||||
const plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
|
@ -167,29 +95,9 @@ it("Design constructor should not load conditional plugin (2022)", () => {
|
|||
const design = new freesewing.Design({ conditionalPlugins: { plugin, condition } });
|
||||
const pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor should load multiple conditional plugins (legacy)", () => {
|
||||
const plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
hooks: {
|
||||
preRender: function(svg, attributes) {
|
||||
svg.attributes.add("freesewing:plugin-example", version);
|
||||
}
|
||||
}
|
||||
};
|
||||
const condition1 = () => true
|
||||
const condition2 = () => false
|
||||
const design = new freesewing.Design({}, [], [
|
||||
{ plugin, condition: condition1 },
|
||||
{ plugin, condition: condition2 },
|
||||
]);
|
||||
const pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||
});
|
||||
|
||||
it("Design constructor should load multiple conditional plugins (2022)", () => {
|
||||
it("Design constructor should load multiple conditional plugins", () => {
|
||||
const plugin = {
|
||||
name: "example",
|
||||
version: 1,
|
||||
|
@ -207,22 +115,10 @@ it("Design constructor should load multiple conditional plugins (2022)", () => {
|
|||
]});
|
||||
const pattern = new design();
|
||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||
});
|
||||
|
||||
it("Design constructor should construct basic part order", () => {
|
||||
let design = new freesewing.Design({
|
||||
dependencies: { step4: "step3" },
|
||||
inject: { step4: "step3" },
|
||||
parts: ["step1", "step2"]
|
||||
});
|
||||
let pattern = new design().init();
|
||||
expect(pattern.config.draftOrder[0]).to.equal("step3");
|
||||
expect(pattern.config.draftOrder[1]).to.equal("step4");
|
||||
expect(pattern.config.draftOrder[2]).to.equal("step1");
|
||||
expect(pattern.config.draftOrder[3]).to.equal("step2");
|
||||
});
|
||||
|
||||
it("Design constructor should not require depencies for injected parts", () => {
|
||||
/*
|
||||
it("Design constructor should not require depencies for injected parts", () => {
|
||||
let design = new freesewing.Design({
|
||||
inject: { step4: "step3" },
|
||||
parts: ["step1", "step2"]
|
||||
|
@ -232,9 +128,9 @@ it("Design constructor should not require depencies for injected parts", () => {
|
|||
expect(pattern.config.draftOrder[1]).to.equal("step4");
|
||||
expect(pattern.config.draftOrder[2]).to.equal("step1");
|
||||
expect(pattern.config.draftOrder[3]).to.equal("step2");
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor should handle parts and dependencies overlap", () => {
|
||||
it("Design constructor should handle parts and dependencies overlap", () => {
|
||||
let design = new freesewing.Design({
|
||||
inject: { step4: "step3" },
|
||||
parts: ["step1", "step2", "step3"]
|
||||
|
@ -244,9 +140,9 @@ it("Design constructor should handle parts and dependencies overlap", () => {
|
|||
expect(pattern.config.draftOrder[1]).to.equal("step4");
|
||||
expect(pattern.config.draftOrder[2]).to.equal("step1");
|
||||
expect(pattern.config.draftOrder[3]).to.equal("step2");
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor discover all parts", () => {
|
||||
it("Design constructor discover all parts", () => {
|
||||
let design = new freesewing.Design({
|
||||
inject: {
|
||||
step4: "step3",
|
||||
|
@ -273,9 +169,9 @@ it("Design constructor discover all parts", () => {
|
|||
expect(pattern.config.draftOrder[8]).to.equal("step11");
|
||||
expect(pattern.config.draftOrder[9]).to.equal("step1");
|
||||
expect(pattern.config.draftOrder[10]).to.equal("step2");
|
||||
});
|
||||
});
|
||||
|
||||
it("Design constructor should handle Simon", () => {
|
||||
it("Design constructor should handle Simon", () => {
|
||||
let design = new freesewing.Design({
|
||||
dependencies: {
|
||||
sleeve: ["front", "back"]
|
||||
|
@ -302,9 +198,11 @@ it("Design constructor should handle Simon", () => {
|
|||
hide: ["base", "frontBase", "front", "backBase", "sleeveBase"]
|
||||
});
|
||||
let pattern = new design().init();
|
||||
});
|
||||
});
|
||||
|
||||
it("Pattern constructor should add default hide() method to options", () => {
|
||||
*/
|
||||
|
||||
it("Pattern constructor should add default hide() method to options", () => {
|
||||
const design = new freesewing.Design({
|
||||
foo: "bar",
|
||||
options: {
|
||||
|
@ -327,20 +225,7 @@ it("Pattern constructor should add default hide() method to options", () => {
|
|||
expect(pattern.config.options.percentage.hide()).to.be.false
|
||||
expect(pattern.config.options.degree.hide()).to.be.false
|
||||
expect(pattern.config.options.withHide.hide(pattern.settings)).to.be.true
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it("Should warn when passing plugins both as parameter and in the config", () => {
|
||||
const design = new freesewing.Design({plugins: [{}]}, {});
|
||||
expect(design.config.warnings.length).to.equal(2)
|
||||
expect(design.config.warnings[0]).to.equal('Passing plugins to the Design constructor both as a second parameter and in the config is unsupported')
|
||||
expect(design.config.warnings[1]).to.equal('Ignoring plugins passed as parameter. Only config.plugins will be used.')
|
||||
})
|
||||
|
||||
it("Should warn when passing conditionalPlugins both as parameter and in the config", () => {
|
||||
const design = new freesewing.Design({conditionalPlugins: [{}]}, false, {});
|
||||
expect(design.config.warnings.length).to.equal(2)
|
||||
expect(design.config.warnings[0]).to.equal('Passing conditionalPlugins to the Design constructor both as a third parameter and in the config is unsupported.')
|
||||
expect(design.config.warnings[1]).to.equal('Ignoring conditionalPlugins passes as parameter. Only config.conditionalPlugins will be used.')
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -3,10 +3,11 @@ import { Pattern } from "./dist/index.mjs"
|
|||
|
||||
const expect = chai.expect
|
||||
|
||||
it("Should contain all hooks", () => {
|
||||
let pattern = new Pattern();
|
||||
let h = pattern.hooks;
|
||||
let test = {
|
||||
describe('Hooks', () => {
|
||||
it("Should contain all hooks", () => {
|
||||
const pattern = new Pattern();
|
||||
const h = pattern.hooks;
|
||||
const test = {
|
||||
preDraft: [],
|
||||
postDraft: [],
|
||||
postLayout: [],
|
||||
|
@ -17,4 +18,5 @@ it("Should contain all hooks", () => {
|
|||
insertText: [],
|
||||
};
|
||||
expect(h).to.eql(test);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ import freesewing from "./dist/index.mjs"
|
|||
const expect = chai.expect
|
||||
|
||||
describe('Part', () => {
|
||||
it("Svg constructor should initialize object", () => {
|
||||
it("Svg constructor should initialize object", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
expect(part.paths).to.eql({});
|
||||
|
@ -15,22 +15,22 @@ it("Svg constructor should initialize object", () => {
|
|||
expect(part.width).to.equal(false);
|
||||
expect(part.height).to.equal(false);
|
||||
expect(part.render).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return a function from macroClosure", () => {
|
||||
it("Should return a function from macroClosure", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
expect(typeof part.macroClosure()).to.equal("function");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not run an unknown macro", () => {
|
||||
it("Should not run an unknown macro", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
let macro = part.macroClosure();
|
||||
expect(macro("unknown")).to.equal(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should register and run a macro", () => {
|
||||
it("Should register and run a macro", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let plugin = {
|
||||
name: "test",
|
||||
|
@ -48,30 +48,30 @@ it("Should register and run a macro", () => {
|
|||
macro("test", { x: 123, y: 456 });
|
||||
expect(part.points.macro.x).to.equal(123);
|
||||
expect(part.points.macro.y).to.equal(456);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return a free ID", () => {
|
||||
it("Should return a free ID", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
let free = part.getId();
|
||||
expect(part.getId()).to.equal("" + (parseInt(free) + 1));
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return a function from unitsClosure", () => {
|
||||
it("Should return a function from unitsClosure", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
expect(typeof part.unitsClosure()).to.equal("function");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should convert units", () => {
|
||||
it("Should convert units", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
let units = part.unitsClosure();
|
||||
expect(units(123.456)).to.equal("12.35cm");
|
||||
expect(part.units(123.456)).to.equal("12.35cm");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set part attributes", () => {
|
||||
it("Should set part attributes", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.attr("foo", "bar");
|
||||
|
@ -80,9 +80,9 @@ it("Should set part attributes", () => {
|
|||
expect(part.attributes.get("foo")).to.equal("bar baz");
|
||||
part.attr("foo", "schmoo", true);
|
||||
expect(part.attributes.get("foo")).to.equal("schmoo");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should inject a part", () => {
|
||||
it("Should inject a part", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.points.a = new part.Point(12, 23);
|
||||
|
@ -106,9 +106,9 @@ it("Should inject a part", () => {
|
|||
}
|
||||
expect(test.snippets.d.anchor.x).to.equal(part.points.a.x)
|
||||
expect(test.snippets.d.anchor.y).to.equal(part.points.a.y)
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return shorthand", () => {
|
||||
it("Should return shorthand", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
pattern.settings.paperless = true;
|
||||
|
@ -116,9 +116,9 @@ it("Should return shorthand", () => {
|
|||
let short = part.shorthand();
|
||||
expect(short.complete).to.equal(true);
|
||||
expect(short.paperless).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when setting a non-Point value in points", () => {
|
||||
it("Should raise a warning when setting a non-Point value in points", () => {
|
||||
const pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
const part = new pattern.Part();
|
||||
|
@ -128,9 +128,9 @@ it("Should raise a warning when setting a non-Point value in points", () => {
|
|||
expect(pattern.events.warning[0]).to.equal('`points.a` was set with a value that is not a `Point` object')
|
||||
expect(pattern.events.warning[1]).to.equal('`points.a` was set with a `x` parameter that is not a `number`')
|
||||
expect(pattern.events.warning[2]).to.equal('`points.a` was set with a `y` parameter that is not a `number`')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when setting a non-Snippet value in snippets", () => {
|
||||
it("Should raise a warning when setting a non-Snippet value in snippets", () => {
|
||||
const pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
const part = new pattern.Part();
|
||||
|
@ -140,9 +140,9 @@ it("Should raise a warning when setting a non-Snippet value in snippets", () =>
|
|||
expect(pattern.events.warning[0]).to.equal('`snippets.a` was set with a value that is not a `Snippet` object')
|
||||
expect(pattern.events.warning[1]).to.equal('`snippets.a` was set with a `def` parameter that is not a `string`')
|
||||
expect(pattern.events.warning[2]).to.equal('`snippets.a` was set with an `anchor` parameter that is not a `Point`')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should calculate the part boundary with default margin", () => {
|
||||
it("Should calculate the part boundary with default margin", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
let part = new pattern.Part();
|
||||
|
@ -160,9 +160,9 @@ it("Should calculate the part boundary with default margin", () => {
|
|||
boundary = part.boundary();
|
||||
expect(boundary.width).to.equal(108);
|
||||
expect(boundary.height).to.equal(384);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should calculate the part boundary with custom margin", () => {
|
||||
it("Should calculate the part boundary with custom margin", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
pattern.settings.margin = 5;
|
||||
|
@ -181,9 +181,9 @@ it("Should calculate the part boundary with custom margin", () => {
|
|||
boundary = part.boundary();
|
||||
expect(boundary.width).to.equal(114);
|
||||
expect(boundary.height).to.equal(390);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should calculate the part boundary for paperless", () => {
|
||||
it("Should calculate the part boundary for paperless", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
pattern.settings.margin = 5;
|
||||
|
@ -203,9 +203,9 @@ it("Should calculate the part boundary for paperless", () => {
|
|||
boundary = part.boundary();
|
||||
expect(boundary.width).to.equal(124);
|
||||
expect(boundary.height).to.equal(400);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should stack a part", () => {
|
||||
it("Should stack a part", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
let part = new pattern.Part();
|
||||
|
@ -217,9 +217,9 @@ it("Should stack a part", () => {
|
|||
.line(part.points.to);
|
||||
part.stack();
|
||||
expect(part.attributes.get("transform")).to.equal("translate(-17, -74)");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should only stack a part if needed", () => {
|
||||
it("Should only stack a part if needed", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
let part = new pattern.Part();
|
||||
|
@ -233,28 +233,29 @@ it("Should only stack a part if needed", () => {
|
|||
expect(part.attributes.get("transform")).to.equal(false);
|
||||
part.stack();
|
||||
expect(part.attributes.get("transform")).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should run hooks", () => {
|
||||
it("Should run hooks", () => {
|
||||
let count = 0
|
||||
const pattern = new freesewing.Pattern()
|
||||
const part = new pattern.Part();
|
||||
part.hooks.preDraft = [{ method: function(p) { count++ }} ]
|
||||
part.runHooks('preDraft')
|
||||
expect(count).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should get the units closure to raise a debug when passing a non-number", () => {
|
||||
it("Should get the units closure to raise a debug when passing a non-number", () => {
|
||||
const pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
pattern.settings.debug = true
|
||||
const part = new pattern.Part();
|
||||
const short = part.shorthand();
|
||||
short.units('a')
|
||||
expect(pattern.events.debug.length).to.equal(1)
|
||||
expect(pattern.events.debug[0]).to.equal('Calling `units(value)` but `value` is not a number (`string`)')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate the part transforms", () => {
|
||||
it("Should generate the part transforms", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
let part = new pattern.Part();
|
||||
|
@ -273,10 +274,10 @@ it("Should generate the part transforms", () => {
|
|||
})
|
||||
expect(part.attributes.list.transform.length).to.equal(1)
|
||||
expect(part.attributes.list.transform[0]).to.equal('translate(10 20)')
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("Should add the part cut", () => {
|
||||
it("Should add the part cut", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(4, 'fabric', true)
|
||||
|
@ -285,101 +286,101 @@ it("Should add the part cut", () => {
|
|||
part.addCut()
|
||||
expect(part.cut.materials.fabric.cut).to.equal(2)
|
||||
expect(part.cut.materials.fabric.identical).to.equal(false)
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate an error if cut is not a number", () => {
|
||||
it("Should generate an error if cut is not a number", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut('a', 'fabric', true)
|
||||
expect(pattern.events.error.length).to.equal(1)
|
||||
expect(pattern.events.error[0]).to.equal('Tried to set cut to a value that is not a positive integer')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate an warning if material is not a string", () => {
|
||||
it("Should generate an warning if material is not a string", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(3, 4)
|
||||
expect(pattern.events.warning.length).to.equal(1)
|
||||
expect(pattern.events.warning[0]).to.equal('Tried to set material to a value that is not a string')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate an error when removing a material that is not set (through addCut)", () => {
|
||||
it("Should generate an error when removing a material that is not set (through addCut)", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(4, 'fabric', true)
|
||||
part.addCut(false, 'lining')
|
||||
expect(pattern.events.warning.length).to.equal(1)
|
||||
expect(pattern.events.warning[0]).to.equal('Tried to remove a material that is not set')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should remove the part cut through addCut", () => {
|
||||
it("Should remove the part cut through addCut", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(4, 'fabric', true)
|
||||
part.addCut(false, 'fabric')
|
||||
expect(typeof part.cut.materials.fabric).to.equal('undefined')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should remove the part cut through removeCut", () => {
|
||||
it("Should remove the part cut through removeCut", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(4, 'fabric', true)
|
||||
part.removeCut('fabric')
|
||||
expect(typeof part.cut.materials.fabric).to.equal('undefined')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate an error when removing a material that is not set (through removeCut)", () => {
|
||||
it("Should generate an error when removing a material that is not set (through removeCut)", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(4, 'fabric', true)
|
||||
part.removeCut('lining')
|
||||
expect(pattern.events.warning.length).to.equal(1)
|
||||
expect(pattern.events.warning[0]).to.equal('Tried to remove a material that is not set')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate an error when removing a material that is not a string (through removeCut)", () => {
|
||||
it("Should generate an error when removing a material that is not a string (through removeCut)", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(4, 'fabric', true)
|
||||
part.removeCut(23)
|
||||
expect(pattern.events.warning.length).to.equal(1)
|
||||
expect(pattern.events.warning[0]).to.equal('Tried to remove a material that is not set')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate a warning when calling removeCut without parameters", () => {
|
||||
it("Should generate a warning when calling removeCut without parameters", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.addCut(4, 'fabric', true)
|
||||
part.removeCut()
|
||||
expect(pattern.events.warning.length).to.equal(1)
|
||||
expect(pattern.events.warning[0]).to.equal('Tried to remove a material that is not set')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set the part grainline", () => {
|
||||
it("Should set the part grainline", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
expect(part.cut.grain).to.equal(90)
|
||||
part.setGrain(123)
|
||||
expect(part.cut.grain).to.equal(123)
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when calling part.setGrain() without any parameters", () => {
|
||||
it("Should raise a warning when calling part.setGrain() without any parameters", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.setGrain()
|
||||
expect(part.cut.grain).to.equal(false)
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise an error when calling part.setGrain() with a value that is not a number", () => {
|
||||
it("Should raise an error when calling part.setGrain() with a value that is not a number", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
part.setGrain('a')
|
||||
expect(part.cut.grain).to.equal(90)
|
||||
expect(pattern.events.error.length).to.equal(1)
|
||||
expect(pattern.events.error[0]).to.equal('Called part.setGrain() with a value that is not a number')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set and then remove the cutOnFold", () => {
|
||||
it("Should set and then remove the cutOnFold", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
const { Point } = part.shorthand()
|
||||
|
@ -390,18 +391,18 @@ it("Should set and then remove the cutOnFold", () => {
|
|||
expect(part.cut.cutOnFold[1].y).to.equal(200)
|
||||
part.setCutOnFold(false)
|
||||
expect(typeof part.cut.cutOnFold).to.equal('undefined')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise an error when setting the cutOnFold with a non-Point value", () => {
|
||||
it("Should raise an error when setting the cutOnFold with a non-Point value", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
const { Point } = part.shorthand()
|
||||
part.setCutOnFold(new Point(2,3), 12)
|
||||
expect(pattern.events.error.length).to.equal(1)
|
||||
expect(pattern.events.error[0]).to.equal('Called part.setCutOnFold() but at least one parameter is not a Point instance')
|
||||
});
|
||||
});
|
||||
|
||||
describe('isEmpty', () => {
|
||||
describe('isEmpty', () => {
|
||||
it("Should return true if the part has no paths or snippets", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
|
@ -459,6 +460,6 @@ describe('isEmpty', () => {
|
|||
points.test.attributes.set('data-circle', 10)
|
||||
expect(part.isEmpty()).to.be.false
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
@ -4,7 +4,8 @@ import freesewing from "./dist/index.mjs"
|
|||
const expect = chai.expect
|
||||
const round = freesewing.utils.round
|
||||
|
||||
it("Should offset a line", () => {
|
||||
describe('Path', () => {
|
||||
it("Should offset a line", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -14,9 +15,9 @@ it("Should offset a line", () => {
|
|||
pattern.render();
|
||||
expect(a.paths.offset.bottomRight.x).to.equal(-10);
|
||||
expect(a.paths.offset.bottomRight.y).to.equal(40);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should offset a curve", () => {
|
||||
it("Should offset a curve", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -28,9 +29,9 @@ it("Should offset a curve", () => {
|
|||
pattern.render();
|
||||
expect(round(a.paths.offset.bottomRight.x)).to.equal(72.18);
|
||||
expect(round(a.paths.offset.bottomRight.y)).to.equal(38.26);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should offset a curve where cp1 = start", () => {
|
||||
it("Should offset a curve where cp1 = start", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -42,9 +43,9 @@ it("Should offset a curve where cp1 = start", () => {
|
|||
pattern.render();
|
||||
expect(round(a.paths.offset.bottomRight.x)).to.equal(72.63);
|
||||
expect(round(a.paths.offset.bottomRight.y)).to.equal(26.48);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should offset a curve where cp2 = end", () => {
|
||||
it("Should offset a curve where cp2 = end", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -57,27 +58,27 @@ it("Should offset a curve where cp2 = end", () => {
|
|||
pattern.render();
|
||||
expect(round(a.paths.offset.bottomRight.x)).to.equal(119.26);
|
||||
expect(round(a.paths.offset.bottomRight.y)).to.equal(43.27);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should throw error when offsetting line that is no line", () => {
|
||||
it("Should throw error when offsetting line that is no line", () => {
|
||||
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, 40)).line(new a.Point(0, 40));
|
||||
expect(() => a.paths.line.offset(10)).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return the length of a line", () => {
|
||||
it("Should return the length of a line", () => {
|
||||
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(0, 40));
|
||||
expect(a.paths.line.length()).to.equal(40);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return the length of a curve", () => {
|
||||
it("Should return the length of a curve", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -87,9 +88,9 @@ it("Should return the length of a curve", () => {
|
|||
.curve(new a.Point(0, 40), new a.Point(123, 34), new a.Point(23, 4))
|
||||
.close();
|
||||
expect(round(a.paths.curve.length())).to.equal(145.11);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return the path start point", () => {
|
||||
it("Should return the path start point", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -100,9 +101,9 @@ it("Should return the path start point", () => {
|
|||
.close();
|
||||
expect(a.paths.curve.start().x).to.equal(123);
|
||||
expect(a.paths.curve.start().y).to.equal(456);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return the path end point", () => {
|
||||
it("Should return the path end point", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -115,9 +116,9 @@ it("Should return the path end point", () => {
|
|||
a.paths.curve.close();
|
||||
expect(a.paths.curve.end().x).to.equal(123);
|
||||
expect(a.paths.curve.end().y).to.equal(456);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should calculate that path boundary", () => {
|
||||
it("Should calculate that path boundary", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -131,9 +132,9 @@ it("Should calculate that path boundary", () => {
|
|||
a.paths.curve.boundary();
|
||||
expect(a.paths.curve.bottomRight.x).to.equal(230);
|
||||
expect(a.paths.curve.bottomRight.y).to.equal(456);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should clone a path", () => {
|
||||
it("Should clone a path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -148,9 +149,9 @@ it("Should clone a path", () => {
|
|||
b = b.clone();
|
||||
expect(b.bottomRight.x).to.equal(230);
|
||||
expect(b.bottomRight.y).to.equal(456);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should join paths", () => {
|
||||
it("Should join paths", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -161,9 +162,9 @@ it("Should join paths", () => {
|
|||
.curve(new a.Point(0, 40), new a.Point(123, 34), new a.Point(230, 4));
|
||||
a.paths.joint = a.paths.curve.join(a.paths.line);
|
||||
expect(a.paths.joint.ops.length).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should throw error when joining a closed paths", () => {
|
||||
it("Should throw error when joining a closed paths", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -174,27 +175,27 @@ it("Should throw error when joining a closed paths", () => {
|
|||
.curve(new a.Point(0, 40), new a.Point(123, 34), new a.Point(230, 4))
|
||||
.close();
|
||||
expect(() => a.paths.curve.join(a.paths.line)).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift along a line", () => {
|
||||
it("Should shift along a line", () => {
|
||||
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(0, 40));
|
||||
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", () => {
|
||||
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", () => {
|
||||
it("Should shift along lines", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -205,9 +206,9 @@ it("Should shift along lines", () => {
|
|||
.line(new a.Point(100, 40));
|
||||
expect(a.paths.line.shiftAlong(50).x).to.equal(10);
|
||||
expect(a.paths.line.shiftAlong(50).y).to.equal(40);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift along curve + line", () => {
|
||||
it("Should shift along curve + line", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -219,9 +220,9 @@ it("Should shift along curve + line", () => {
|
|||
.line(new a.Point(200, 400));
|
||||
expect(round(a.paths.test.shiftAlong(500).x)).to.equal(200);
|
||||
expect(round(a.paths.test.shiftAlong(500).y)).to.equal(253.74);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should throw error when shifting along path further than it's long", () => {
|
||||
it("Should throw error when shifting along path further than it's long", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -230,9 +231,9 @@ it("Should throw error when shifting along path further than it's long", () => {
|
|||
.line(new a.Point(0, 40))
|
||||
.line(new a.Point(200, 400));
|
||||
expect(() => a.paths.test.shiftAlong(500)).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift along with sufficient precision", () => {
|
||||
it("Should shift along with sufficient precision", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -242,9 +243,9 @@ it("Should shift along with sufficient precision", () => {
|
|||
a.points.a = a.paths.test.shiftAlong(100)
|
||||
a.points.b = a.paths.test.reverse().shiftAlong(a.paths.test.length()-100)
|
||||
expect(a.points.a.dist(a.points.b)).to.below(0.05);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift fraction with sufficient precision", () => {
|
||||
it("Should shift fraction with sufficient precision", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -254,9 +255,9 @@ it("Should shift fraction with sufficient precision", () => {
|
|||
a.points.a = a.paths.test.shiftFractionAlong(0.5)
|
||||
a.points.b = a.paths.test.reverse().shiftFractionAlong(0.5)
|
||||
expect(a.points.a.dist(a.points.b)).to.below(0.05);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift a fraction along a line", () => {
|
||||
it("Should shift a fraction along a line", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -266,9 +267,9 @@ it("Should shift a fraction along a line", () => {
|
|||
.line(new a.Point(100, 40));
|
||||
expect(round(a.paths.line.shiftFractionAlong(0.5).x)).to.equal(30);
|
||||
expect(round(a.paths.line.shiftFractionAlong(0.5).y)).to.equal(40);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the bounding box of a line", () => {
|
||||
it("Should find the bounding box of a line", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let Path = pattern.parts.a.Path;
|
||||
|
@ -329,9 +330,9 @@ it("Should find the bounding box of a line", () => {
|
|||
expect(box.topLeft.y).to.equal(12);
|
||||
expect(box.bottomRight.x).to.equal(41);
|
||||
expect(box.bottomRight.y).to.equal(12);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the bounding box of a line", () => {
|
||||
it("Should find the bounding box of a line", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -344,9 +345,9 @@ it("Should find the bounding box of a line", () => {
|
|||
expect(box.topLeft.y).to.equal(4);
|
||||
expect(box.bottomRight.x).to.equal(230);
|
||||
expect(box.bottomRight.y).to.equal(456);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should reverse a path", () => {
|
||||
it("Should reverse a path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -364,9 +365,9 @@ it("Should reverse a path", () => {
|
|||
expect(tb.bottomRight.y).to.equal(rb.bottomRight.y);
|
||||
expect(rev.ops[1].type).to.equal("curve");
|
||||
expect(rev.ops[2].type).to.equal("line");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the edges of a path", () => {
|
||||
it("Should find the edges of a path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -399,9 +400,9 @@ it("Should find the edges of a path", () => {
|
|||
expect(round(a.paths.test.edge("right").y)).to.equal(29.64);
|
||||
expect(round(a.paths.test.edge("top").x)).to.equal(55.98);
|
||||
expect(round(a.paths.test.edge("top").y)).to.equal(0.97);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the edges of a path for corner cases", () => {
|
||||
it("Should find the edges of a path for corner cases", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -426,9 +427,9 @@ it("Should find the edges of a path for corner cases", () => {
|
|||
expect(round(a.paths.test.edge("bottom").y)).to.equal(60);
|
||||
expect(round(a.paths.test.edge("right").x)).to.equal(45);
|
||||
expect(round(a.paths.test.edge("right").y)).to.equal(60);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the edge of a path for this edge-case", () => {
|
||||
it("Should find the edge of a path for this edge-case", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -441,9 +442,9 @@ it("Should find the edge of a path for this edge-case", () => {
|
|||
.curve(a.points.B, a.points.C, a.points.D);
|
||||
expect(round(a.paths.test.edge("right").x)).to.equal(-45.22);
|
||||
expect(round(a.paths.test.edge("right").y)).to.equal(139.4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find where a path intersects with an X value", () => {
|
||||
it("Should find where a path intersects with an X value", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -470,9 +471,9 @@ it("Should find where a path intersects with an X value", () => {
|
|||
expect(round(intersections[2].y)).to.equal(120);
|
||||
expect(round(intersections[3].x)).to.equal(60);
|
||||
expect(round(intersections[3].y)).to.equal(112.22);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find where a path intersects with an Y value", () => {
|
||||
it("Should find where a path intersects with an Y value", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -495,18 +496,18 @@ it("Should find where a path intersects with an Y value", () => {
|
|||
expect(round(intersections[0].y)).to.equal(60);
|
||||
expect(round(intersections[1].x)).to.equal(89.38);
|
||||
expect(round(intersections[1].y)).to.equal(60);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should throw an error when not passing a value to path.intersectsX", () => {
|
||||
it("Should throw an error when not passing a value to path.intersectsX", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
a.paths.test = new a.Path();
|
||||
expect(() => a.paths.test.intersectsX()).to.throw();
|
||||
expect(() => a.paths.test.intersectsY()).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the intersections between two paths", () => {
|
||||
it("Should find the intersections between two paths", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -550,17 +551,17 @@ it("Should find the intersections between two paths", () => {
|
|||
expect(round(intersections[4].y)).to.equal(40.52);
|
||||
expect(round(intersections[5].x)).to.equal(86.52);
|
||||
expect(round(intersections[5].y)).to.equal(93.31);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should throw an error when running path.intersect on an identical path", () => {
|
||||
it("Should throw an error when running path.intersect on an identical path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
a.paths.test = new a.Path();
|
||||
expect(() => a.paths.test.intersects(a.paths.test)).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should divide a path", () => {
|
||||
it("Should divide a path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -611,9 +612,9 @@ it("Should divide a path", () => {
|
|||
expect(divided[3].ops[1].type).to.equal("line");
|
||||
expect(divided[3].ops[1].to.x).to.equal(45);
|
||||
expect(divided[3].ops[1].to.y).to.equal(60);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should split a path on a curve", () => {
|
||||
it("Should split a path on a curve", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -641,9 +642,9 @@ it("Should split a path on a curve", () => {
|
|||
expect(round(curve.cp2.y)).to.equal(-14.69);
|
||||
expect(round(curve.to.x)).to.equal(72.53);
|
||||
expect(round(curve.to.y)).to.equal(8.71);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should split a path on a line", () => {
|
||||
it("Should split a path on a line", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -667,9 +668,9 @@ it("Should split a path on a line", () => {
|
|||
expect(line.type).to.equal("line");
|
||||
expect(round(line.to.x)).to.equal(29.81);
|
||||
expect(round(line.to.y)).to.equal(46.98);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should trim a path when lines overlap", () => {
|
||||
it("Should trim a path when lines overlap", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -690,9 +691,9 @@ it("Should trim a path when lines overlap", () => {
|
|||
expect(test.ops.length).to.equal(5);
|
||||
expect(test.ops[2].to.x).to.equal(50);
|
||||
expect(test.ops[2].to.y).to.equal(50);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should trim a path when a line overlaps with a curve", () => {
|
||||
it("Should trim a path when a line overlaps with a curve", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -713,9 +714,9 @@ it("Should trim a path when a line overlaps with a curve", () => {
|
|||
expect(test.ops.length).to.equal(5);
|
||||
expect(round(test.ops[2].to.x)).to.equal(72.19);
|
||||
expect(round(test.ops[2].to.y)).to.equal(27.81);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should trim a path when a curves overlap", () => {
|
||||
it("Should trim a path when a curves overlap", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -736,9 +737,9 @@ it("Should trim a path when a curves overlap", () => {
|
|||
expect(test.ops.length).to.equal(5);
|
||||
expect(round(test.ops[2].to.x)).to.equal(50);
|
||||
expect(round(test.ops[2].to.y)).to.equal(11.01);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should translate a path", () => {
|
||||
it("Should translate a path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -757,9 +758,9 @@ it("Should translate a path", () => {
|
|||
expect(test.ops[0].to.y).to.equal(20);
|
||||
expect(test.ops[1].to.x).to.equal(110);
|
||||
expect(test.ops[1].to.y).to.equal(20);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should add a path attribute", () => {
|
||||
it("Should add a path attribute", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -770,9 +771,9 @@ it("Should add a path attribute", () => {
|
|||
.attr("class", "foo")
|
||||
.attr("class", "bar");
|
||||
expect(a.paths.line.attributes.get("class")).to.equal("foo bar");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should overwrite a path attribute", () => {
|
||||
it("Should overwrite a path attribute", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -786,9 +787,9 @@ it("Should overwrite a path attribute", () => {
|
|||
.attr("class", "bar")
|
||||
.attr("class", "overwritten", true);
|
||||
expect(a.paths.line.attributes.get("class")).to.equal("overwritten");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should move along a path even if it lands just on a joint", () => {
|
||||
it("Should move along a path even if it lands just on a joint", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.parts.a = new pattern.Part();
|
||||
let a = pattern.parts.a;
|
||||
|
@ -806,32 +807,32 @@ 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", () => {
|
||||
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", () => {
|
||||
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", () => {
|
||||
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", () => {
|
||||
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", () => {
|
||||
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)
|
||||
|
@ -843,9 +844,9 @@ it("Should raise a warning when moving to a non-point", () => {
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -857,9 +858,9 @@ it("Should raise a warning when drawing a line to a non-point", () => {
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -873,9 +874,9 @@ it("Should raise a warning when drawing a curve to a non-point", () => {
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -889,9 +890,9 @@ it("Should raise a warning when drawing a curve with a Cp1 that is a non-point",
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -904,9 +905,9 @@ it("Should raise a warning when drawing a curve with a Cp1 that is a non-point",
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -919,9 +920,9 @@ it("Should raise a warning when drawing a curve with a Cp2 that is a non-point",
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -934,9 +935,9 @@ it("Should raise a warning when drawing a _curve with a To that is a non-point",
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -949,9 +950,9 @@ it("Should raise a warning when drawing a _curve with a Cp2 that is a non-point"
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -964,9 +965,9 @@ it("Should raise a warning when drawing a curve_ with a To that is a non-point",
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -979,15 +980,15 @@ it("Should raise a warning when drawing a curve_ with a Cp2 that is a non-point"
|
|||
expect(''+err).to.contain("copy is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should add a noop operation", () => {
|
||||
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", () => {
|
||||
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)
|
||||
|
@ -995,9 +996,9 @@ it("Should handle an insop operation", () => {
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -1006,9 +1007,9 @@ it("Should raise a warning when an insop operation used an falsy ID", () => {
|
|||
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", () => {
|
||||
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)
|
||||
|
@ -1022,25 +1023,25 @@ it("Should raise a warning when an insop operation used an falsy ID", () => {
|
|||
expect(''+err).to.contain("Cannot read properties of undefined (reading 'ops')")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when setting an attribute without a name", () => {
|
||||
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", () => {
|
||||
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", () => {
|
||||
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()
|
||||
|
@ -1050,9 +1051,9 @@ it("Should raise a warning when calling offset without a distance", () => {
|
|||
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", () => {
|
||||
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()
|
||||
|
@ -1067,9 +1068,9 @@ it("Should raise a warning when calling join without a path", () => {
|
|||
}
|
||||
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", () => {
|
||||
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);
|
||||
|
@ -1080,9 +1081,9 @@ it("Should raise a warning when calling start on a path without drawing operatio
|
|||
expect(''+err).to.contain("Cannot read properties of undefined (reading 'to')")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when calling end on a path without drawing operations", () => {
|
||||
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);
|
||||
|
@ -1093,9 +1094,9 @@ it("Should raise a warning when calling end on a path without drawing operations
|
|||
expect(''+err).to.contain("Cannot read properties of undefined (reading 'type')")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when calling shiftAlong but distance is not a number", () => {
|
||||
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);
|
||||
|
@ -1105,9 +1106,9 @@ it("Should raise a warning when calling shiftAlong but distance is not a number"
|
|||
.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", () => {
|
||||
it("Should raise a warning when calling shiftFractionalong but fraction is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = {
|
||||
error: () => invalid = true,
|
||||
|
@ -1121,9 +1122,9 @@ it("Should raise a warning when calling shiftFractionalong but fraction is not a
|
|||
.line(new freesewing.Point(10,20).withRaise(raise))
|
||||
.shiftFractionAlong()
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when splitting a path on a non-point", () => {
|
||||
it("Should raise a warning when splitting a path on a non-point", () => {
|
||||
let invalid = false
|
||||
const raise = {
|
||||
error: () => invalid = true,
|
||||
|
@ -1146,9 +1147,9 @@ it("Should raise a warning when splitting a path on a non-point", () => {
|
|||
expect(''+err).to.contain("Cannot read properties of undefined (reading 'check')")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when splitting a path on a non-point", () => {
|
||||
it("Should raise a warning when splitting a path on a non-point", () => {
|
||||
let invalid = false
|
||||
const raise = {
|
||||
error: () => invalid = true,
|
||||
|
@ -1170,4 +1171,5 @@ it("Should raise a warning when splitting a path on a non-point", () => {
|
|||
expect(''+err).to.contain("Cannot read properties of undefined (reading 'check')")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,7 +3,8 @@ import freesewing from "./dist/index.mjs"
|
|||
|
||||
const expect = chai.expect
|
||||
|
||||
it("Pattern constructor should initialize object", () => {
|
||||
describe('Pattern', () => {
|
||||
it("Pattern constructor should initialize object", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
foo: "bar",
|
||||
options: {
|
||||
|
@ -19,55 +20,55 @@ it("Pattern constructor should initialize object", () => {
|
|||
expect(pattern.config.foo).to.equal("bar");
|
||||
expect(pattern.settings.options.constant).to.equal(2);
|
||||
expect(pattern.settings.options.percentage).to.equal(0.3);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("Should load percentage options", () => {
|
||||
it("Should load percentage options", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
options: {
|
||||
test: { pct: 30 }
|
||||
}
|
||||
});
|
||||
expect(pattern.settings.options.test).to.equal(0.3);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should load millimeter options", () => {
|
||||
it("Should load millimeter options", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
options: {
|
||||
test: { mm: 30 }
|
||||
}
|
||||
});
|
||||
expect(pattern.settings.options.test).to.equal(30);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should load degree options", () => {
|
||||
it("Should load degree options", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
options: {
|
||||
test: { deg: 15 }
|
||||
}
|
||||
});
|
||||
expect(pattern.settings.options.test).to.equal(15);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should load an array option", () => {
|
||||
it("Should load an array option", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
options: {
|
||||
test: { dflt: "foo" }
|
||||
}
|
||||
});
|
||||
expect(pattern.settings.options.test).to.equal("foo");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should load a count option", () => {
|
||||
it("Should load a count option", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
options: {
|
||||
test: { count: 3 }
|
||||
}
|
||||
});
|
||||
expect(pattern.settings.options.test).to.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should load a boolean option", () => {
|
||||
it("Should load a boolean option", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
options: {
|
||||
test1: { bool: false },
|
||||
|
@ -76,9 +77,9 @@ it("Should load a boolean option", () => {
|
|||
});
|
||||
expect(pattern.settings.options.test1).to.be.false;
|
||||
expect(pattern.settings.options.test2).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
it("Should throw an error for an unknown option", () => {
|
||||
it("Should throw an error for an unknown option", () => {
|
||||
expect(
|
||||
() =>
|
||||
new freesewing.Pattern({
|
||||
|
@ -87,9 +88,9 @@ it("Should throw an error for an unknown option", () => {
|
|||
}
|
||||
})
|
||||
).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should merge settings with default settings", () => {
|
||||
it("Should merge settings with default settings", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let settings = {
|
||||
foo: "bar",
|
||||
|
@ -103,43 +104,37 @@ it("Should merge settings with default settings", () => {
|
|||
expect(pattern.settings.margin).to.equal(2);
|
||||
expect(pattern.settings.idPrefix).to.equal("fs-");
|
||||
expect(pattern.settings.deep.free).to.equal("ze");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should draft according to settings", () => {
|
||||
it("Should draft according to settings", () => {
|
||||
let count = 0
|
||||
const back = {
|
||||
name: 'back',
|
||||
hide: true,
|
||||
draft: function(part) {
|
||||
count ++
|
||||
return part;
|
||||
}
|
||||
}
|
||||
const front = {
|
||||
name: 'front',
|
||||
from: back,
|
||||
draft: function(part) {
|
||||
count ++
|
||||
return part;
|
||||
}
|
||||
}
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
dependencies: { back: "front" },
|
||||
inject: { back: "front" },
|
||||
hide: ["back"]
|
||||
parts: [ back, front ],
|
||||
});
|
||||
Test.prototype.draftBack = function(part) {
|
||||
this.count++;
|
||||
return part;
|
||||
};
|
||||
Test.prototype.draftFront = function(part) {
|
||||
this.count++;
|
||||
return part;
|
||||
};
|
||||
|
||||
let pattern = new Test();
|
||||
pattern.count = 0;
|
||||
const pattern = new Test();
|
||||
pattern.draft();
|
||||
expect(pattern.count).to.equal(2);
|
||||
});
|
||||
|
||||
it("Should throw an error if per-part draft method is missing", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
dependencies: { back: "front" },
|
||||
inject: { back: "front" },
|
||||
hide: ["back"]
|
||||
expect(count).to.equal(2);
|
||||
});
|
||||
Test.prototype.draftBack = part => part;
|
||||
let pattern = new Test();
|
||||
expect(() => pattern.draft()).to.throw();
|
||||
});
|
||||
|
||||
it("Should sample an option", () => {
|
||||
it("Should sample an option", () => {
|
||||
let pattern = new freesewing.Pattern({
|
||||
options: {
|
||||
len: { pct: 30, min: 10 },
|
||||
|
@ -165,20 +160,18 @@ it("Should sample an option", () => {
|
|||
pattern.sample();
|
||||
expect(pattern.parts.a.paths.test_1.render).to.equal(true);
|
||||
expect(pattern.parts.b.paths.test_10.ops[1].to.y).to.equal(10);
|
||||
});
|
||||
|
||||
it("Should sample a list option", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: ['front'],
|
||||
});
|
||||
/*
|
||||
it("Should sample a list option", () => {
|
||||
const front = {
|
||||
name: 'front',
|
||||
options: {
|
||||
len: {
|
||||
dflt: 1,
|
||||
list: [1,2,3]
|
||||
}
|
||||
},
|
||||
})
|
||||
Test.prototype.draftFront = function(part) {
|
||||
draft: function(part) {
|
||||
const { Point, points, Path, paths, options } = part.shorthand()
|
||||
points.from = new Point(0, 0);
|
||||
points.to = new Point( 100 * options.len, 0)
|
||||
|
@ -187,7 +180,12 @@ it("Should sample a list option", () => {
|
|||
.line(points.to)
|
||||
|
||||
return part
|
||||
};
|
||||
}
|
||||
}
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: [front],
|
||||
})
|
||||
const pattern = new Test({
|
||||
sample: {
|
||||
type: 'option',
|
||||
|
@ -195,12 +193,13 @@ it("Should sample a list option", () => {
|
|||
}
|
||||
})
|
||||
pattern.sample();
|
||||
console.log(pattern.parts)
|
||||
expect(pattern.parts.front.paths.line_1.ops[1].to.x).to.equal(100);
|
||||
expect(pattern.parts.front.paths.line_2.ops[1].to.x).to.equal(200);
|
||||
expect(pattern.parts.front.paths.line_3.ops[1].to.x).to.equal(300);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should sample a measurement", () => {
|
||||
it("Should sample a measurement", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: ['front'],
|
||||
|
@ -235,9 +234,9 @@ it("Should sample a measurement", () => {
|
|||
pattern.sampleMeasurement('nope')
|
||||
expect(pattern.events.error.length).to.equal(1)
|
||||
expect(pattern.events.error[0]).to.equal("Cannot sample measurement `nope` because it's `undefined`")
|
||||
});
|
||||
});
|
||||
|
||||
it("Should sample models", () => {
|
||||
it("Should sample models", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: ['front'],
|
||||
|
@ -281,9 +280,10 @@ it("Should sample models", () => {
|
|||
expect(pattern.is).to.equal('sample')
|
||||
expect(pattern.parts.front.paths[`line_-1`].ops[1].to.x).to.equal(50);
|
||||
expect(pattern.parts.front.paths[`line_0`].ops[1].to.x).to.equal(100);
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
||||
it("Should register a hook via on", () => {
|
||||
it("Should register a hook via on", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let count = 0;
|
||||
pattern._draft = () => {};
|
||||
|
@ -292,9 +292,9 @@ it("Should register a hook via on", () => {
|
|||
});
|
||||
pattern.draft();
|
||||
expect(count).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should register a hook from a plugin", () => {
|
||||
it("Should register a hook from a plugin", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let count = 0;
|
||||
pattern._draft = () => {};
|
||||
|
@ -310,9 +310,9 @@ it("Should register a hook from a plugin", () => {
|
|||
pattern.use(plugin);
|
||||
pattern.draft();
|
||||
expect(count).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should register multiple methods on a single hook", () => {
|
||||
it("Should register multiple methods on a single hook", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let count = 0;
|
||||
pattern._draft = () => {};
|
||||
|
@ -333,9 +333,9 @@ it("Should register multiple methods on a single hook", () => {
|
|||
pattern.use(plugin);
|
||||
pattern.draft();
|
||||
expect(count).to.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should check whether a part is needed", () => {
|
||||
it("Should check whether a part is needed", () => {
|
||||
let config = {
|
||||
name: "test",
|
||||
dependencies: { back: "front", side: "back" },
|
||||
|
@ -359,9 +359,9 @@ it("Should check whether a part is needed", () => {
|
|||
//expect(pattern.needs("back")).to.equal(true);
|
||||
//expect(pattern.needs("front")).to.equal(true);
|
||||
//expect(pattern.needs("side")).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should check whether a part is wanted", () => {
|
||||
it("Should check whether a part is wanted", () => {
|
||||
let config = {
|
||||
name: "test",
|
||||
dependencies: { back: "front", side: "back" },
|
||||
|
@ -390,9 +390,9 @@ it("Should check whether a part is wanted", () => {
|
|||
expect(pattern.wants("back")).to.equal(true);
|
||||
expect(pattern.wants("front")).to.equal(false);
|
||||
expect(pattern.wants("side")).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly resolve dependencies - string version", () => {
|
||||
it("Should correctly resolve dependencies - string version", () => {
|
||||
let config = {
|
||||
name: "test",
|
||||
dependencies: { front: "back", side: "back", hood: "front", stripe: "hood" },
|
||||
|
@ -424,9 +424,9 @@ it("Should correctly resolve dependencies - string version", () => {
|
|||
expect(pattern.config.draftOrder[1]).to.equal('front');
|
||||
expect(pattern.config.draftOrder[2]).to.equal('side');
|
||||
expect(pattern.config.draftOrder[3]).to.equal('hood');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly resolve dependencies - array version", () => {
|
||||
it("Should correctly resolve dependencies - array version", () => {
|
||||
let config = {
|
||||
name: "test",
|
||||
dependencies: { front: ["back"], side: ["back"], hood: ["front"], stripe: ["hood"]},
|
||||
|
@ -461,9 +461,9 @@ it("Should correctly resolve dependencies - array version", () => {
|
|||
expect(pattern.config.draftOrder[1]).to.equal('front');
|
||||
expect(pattern.config.draftOrder[2]).to.equal('side');
|
||||
expect(pattern.config.draftOrder[3]).to.equal('hood');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly resolve dependencies - issue #971 - working version", () => {
|
||||
it("Should correctly resolve dependencies - issue #971 - working version", () => {
|
||||
let config = {
|
||||
name: "test",
|
||||
dependencies: {front:['back'],crotch:['front','back']},
|
||||
|
@ -486,9 +486,9 @@ it("Should correctly resolve dependencies - issue #971 - working version", () =>
|
|||
expect(pattern.config.draftOrder[0]).to.equal('back');
|
||||
expect(pattern.config.draftOrder[1]).to.equal('front');
|
||||
expect(pattern.config.draftOrder[2]).to.equal('crotch');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly resolve dependencies - issue #971 - broken version", () => {
|
||||
it("Should correctly resolve dependencies - issue #971 - broken version", () => {
|
||||
let config = {
|
||||
name: "test",
|
||||
dependencies: {front:'back',crotch:['front','back']},
|
||||
|
@ -511,9 +511,9 @@ it("Should correctly resolve dependencies - issue #971 - broken version", () =>
|
|||
expect(pattern.config.draftOrder[0]).to.equal('back');
|
||||
expect(pattern.config.draftOrder[1]).to.equal('front');
|
||||
expect(pattern.config.draftOrder[2]).to.equal('crotch');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly resolve dependencies - Handle uncovered code path", () => {
|
||||
it("Should correctly resolve dependencies - Handle uncovered code path", () => {
|
||||
let config = {
|
||||
name: "test",
|
||||
dependencies: {
|
||||
|
@ -544,15 +544,15 @@ it("Should correctly resolve dependencies - Handle uncovered code path", () => {
|
|||
expect(pattern.config.draftOrder[0]).to.equal('side');
|
||||
expect(pattern.config.draftOrder[1]).to.equal('back');
|
||||
expect(pattern.config.draftOrder[2]).to.equal('front');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should check whether created parts get the pattern context", () => {
|
||||
it("Should check whether created parts get the pattern context", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let part = new pattern.Part();
|
||||
expect(part.context.settings).to.equal(pattern.settings);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly merge settings", () => {
|
||||
it("Should correctly merge settings", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
let settings = {
|
||||
complete: false,
|
||||
|
@ -564,9 +564,9 @@ it("Should correctly merge settings", () => {
|
|||
expect(pattern.settings.only[1]).to.equal(2);
|
||||
expect(pattern.settings.margin).to.equal(5);
|
||||
expect(pattern.settings.only.length).to.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly merge settings for existing array", () => {
|
||||
it("Should correctly merge settings for existing array", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.only = [1];
|
||||
let settings = {
|
||||
|
@ -578,16 +578,17 @@ it("Should correctly merge settings for existing array", () => {
|
|||
expect(pattern.settings.complete).to.equal(false);
|
||||
expect(pattern.settings.only.length).to.equal(4);
|
||||
expect(pattern.settings.margin).to.equal(5);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return all render props", () => {
|
||||
it("Should return all render props", () => {
|
||||
const front = {
|
||||
name: 'front',
|
||||
draft: function(part) { return part }
|
||||
}
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: ['front'],
|
||||
parts: [front],
|
||||
});
|
||||
Test.prototype.draftFront = function(part) {
|
||||
return part;
|
||||
};
|
||||
const pattern = new Test()
|
||||
pattern.draft();
|
||||
const rp = pattern.getRenderProps()
|
||||
|
@ -595,24 +596,32 @@ it("Should return all render props", () => {
|
|||
expect(rp.width).to.equal(4);
|
||||
expect(rp.height).to.equal(4);
|
||||
expect(rp.parts.front.height).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not pack a pattern with errors", () => {
|
||||
it("Should not pack a pattern with errors", () => {
|
||||
const pattern = new freesewing.Pattern()
|
||||
pattern.events.error.push('error')
|
||||
pattern.pack()
|
||||
expect(pattern.events.warning.length).to.equal(1)
|
||||
expect(pattern.events.warning[0]).to.equal('One or more errors occured. Not packing pattern parts')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate an auto layout if there is no set layout", () => {
|
||||
const Test = new freesewing.Design({ name: "test", parts: ['front'] })
|
||||
Test.prototype.draftFront = function(part) {
|
||||
/*
|
||||
it("Should generate an auto layout if there is no set layout", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: [
|
||||
{
|
||||
name: 'front',
|
||||
draft: function(part) {
|
||||
const {Path, paths, Point} = part.shorthand()
|
||||
paths.seam = new Path().move(new Point(0,0))
|
||||
.line(new Point(5,5))
|
||||
return part
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
const pattern = new Test()
|
||||
pattern.parts.front = new pattern.Part('front')
|
||||
pattern.draftFront(pattern.parts.front);
|
||||
|
@ -620,9 +629,10 @@ it("Should generate an auto layout if there is no set layout", () => {
|
|||
expect(pattern.autoLayout.parts.front).to.exist
|
||||
expect(pattern.autoLayout.parts.front.move.y).to.equal(2)
|
||||
expect(pattern.autoLayout.parts.front.move.x).to.equal(2)
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
it("Should handle custom layouts", () => {
|
||||
it("Should handle custom layouts", () => {
|
||||
const Test = new freesewing.Design({ name: "test", parts: ['front'] })
|
||||
Test.prototype.draftFront = function(part) { return part }
|
||||
const pattern = new Test({
|
||||
|
@ -635,9 +645,9 @@ it("Should handle custom layouts", () => {
|
|||
pattern.pack()
|
||||
expect(pattern.width).to.equal(400)
|
||||
expect(pattern.height).to.equal(200)
|
||||
});
|
||||
});
|
||||
|
||||
it("Should handle a simple snapped option", () => {
|
||||
it("Should handle a simple snapped option", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: ['front'],
|
||||
|
@ -678,18 +688,15 @@ it("Should handle a simple snapped option", () => {
|
|||
expect(pattern.parts.front.paths.line_8.ops[1].to.x).to.equal(60);
|
||||
expect(pattern.parts.front.paths.line_9.ops[1].to.x).to.equal(80);
|
||||
expect(pattern.parts.front.paths.line_10.ops[1].to.x).to.equal(80);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should handle a list snapped option", () => {
|
||||
it("Should handle a list snapped option", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: ['front'],
|
||||
measurements: [ 'head' ],
|
||||
options: {
|
||||
len: { pct: 50, min: 22, max: 78, snap: [10,14,19,28], ...freesewing.pctBasedOn('head') }
|
||||
}
|
||||
})
|
||||
Test.prototype.draftFront = function(part) {
|
||||
parts: [
|
||||
{
|
||||
name: 'front',
|
||||
draft: function(part) {
|
||||
const { Point, points, Path, paths, absoluteOptions } = part.shorthand()
|
||||
points.from = new Point(0, 0);
|
||||
points.to = new Point( absoluteOptions.len, 0)
|
||||
|
@ -698,7 +705,14 @@ it("Should handle a list snapped option", () => {
|
|||
.line(points.to)
|
||||
|
||||
return part
|
||||
};
|
||||
}
|
||||
}
|
||||
],
|
||||
measurements: [ 'head' ],
|
||||
options: {
|
||||
len: { pct: 50, min: 22, max: 78, snap: [10,14,19,28], ...freesewing.pctBasedOn('head') }
|
||||
}
|
||||
})
|
||||
let pattern = new Test({
|
||||
sample: {
|
||||
type: 'option',
|
||||
|
@ -721,30 +735,32 @@ it("Should handle a list snapped option", () => {
|
|||
expect(pattern.parts.front.paths.line_8.ops[1].to.x).to.equal(28);
|
||||
expect(pattern.parts.front.paths.line_9.ops[1].to.x).to.equal(28);
|
||||
expect(freesewing.utils.round(pattern.parts.front.paths.line_10.ops[1].to.x)).to.equal(33.72);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("Should retrieve the cutList", () => {
|
||||
it("Should retrieve the cutList", () => {
|
||||
const Test = new freesewing.Design({
|
||||
name: "test",
|
||||
parts: ['front'],
|
||||
})
|
||||
Test.prototype.draftFront = function(part) {
|
||||
part.addCut(4, 'lining', true)
|
||||
|
||||
parts: [{
|
||||
name: 'front',
|
||||
draft: function(part) {
|
||||
const { addCut } = part.shorthand()
|
||||
addCut(4, 'lining', true)
|
||||
return part
|
||||
};
|
||||
}
|
||||
}],
|
||||
})
|
||||
const pattern = new Test()
|
||||
expect(JSON.stringify(pattern.getCutList())).to.equal(JSON.stringify({}))
|
||||
pattern.draft()
|
||||
const list = `{"front":{"grain":90,"materials":{"lining":{"cut":4,"identical":true}}}}`
|
||||
expect(JSON.stringify(pattern.getCutList())).to.equal(list)
|
||||
});
|
||||
});
|
||||
|
||||
// 2022 style part inheritance
|
||||
// I am aware this does too much for one unit test, but this is to simplify TDD
|
||||
// we can split it up later
|
||||
it("Design constructor should resolve nested injections (2022)", () => {
|
||||
// 2022 style part inheritance
|
||||
// I am aware this does too much for one unit test, but this is to simplify TDD
|
||||
// we can split it up later
|
||||
it("Design constructor should resolve nested injections", () => {
|
||||
const partA = {
|
||||
name: "partA",
|
||||
options: { optionA: { bool: true } },
|
||||
|
@ -896,9 +912,9 @@ it("Design constructor should resolve nested injections (2022)", () => {
|
|||
expect(pattern.parts.partR.paths.r.ops[0].to.y).to.equal(4)
|
||||
expect(pattern.parts.partR.paths.r.ops[1].to.x).to.equal(44)
|
||||
expect(pattern.parts.partR.paths.r.ops[1].to.y).to.equal(44)
|
||||
})
|
||||
})
|
||||
|
||||
it("Design constructor should resolve nested dependencies (2022)", () => {
|
||||
it("Design constructor should resolve nested dependencies (2022)", () => {
|
||||
const partA = {
|
||||
name: "partA",
|
||||
options: { optionA: { bool: true } },
|
||||
|
@ -1042,8 +1058,8 @@ it("Design constructor should resolve nested dependencies (2022)", () => {
|
|||
expect(pattern.parts.partD.paths.d.ops[0].to.y).to.equal(4)
|
||||
expect(pattern.parts.partD.paths.d.ops[1].to.x).to.equal(44)
|
||||
expect(pattern.parts.partD.paths.d.ops[1].to.y).to.equal(44)
|
||||
})
|
||||
it("Pattern should merge optiongroups", () => {
|
||||
})
|
||||
it("Pattern should merge optiongroups", () => {
|
||||
const partA = {
|
||||
name: "partA",
|
||||
options: { optionA: { bool: true } },
|
||||
|
@ -1135,5 +1151,6 @@ it("Pattern should merge optiongroups", () => {
|
|||
expect(og.subnested.subnested1.indexOf('subnested1b2') === -1).to.equal(false)
|
||||
expect(og.subnested.subnested1.indexOf('subnested1b3') === -1).to.equal(false)
|
||||
// FIXME: Some work to be done still with deep-nesting of groups with the same name
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -5,24 +5,25 @@ const expect = chai.expect
|
|||
const Point = freesewing.Point
|
||||
const round = freesewing.utils.round
|
||||
|
||||
it("Should return point object", () => {
|
||||
describe('Point', () => {
|
||||
it("Should return point object", () => {
|
||||
let result = new Point(2, 4);
|
||||
expect(result).to.be.a("object");
|
||||
expect(result.x).to.equal(2);
|
||||
expect(result.y).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not limit point precision", () => {
|
||||
it("Should not limit point precision", () => {
|
||||
let result = new Point(2.12345, 4.98765);
|
||||
expect(result.x).to.equal(2.12345);
|
||||
expect(result.y).to.equal(4.98765);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return distance", () => {
|
||||
it("Should return distance", () => {
|
||||
expect(round(new Point(2, 4).dist(new Point(-123, -32423)))).to.equal(32427.24);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return slope", () => {
|
||||
it("Should return slope", () => {
|
||||
let from = new Point(0, 0);
|
||||
expect(from.slope(new Point(0, -10))).to.equal(-Infinity);
|
||||
expect(from.slope(new Point(10, 0))).to.equal(0);
|
||||
|
@ -30,9 +31,9 @@ it("Should return slope", () => {
|
|||
expect(from.slope(new Point(-10, 0))).to.equal(-0);
|
||||
expect(from.slope(new Point(10, 10))).to.equal(1);
|
||||
expect(from.slope(new Point(-10, 5))).to.equal(-0.5);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return angle", () => {
|
||||
it("Should return angle", () => {
|
||||
let from = new Point(0, 0);
|
||||
expect(from.angle(new Point(10, 0))).to.equal(0);
|
||||
expect(from.angle(new Point(-20, 0))).to.equal(180);
|
||||
|
@ -40,59 +41,59 @@ it("Should return angle", () => {
|
|||
expect(from.angle(new Point(0, 10))).to.equal(270);
|
||||
expect(from.angle(new Point(10, -10))).to.equal(45);
|
||||
expect(from.angle(new Point(10, 10))).to.equal(315);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should copy a point", () => {
|
||||
it("Should copy a point", () => {
|
||||
let result = new Point(2, 4).copy();
|
||||
expect(result.x).to.equal(2);
|
||||
expect(result.y).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should check points for equality", () => {
|
||||
it("Should check points for equality", () => {
|
||||
let a = new Point(-123, 456);
|
||||
let b = new Point(-123, 456);
|
||||
expect(a).to.deep.equal(b);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should flip point around unset X value", () => {
|
||||
it("Should flip point around unset X value", () => {
|
||||
let result = new Point(2, 4).flipX();
|
||||
expect(result.x).to.equal(-2);
|
||||
expect(result.y).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should flip point around X value that is zero", () => {
|
||||
it("Should flip point around X value that is zero", () => {
|
||||
let flip = new Point(0, 0);
|
||||
let result = new Point(2, 4).flipX(flip);
|
||||
expect(result.x).to.equal(-2);
|
||||
expect(result.y).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should flip point around X value", () => {
|
||||
it("Should flip point around X value", () => {
|
||||
let result = new Point(2, 4).flipX(new Point(-20, 19));
|
||||
expect(result.x).to.equal(-42);
|
||||
expect(result.y).to.equal(4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should flip point around unset Y value", () => {
|
||||
it("Should flip point around unset Y value", () => {
|
||||
let result = new Point(2, 4).flipY();
|
||||
expect(result.x).to.equal(2);
|
||||
expect(result.y).to.equal(-4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should flip point around Y value that is zero", () => {
|
||||
it("Should flip point around Y value that is zero", () => {
|
||||
let flip = new Point(0, 0);
|
||||
let result = new Point(2, 4).flipY(flip);
|
||||
expect(result.x).to.equal(2);
|
||||
expect(result.y).to.equal(-4);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should flip point around Y value", () => {
|
||||
it("Should flip point around Y value", () => {
|
||||
let result = new Point(2, 4).flipY(new Point(12, -14));
|
||||
expect(result.x).to.equal(2);
|
||||
expect(result.y).to.equal(-32);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift a point", () => {
|
||||
it("Should shift a point", () => {
|
||||
let origin = new Point(0, 0);
|
||||
let n = origin.shift(90, 10);
|
||||
let e = origin.shift(0, 10);
|
||||
|
@ -109,9 +110,9 @@ it("Should shift a point", () => {
|
|||
let rand = origin.shift(-123, 456);
|
||||
expect(round(rand.x)).to.equal(-248.36);
|
||||
expect(round(rand.y)).to.equal(382.43);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift a point towards another", () => {
|
||||
it("Should shift a point towards another", () => {
|
||||
let origin = new Point(0, 0);
|
||||
let n = new Point(0, -10);
|
||||
let e = new Point(10, 0);
|
||||
|
@ -131,9 +132,9 @@ it("Should shift a point towards another", () => {
|
|||
expect(round(sw.y)).to.equal(0);
|
||||
expect(round(sw.shiftTowards(sn, 100).x)).to.equal(-52.29);
|
||||
expect(round(ss.shiftTowards(se, 200).y)).to.equal(-18.42);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift a point a fraction towards another", () => {
|
||||
it("Should shift a point a fraction towards another", () => {
|
||||
let origin = new Point(0, 0);
|
||||
let n = new Point(0, -10);
|
||||
let e = new Point(10, 0);
|
||||
|
@ -153,9 +154,9 @@ it("Should shift a point a fraction towards another", () => {
|
|||
expect(round(sw.y)).to.equal(0);
|
||||
expect(round(sw.shiftFractionTowards(sn, 100).x)).to.equal(2475);
|
||||
expect(round(ss.shiftFractionTowards(se, 200).y)).to.equal(-995);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shift a point beyond another", () => {
|
||||
it("Should shift a point beyond another", () => {
|
||||
let origin = new Point(0, 0);
|
||||
let n = new Point(0, -10);
|
||||
let e = new Point(10, 0);
|
||||
|
@ -175,9 +176,9 @@ it("Should shift a point beyond another", () => {
|
|||
expect(round(sw.y)).to.equal(0);
|
||||
expect(round(sw.shiftOutwards(sn, 100).x)).to.equal(70.71);
|
||||
expect(round(ss.shiftOutwards(se, 200).y)).to.equal(-141.42);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should rotate a point around another", () => {
|
||||
it("Should rotate a point around another", () => {
|
||||
let sun = new Point(0, 0);
|
||||
let moon = new Point(10, 0);
|
||||
let a = moon.rotate(90, sun);
|
||||
|
@ -194,47 +195,47 @@ it("Should rotate a point around another", () => {
|
|||
let d = moon2.rotate(90, sun2);
|
||||
expect(round(d.x)).to.equal(219);
|
||||
expect(round(d.y)).to.equal(54);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set an attribute", () => {
|
||||
it("Should set an attribute", () => {
|
||||
let p = new Point(0, 0).attr("class", "test");
|
||||
expect(p.attributes.get("class")).to.equal("test");
|
||||
p.attr("class", "more");
|
||||
expect(p.attributes.get("class")).to.equal("test more");
|
||||
p.attr("class", "less", true);
|
||||
expect(p.attributes.get("class")).to.equal("less");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should detect points in the same location", () => {
|
||||
it("Should detect points in the same location", () => {
|
||||
let p1 = new Point(123, 456);
|
||||
let p2 = new Point(123, 456);
|
||||
expect(p1.sitsOn(p2)).to.equal(true);
|
||||
p2.x = 122.99;
|
||||
expect(p1.sitsOn(p2)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should clone a point", () => {
|
||||
it("Should clone a point", () => {
|
||||
let p1 = new Point(123, 456).attr("class", "something");
|
||||
p1.attr("class", "else");
|
||||
let p2 = p1.clone();
|
||||
expect(p2.sitsOn(p1)).to.equal(true);
|
||||
expect(p2.attributes.get("class")).to.equal("something else");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should translate a point", () => {
|
||||
it("Should translate a point", () => {
|
||||
let p1 = new Point(10, 20);
|
||||
let p2 = p1.translate(15, 50);
|
||||
expect(p2.x).to.equal(25);
|
||||
expect(p2.y).to.equal(70);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should add raise methods to a point", () => {
|
||||
it("Should add raise methods to a point", () => {
|
||||
const raise = () => 'hello'
|
||||
const p1 = new Point(10, 20).withRaise(raise);
|
||||
expect(p1.raise()).to.equal('hello');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning on invalid point coordinates", () => {
|
||||
it("Should raise a warning on invalid point coordinates", () => {
|
||||
const invalid = { x: false, y: false }
|
||||
const raiseX = { warning: () => invalid.x = true }
|
||||
const raiseY = { warning: () => invalid.y = true }
|
||||
|
@ -246,9 +247,9 @@ it("Should raise a warning on invalid point coordinates", () => {
|
|||
p2.check()
|
||||
expect(invalid.x).to.equal(true);
|
||||
expect(invalid.y).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning if rotation is not a number", () => {
|
||||
it("Should raise a warning if rotation is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -256,9 +257,9 @@ it("Should raise a warning if rotation is not a number", () => {
|
|||
expect(invalid).to.equal(false);
|
||||
const p3 = p1.rotate('a', p2)
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning if rotating around what is not a point", () => {
|
||||
it("Should raise a warning if rotating around what is not a point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -270,9 +271,9 @@ it("Should raise a warning if rotating around what is not a point", () => {
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when flipX'ing around what is not a point", () => {
|
||||
it("Should raise a warning when flipX'ing around what is not a point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -285,9 +286,9 @@ it("Should raise a warning when flipX'ing around what is not a point", () => {
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when flipY'ing around what is not a point", () => {
|
||||
it("Should raise a warning when flipY'ing around what is not a point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -300,9 +301,9 @@ it("Should raise a warning when flipY'ing around what is not a point", () => {
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting with a distance that is not a number", () => {
|
||||
it("Should raise a warning when shifting with a distance that is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -314,9 +315,9 @@ it("Should raise a warning when shifting with a distance that is not a number",
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting with an angle that is not a number", () => {
|
||||
it("Should raise a warning when shifting with an angle that is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -328,9 +329,9 @@ it("Should raise a warning when shifting with an angle that is not a number", ()
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting towards with a distance that is not a number", () => {
|
||||
it("Should raise a warning when shifting towards with a distance that is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -343,9 +344,9 @@ it("Should raise a warning when shifting towards with a distance that is not a n
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting towards with a target that is not a point", () => {
|
||||
it("Should raise a warning when shifting towards with a target that is not a point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -358,9 +359,9 @@ it("Should raise a warning when shifting towards with a target that is not a poi
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting fraction towards with a distance that is not a number", () => {
|
||||
it("Should raise a warning when shifting fraction towards with a distance that is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -373,9 +374,9 @@ it("Should raise a warning when shifting fraction towards with a distance that i
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting a fraction towards with a target that is not a point", () => {
|
||||
it("Should raise a warning when shifting a fraction towards with a target that is not a point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -388,9 +389,9 @@ it("Should raise a warning when shifting a fraction towards with a target that i
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting outowards with a distance that is not a number", () => {
|
||||
it("Should raise a warning when shifting outowards with a distance that is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -403,9 +404,9 @@ it("Should raise a warning when shifting outowards with a distance that is not a
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when shifting a outowards with a target that is not a point", () => {
|
||||
it("Should raise a warning when shifting a outowards with a target that is not a point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -418,9 +419,9 @@ it("Should raise a warning when shifting a outowards with a target that is not a
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when translating with an X-delta that is not a number", () => {
|
||||
it("Should raise a warning when translating with an X-delta that is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -432,9 +433,9 @@ it("Should raise a warning when translating with an X-delta that is not a number
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when translating with an Y-delta that is not a number", () => {
|
||||
it("Should raise a warning when translating with an Y-delta that is not a number", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -446,9 +447,9 @@ it("Should raise a warning when translating with an Y-delta that is not a number
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when sitsOn receives a non-point", () => {
|
||||
it("Should raise a warning when sitsOn receives a non-point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -460,9 +461,9 @@ it("Should raise a warning when sitsOn receives a non-point", () => {
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when sitsRoughlyOn receives a non-point", () => {
|
||||
it("Should raise a warning when sitsRoughlyOn receives a non-point", () => {
|
||||
let invalid = false
|
||||
const raise = { warning: () => invalid = true }
|
||||
const p1 = new Point(10,10).withRaise(raise);
|
||||
|
@ -474,27 +475,28 @@ it("Should raise a warning when sitsRoughlyOn receives a non-point", () => {
|
|||
expect(''+err).to.contain("check is not a function")
|
||||
}
|
||||
expect(invalid).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set the data-text property in a chainable way", () => {
|
||||
it("Should set the data-text property in a chainable way", () => {
|
||||
const p1 = new Point(10,10).setText('hello')
|
||||
expect(p1.attributes.get('data-text')).to.equal('hello');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set the data-text-class property in a chainable way", () => {
|
||||
it("Should set the data-text-class property in a chainable way", () => {
|
||||
const p1 = new Point(10,10).setText('hello', 'fabric')
|
||||
expect(p1.attributes.get('data-text')).to.equal('hello');
|
||||
expect(p1.attributes.get('data-text-class')).to.equal('fabric');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set the data-circle property in a chainable way", () => {
|
||||
it("Should set the data-circle property in a chainable way", () => {
|
||||
const p1 = new Point(10,10).setCircle('20')
|
||||
expect(p1.attributes.get('data-circle')).to.equal('20');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set the data-circle-class property in a chainable way", () => {
|
||||
it("Should set the data-circle-class property in a chainable way", () => {
|
||||
const p1 = new Point(10,10).setCircle('20', 'fabric')
|
||||
expect(p1.attributes.get('data-circle')).to.equal('20');
|
||||
expect(p1.attributes.get('data-circle-class')).to.equal('fabric');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
import chai from "chai"
|
||||
import freesewing from "../dist/index.js"
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
const measurements = { head: 400 }
|
||||
const toAbs = (val, { measurements }) => measurements.head * val
|
||||
|
||||
it("Should snap a percentage options to equal steps", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: { pct: 30, min: 0, max: 100, snap: 12, toAbs }
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(60)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(108)
|
||||
});
|
||||
|
||||
it("Should snap a percentage options to the Fibonacci sequence", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: {
|
||||
pct: 30, min: 0, max: 100, toAbs,
|
||||
snap: [ 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 ],
|
||||
}
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements })
|
||||
const patternC = new design({ options: { test: 0.97 }, measurements })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(55)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(89)
|
||||
expect(patternC.settings.absoluteOptions.test).to.equal(388)
|
||||
});
|
||||
|
||||
it("Should snap a percentage options to imperial snaps", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: {
|
||||
pct: 30, min: 0, max: 100, toAbs,
|
||||
snap: {
|
||||
metric: [ 25, 50, 75, 100 ],
|
||||
imperial: [ 25.4, 50.8, 76.2, 101.6 ],
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements, units:'metric' })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements, units:'metric' })
|
||||
const patternC = new design({ options: { test: 0.97 }, measurements, units:'metric' })
|
||||
const patternD = new design({ options: { test: 0.01 }, measurements, units:'metric' })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(50)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(100)
|
||||
expect(patternC.settings.absoluteOptions.test).to.equal(388)
|
||||
expect(patternD.settings.absoluteOptions.test).to.equal(4)
|
||||
});
|
||||
|
||||
it("Should snap a percentage options to metrics snaps", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: {
|
||||
pct: 30, min: 0, max: 100, toAbs,
|
||||
snap: {
|
||||
metric: [ 25, 50, 75, 100 ],
|
||||
imperial: [ 25.4, 50.8, 76.2, 101.6 ],
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements, units:'imperial' })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements, units:'imperial' })
|
||||
const patternC = new design({ options: { test: 0.97 }, measurements, units:'imperial' })
|
||||
const patternD = new design({ options: { test: 0.01 }, measurements, units:'imperial' })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(50.8)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(101.6)
|
||||
expect(patternC.settings.absoluteOptions.test).to.equal(388)
|
||||
expect(patternD.settings.absoluteOptions.test).to.equal(4)
|
||||
});
|
||||
|
83
packages/core/tests/snap.mjs
Normal file
83
packages/core/tests/snap.mjs
Normal file
|
@ -0,0 +1,83 @@
|
|||
import chai from "chai"
|
||||
import freesewing from "../dist/index.js"
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
const measurements = { head: 400 }
|
||||
const toAbs = (val, { measurements }) => measurements.head * val
|
||||
|
||||
describe('Snapped options', () => {
|
||||
it("Should snap a percentage options to equal steps", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: { pct: 30, min: 0, max: 100, snap: 12, toAbs }
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(60)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(108)
|
||||
});
|
||||
|
||||
it("Should snap a percentage options to the Fibonacci sequence", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: {
|
||||
pct: 30, min: 0, max: 100, toAbs,
|
||||
snap: [ 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 ],
|
||||
}
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements })
|
||||
const patternC = new design({ options: { test: 0.97 }, measurements })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(55)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(89)
|
||||
expect(patternC.settings.absoluteOptions.test).to.equal(388)
|
||||
});
|
||||
|
||||
it("Should snap a percentage options to imperial snaps", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: {
|
||||
pct: 30, min: 0, max: 100, toAbs,
|
||||
snap: {
|
||||
metric: [ 25, 50, 75, 100 ],
|
||||
imperial: [ 25.4, 50.8, 76.2, 101.6 ],
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements, units:'metric' })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements, units:'metric' })
|
||||
const patternC = new design({ options: { test: 0.97 }, measurements, units:'metric' })
|
||||
const patternD = new design({ options: { test: 0.01 }, measurements, units:'metric' })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(50)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(100)
|
||||
expect(patternC.settings.absoluteOptions.test).to.equal(388)
|
||||
expect(patternD.settings.absoluteOptions.test).to.equal(4)
|
||||
});
|
||||
|
||||
it("Should snap a percentage options to metrics snaps", () => {
|
||||
const design = new freesewing.Design({
|
||||
options: {
|
||||
test: {
|
||||
pct: 30, min: 0, max: 100, toAbs,
|
||||
snap: {
|
||||
metric: [ 25, 50, 75, 100 ],
|
||||
imperial: [ 25.4, 50.8, 76.2, 101.6 ],
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const patternA = new design({ options: { test: 0.13 }, measurements, units:'imperial' })
|
||||
const patternB = new design({ options: { test: 0.27 }, measurements, units:'imperial' })
|
||||
const patternC = new design({ options: { test: 0.97 }, measurements, units:'imperial' })
|
||||
const patternD = new design({ options: { test: 0.01 }, measurements, units:'imperial' })
|
||||
expect(patternA.settings.absoluteOptions.test).to.equal(50.8)
|
||||
expect(patternB.settings.absoluteOptions.test).to.equal(101.6)
|
||||
expect(patternC.settings.absoluteOptions.test).to.equal(388)
|
||||
expect(patternD.settings.absoluteOptions.test).to.equal(4)
|
||||
});
|
||||
});
|
||||
|
|
@ -3,21 +3,22 @@ import freesewing from "./dist/index.mjs"
|
|||
|
||||
const expect = chai.expect
|
||||
|
||||
it("Should create a snippet", () => {
|
||||
describe('Snippet', () => {
|
||||
it("Should create a snippet", () => {
|
||||
let snip1 = new freesewing.Snippet("test", new freesewing.Point(12, 34));
|
||||
expect(snip1.def).to.equal("test");
|
||||
expect(snip1.anchor.x).to.equal(12);
|
||||
expect(snip1.anchor.y).to.equal(34);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should clone a snippet", () => {
|
||||
it("Should clone a snippet", () => {
|
||||
let snip3 = new freesewing.Snippet("boo", new freesewing.Point(56, 78));
|
||||
expect(snip3.clone().def).to.equal("boo");
|
||||
expect(snip3.clone().anchor.x).to.equal(56);
|
||||
expect(snip3.clone().anchor.y).to.equal(78);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set an attribute", () => {
|
||||
it("Should set an attribute", () => {
|
||||
let s = new freesewing.Snippet("test", new freesewing.Point(12, -34)).attr(
|
||||
"class",
|
||||
"test"
|
||||
|
@ -27,5 +28,6 @@ it("Should set an attribute", () => {
|
|||
expect(s.attributes.get("class")).to.equal("test more");
|
||||
s.attr("class", "less", true);
|
||||
expect(s.attributes.get("class")).to.equal("less");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -3,27 +3,29 @@ import freesewing from "./dist/index.mjs"
|
|||
|
||||
const expect = chai.expect
|
||||
|
||||
let pattern = new freesewing.Pattern();
|
||||
let store = pattern.store;
|
||||
const pattern = new freesewing.Pattern();
|
||||
const store = pattern.store;
|
||||
|
||||
it("Store should be a Map", () => {
|
||||
describe('Store', () => {
|
||||
it("Store should be a Map", () => {
|
||||
expect(store.data.toString()).to.equal("[object Map]");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set/get a store value", () => {
|
||||
it("Should set/get a store value", () => {
|
||||
store.set("foo", "bar");
|
||||
expect(store.get("foo")).to.equal("bar");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should set a store value only if unset", () => {
|
||||
it("Should set a store value only if unset", () => {
|
||||
store.setIfUnset("few", "baz");
|
||||
store.setIfUnset("few", "schmoo");
|
||||
expect(store.get("few")).to.equal("baz");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should raise a warning when retrieving a invalid key", () => {
|
||||
it("Should raise a warning when retrieving a invalid key", () => {
|
||||
store.get('nope')
|
||||
expect(pattern.events.warning.length).to.equal(1)
|
||||
expect(pattern.events.warning[0]).to.equal('Tried to access `nope` in the `store` but it is not set')
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ chai.use(chaiString)
|
|||
const expect = chai.expect
|
||||
const { version } = pkg
|
||||
|
||||
it("Svg constructor should initialize object", () => {
|
||||
describe('Svg', () => {
|
||||
it("Svg constructor should initialize object", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
let svg = pattern.svg;
|
||||
|
@ -33,35 +34,35 @@ it("Svg constructor should initialize object", () => {
|
|||
"http://freesewing.org/namespaces/freesewing"
|
||||
);
|
||||
expect(svg.attributes.get("freesewing")).to.equal(version);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg boilerplate", () => {
|
||||
it("Should render Svg boilerplate", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.boilerplate);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render language attribute", () => {
|
||||
it("Should render language attribute", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.locale = "nl";
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.boilerplateNl);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg boilerplate for embedding", () => {
|
||||
it("Should render Svg boilerplate for embedding", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.embed = true;
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.embed);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg part boilerplate", () => {
|
||||
it("Should render Svg part boilerplate", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.part);
|
||||
pattern.parts.test.render = false;
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.boilerplate);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg path", () => {
|
||||
it("Should render Svg path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -74,8 +75,8 @@ it("Should render Svg path", () => {
|
|||
.attr("id", "something")
|
||||
.attr("class", "freesewing");
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.path);
|
||||
});
|
||||
it("Should not render Svg path when render property is false", () => {
|
||||
});
|
||||
it("Should not render Svg path when render property is false", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -89,9 +90,9 @@ it("Should not render Svg path when render property is false", () => {
|
|||
.attr("class", "freesewing");
|
||||
p.paths.test.render = false;
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.part);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg text", () => {
|
||||
it("Should render Svg text", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -101,9 +102,9 @@ it("Should render Svg text", () => {
|
|||
.attr("data-text-class", "text-lg");
|
||||
p.points.other = new p.Point(10, 10).attr("data-text", "");
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.text);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg multi-line text", () => {
|
||||
it("Should render Svg multi-line text", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -113,9 +114,9 @@ it("Should render Svg multi-line text", () => {
|
|||
.attr("data-text-class", "text-lg")
|
||||
.attr("data-text-lineheight", 8);
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.multiText);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg multi-line text with default lineheight", () => {
|
||||
it("Should render Svg multi-line text with default lineheight", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -124,18 +125,18 @@ it("Should render Svg multi-line text with default lineheight", () => {
|
|||
.attr("data-text", "This is a test\nwith text on\nmultiple lines")
|
||||
.attr("data-text-class", "text-lg");
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.multiTextDflt);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not render text when there is none", () => {
|
||||
it("Should not render text when there is none", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
let p = pattern.parts.test;
|
||||
p.points.test = new p.Point(20, 20);
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.part);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg text on path", () => {
|
||||
it("Should render Svg text on path", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -149,9 +150,9 @@ it("Should render Svg text on path", () => {
|
|||
.attr("data-text-class", "text-sm")
|
||||
.attr("class", "freesewing");
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.textOnPath);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg text on path, center aligned", () => {
|
||||
it("Should render Svg text on path, center aligned", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -165,9 +166,9 @@ it("Should render Svg text on path, center aligned", () => {
|
|||
.attr("data-text-class", "center")
|
||||
.attr("class", "freesewing");
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.textOnPathCenter);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render Svg text on path, right aligned", () => {
|
||||
it("Should render Svg text on path, right aligned", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -181,18 +182,18 @@ it("Should render Svg text on path, right aligned", () => {
|
|||
.attr("data-text-class", "right")
|
||||
.attr("class", "freesewing");
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.textOnPathRight);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render an Svg circle", () => {
|
||||
it("Should render an Svg circle", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
let p = pattern.parts.test;
|
||||
p.points.test = new p.Point(20, 20).attr("data-circle", "50");
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.circle);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render an Svg snippet", () => {
|
||||
it("Should render an Svg snippet", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -203,9 +204,9 @@ it("Should render an Svg snippet", () => {
|
|||
"This is a snippet"
|
||||
);
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.snippet);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should render a rotated Svg snippet", () => {
|
||||
it("Should render a rotated Svg snippet", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -216,17 +217,17 @@ it("Should render a rotated Svg snippet", () => {
|
|||
"This is a snippet"
|
||||
).attr('data-rotate', 90)
|
||||
expect(pattern.render()).to.equalIgnoreSpaces(render.rotatedSnippet);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should replaced double quotes in Svg text", () => {
|
||||
it("Should replaced double quotes in Svg text", () => {
|
||||
const pattern = new freesewing.Pattern()
|
||||
pattern.render()
|
||||
expect(
|
||||
pattern.svg.escapeText('This is a "test" message')
|
||||
).to.equal('This is a “test“ message')
|
||||
});
|
||||
});
|
||||
|
||||
it("Should scale an Svg snippet", () => {
|
||||
it("Should scale an Svg snippet", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.render();
|
||||
pattern.parts.test = new pattern.Part();
|
||||
|
@ -237,18 +238,18 @@ it("Should scale an Svg snippet", () => {
|
|||
"This is a snippet"
|
||||
).attr("data-scale", 2);
|
||||
expect(pattern.render()).to.contain("scale(2)");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should run preRender hook", () => {
|
||||
it("Should run preRender hook", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.on("preRender", svg => {
|
||||
svg.attributes.set("data-hook", "preRender");
|
||||
});
|
||||
pattern.render();
|
||||
expect(pattern.svg.attributes.get("data-hook")).to.equal("preRender");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should run insertText hook", () => {
|
||||
it("Should run insertText hook", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.on("insertText", (locale, text) => {
|
||||
return text.toUpperCase();
|
||||
|
@ -259,22 +260,23 @@ it("Should run insertText hook", () => {
|
|||
.attr("data-text", "This is a test")
|
||||
.attr("data-text-class", "text-lg");
|
||||
expect(pattern.render()).to.contain("THIS IS A TEST");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should run postRender hook", () => {
|
||||
it("Should run postRender hook", () => {
|
||||
let pattern = new freesewing.Pattern()
|
||||
pattern.on("postRender", svg => {
|
||||
svg.svg = "test";
|
||||
});
|
||||
expect(pattern.render()).to.equal("test");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should tab in and out", () => {
|
||||
it("Should tab in and out", () => {
|
||||
let pattern = new freesewing.Pattern()
|
||||
pattern.render()
|
||||
const svg = pattern.svg
|
||||
svg.tabs = 2
|
||||
expect(svg.tab()).to.equal(' ')
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -5,11 +5,12 @@ const { expect } = chai
|
|||
const utils = freesewing.utils
|
||||
const round = utils.round
|
||||
|
||||
it("Should return the correct macro name", () => {
|
||||
describe('Utils', () => {
|
||||
it("Should return the correct macro name", () => {
|
||||
expect(utils.macroName("test")).to.equal("_macro_test");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the intersection of two endless line segments", () => {
|
||||
it("Should find the intersection of two endless line segments", () => {
|
||||
let a = new freesewing.Point(10, 20);
|
||||
let b = new freesewing.Point(20, 24);
|
||||
let c = new freesewing.Point(90, 19);
|
||||
|
@ -17,18 +18,18 @@ it("Should find the intersection of two endless line segments", () => {
|
|||
let X = freesewing.utils.beamsIntersect(a, b, c, d);
|
||||
expect(round(X.x)).to.equal(60.49);
|
||||
expect(round(X.y)).to.equal(40.2);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should detect parallel lines", () => {
|
||||
it("Should detect parallel lines", () => {
|
||||
let a = new freesewing.Point(10, 20);
|
||||
let b = new freesewing.Point(20, 20);
|
||||
let c = new freesewing.Point(90, 40);
|
||||
let d = new freesewing.Point(19, 40);
|
||||
expect(freesewing.utils.beamsIntersect(a, b, c, d)).to.equal(false);
|
||||
expect(freesewing.utils.linesIntersect(a, b, c, d)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should detect vertical lines", () => {
|
||||
it("Should detect vertical lines", () => {
|
||||
let a = new freesewing.Point(10, 20);
|
||||
let b = new freesewing.Point(10, 90);
|
||||
let c = new freesewing.Point(90, 40);
|
||||
|
@ -38,9 +39,9 @@ it("Should detect vertical lines", () => {
|
|||
expect(X.y).to.equal(40);
|
||||
X = freesewing.utils.beamsIntersect(c, d, a, b);
|
||||
expect(X.x).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should swap direction prior to finding beam intersection", () => {
|
||||
it("Should swap direction prior to finding beam intersection", () => {
|
||||
let a = new freesewing.Point(10, 20);
|
||||
let b = new freesewing.Point(0, 90);
|
||||
let c = new freesewing.Point(90, 40);
|
||||
|
@ -48,17 +49,17 @@ it("Should swap direction prior to finding beam intersection", () => {
|
|||
let X = freesewing.utils.beamsIntersect(a, b, c, d);
|
||||
expect(round(X.x)).to.equal(7.14);
|
||||
expect(round(X.y)).to.equal(40);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return false when two lines don't intersect", () => {
|
||||
it("Should return false when two lines don't intersect", () => {
|
||||
let a = new freesewing.Point(10, 20);
|
||||
let b = new freesewing.Point(20, 24);
|
||||
let c = new freesewing.Point(90, 19);
|
||||
let d = new freesewing.Point(19, 70);
|
||||
expect(freesewing.utils.linesIntersect(a, b, c, d)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the intersection of two line segments", () => {
|
||||
it("Should find the intersection of two line segments", () => {
|
||||
let a = new freesewing.Point(10, 10);
|
||||
let b = new freesewing.Point(90, 74);
|
||||
let c = new freesewing.Point(90, 19);
|
||||
|
@ -66,37 +67,37 @@ it("Should find the intersection of two line segments", () => {
|
|||
let X = freesewing.utils.linesIntersect(a, b, c, d);
|
||||
expect(round(X.x)).to.equal(51.95);
|
||||
expect(round(X.y)).to.equal(43.56);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the intersection of an endles line and a give X-value", () => {
|
||||
it("Should find the intersection of an endles line and a give X-value", () => {
|
||||
let a = new freesewing.Point(10, 10);
|
||||
let b = new freesewing.Point(90, 74);
|
||||
let X = freesewing.utils.beamIntersectsX(a, b, 69);
|
||||
expect(X.x).to.equal(69);
|
||||
expect(X.y).to.equal(57.2);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the intersection of an endles line and a give Y-value", () => {
|
||||
it("Should find the intersection of an endles line and a give Y-value", () => {
|
||||
let a = new freesewing.Point(10, 10);
|
||||
let b = new freesewing.Point(90, 74);
|
||||
let X = freesewing.utils.beamIntersectsY(a, b, 69);
|
||||
expect(X.x).to.equal(83.75);
|
||||
expect(X.y).to.equal(69);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should detect vertical lines never pass a give X-value", () => {
|
||||
it("Should detect vertical lines never pass a give X-value", () => {
|
||||
let a = new freesewing.Point(10, 10);
|
||||
let b = new freesewing.Point(10, 90);
|
||||
expect(freesewing.utils.beamIntersectsX(a, b, 69)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should detect horizontal lines never pass a give Y-value", () => {
|
||||
it("Should detect horizontal lines never pass a give Y-value", () => {
|
||||
let a = new freesewing.Point(10, 10);
|
||||
let b = new freesewing.Point(90, 10);
|
||||
expect(freesewing.utils.beamIntersectsY(a, b, 69)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find no intersections between a curve and a line", () => {
|
||||
it("Should find no intersections between a curve and a line", () => {
|
||||
let A = new freesewing.Point(10, 10);
|
||||
let Acp = new freesewing.Point(310, 40);
|
||||
let B = new freesewing.Point(110, 70);
|
||||
|
@ -106,9 +107,9 @@ it("Should find no intersections between a curve and a line", () => {
|
|||
|
||||
let hit = freesewing.utils.lineIntersectsCurve(E, D, A, Acp, Bcp, B);
|
||||
expect(hit).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find 1 intersection between a curve and a line", () => {
|
||||
it("Should find 1 intersection between a curve and a line", () => {
|
||||
let A = new freesewing.Point(10, 10);
|
||||
let Acp = new freesewing.Point(310, 40);
|
||||
let B = new freesewing.Point(110, 70);
|
||||
|
@ -119,9 +120,9 @@ it("Should find 1 intersection between a curve and a line", () => {
|
|||
let hit = freesewing.utils.lineIntersectsCurve(E, D, A, Acp, Bcp, B);
|
||||
expect(round(hit.x)).to.equal(20.85);
|
||||
expect(round(hit.y)).to.equal(11.11);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find 3 intersections between a curve and a line", () => {
|
||||
it("Should find 3 intersections between a curve and a line", () => {
|
||||
let A = new freesewing.Point(10, 10);
|
||||
let Acp = new freesewing.Point(310, 40);
|
||||
let B = new freesewing.Point(110, 70);
|
||||
|
@ -131,9 +132,9 @@ it("Should find 3 intersections between a curve and a line", () => {
|
|||
|
||||
let hits = freesewing.utils.lineIntersectsCurve(E, D, A, Acp, Bcp, B);
|
||||
expect(hits.length).to.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find 9 intersections between two curves", () => {
|
||||
it("Should find 9 intersections between two curves", () => {
|
||||
let A = new freesewing.Point(10, 10);
|
||||
let Acp = new freesewing.Point(310, 40);
|
||||
let B = new freesewing.Point(110, 70);
|
||||
|
@ -145,9 +146,9 @@ it("Should find 9 intersections between two curves", () => {
|
|||
|
||||
let hits = freesewing.utils.curvesIntersect(A, Acp, Bcp, B, C, Ccp, Dcp, D);
|
||||
expect(hits.length).to.equal(9);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find 1 intersection between two curves", () => {
|
||||
it("Should find 1 intersection between two curves", () => {
|
||||
let A = new freesewing.Point(10, 10);
|
||||
let Acp = new freesewing.Point(310, 40);
|
||||
let B = new freesewing.Point(110, 70);
|
||||
|
@ -160,9 +161,9 @@ it("Should find 1 intersection between two curves", () => {
|
|||
let hit = freesewing.utils.curvesIntersect(A, Acp, Bcp, B, C, Ccp, Dcp, D);
|
||||
expect(round(hit.x)).to.equal(15.58);
|
||||
expect(round(hit.y)).to.equal(10.56);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find no intersection between two curves", () => {
|
||||
it("Should find no intersection between two curves", () => {
|
||||
let A = new freesewing.Point(10, 10);
|
||||
let Acp = new freesewing.Point(310, 40);
|
||||
let B = new freesewing.Point(110, 70);
|
||||
|
@ -174,32 +175,32 @@ it("Should find no intersection between two curves", () => {
|
|||
|
||||
let hit = freesewing.utils.curvesIntersect(A, Acp, Bcp, B, C, Ccp, Dcp, D);
|
||||
expect(hit).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should correctly format units", () => {
|
||||
it("Should correctly format units", () => {
|
||||
expect(freesewing.utils.units(123.456)).to.equal("12.35cm");
|
||||
expect(freesewing.utils.units(123.456, "imperial")).to.equal('4.86"');
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find a start or end point on beam", () => {
|
||||
it("Should find a start or end point on beam", () => {
|
||||
let A = new freesewing.Point(12, 34);
|
||||
let B = new freesewing.Point(56, 78);
|
||||
let checkA = new freesewing.Point(12, 34);
|
||||
let checkB = new freesewing.Point(56, 78);
|
||||
expect(freesewing.utils.pointOnBeam(A, B, checkA)).to.equal(true);
|
||||
expect(freesewing.utils.pointOnBeam(A, B, checkB)).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find whether a point lies on a line segment", () => {
|
||||
it("Should find whether a point lies on a line segment", () => {
|
||||
let A = new freesewing.Point(12, 34);
|
||||
let B = new freesewing.Point(56, 78);
|
||||
let check1 = A.shiftTowards(B, 10);
|
||||
let check2 = A.shiftTowards(B, 210);
|
||||
expect(freesewing.utils.pointOnLine(A, B, check1)).to.equal(true);
|
||||
expect(freesewing.utils.pointOnLine(A, B, check2)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find a start or end point on curve", () => {
|
||||
it("Should find a start or end point on curve", () => {
|
||||
let A = new freesewing.Point(12, 34);
|
||||
let Acp = new freesewing.Point(123, 4);
|
||||
let B = new freesewing.Point(56, 78);
|
||||
|
@ -208,9 +209,9 @@ it("Should find a start or end point on curve", () => {
|
|||
let checkB = new freesewing.Point(56, 78);
|
||||
expect(freesewing.utils.pointOnCurve(A, Acp, Bcp, B, checkA)).to.equal(true);
|
||||
expect(freesewing.utils.pointOnCurve(A, Acp, Bcp, B, checkB)).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the intersections of a beam and circle", () => {
|
||||
it("Should find the intersections of a beam and circle", () => {
|
||||
let A = new freesewing.Point(45, 45).attr("data-circle", 35);
|
||||
let B = new freesewing.Point(5, 50);
|
||||
let C = new freesewing.Point(25, 30);
|
||||
|
@ -226,9 +227,9 @@ it("Should find the intersections of a beam and circle", () => {
|
|||
expect(round(intersections[0].y)).to.equal(10);
|
||||
expect(round(intersections[1].x)).to.equal(10);
|
||||
expect(round(intersections[1].y)).to.equal(45);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not find the intersections of this beam and circle", () => {
|
||||
it("Should not find the intersections of this beam and circle", () => {
|
||||
let A = new freesewing.Point(75, 75).attr("data-circle", 35);
|
||||
let B = new freesewing.Point(5, 5);
|
||||
let C = new freesewing.Point(10, 5);
|
||||
|
@ -239,9 +240,9 @@ it("Should not find the intersections of this beam and circle", () => {
|
|||
C
|
||||
);
|
||||
expect(intersections).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find one intersections between this beam and circle", () => {
|
||||
it("Should find one intersections between this beam and circle", () => {
|
||||
let A = new freesewing.Point(5, 5).attr("data-circle", 5);
|
||||
let B = new freesewing.Point(0, 0);
|
||||
let C = new freesewing.Point(-10, 0);
|
||||
|
@ -254,9 +255,9 @@ it("Should find one intersections between this beam and circle", () => {
|
|||
expect(intersections.length).to.equal(1);
|
||||
expect(intersections[0].x).to.equal(5);
|
||||
expect(intersections[0].y).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find one intersections between this tangent and circle", () => {
|
||||
it("Should find one intersections between this tangent and circle", () => {
|
||||
let A = new freesewing.Point(5, 5).attr("data-circle", 5);
|
||||
let B = new freesewing.Point(0, 0);
|
||||
let C = new freesewing.Point(10, 0);
|
||||
|
@ -269,9 +270,9 @@ it("Should find one intersections between this tangent and circle", () => {
|
|||
expect(intersections.length).to.equal(1);
|
||||
expect(intersections[0].x).to.equal(5);
|
||||
expect(intersections[0].y).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find one intersection between this line and circle", () => {
|
||||
it("Should find one intersection between this line and circle", () => {
|
||||
let A = new freesewing.Point(5, 5).attr("data-circle", 5);
|
||||
let B = new freesewing.Point(5, 5);
|
||||
let C = new freesewing.Point(26, 25);
|
||||
|
@ -284,9 +285,9 @@ it("Should find one intersection between this line and circle", () => {
|
|||
expect(intersections.length).to.equal(1);
|
||||
expect(round(intersections[0].x)).to.equal(8.62);
|
||||
expect(round(intersections[0].y)).to.equal(8.45);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not find an intersections between this line and circle", () => {
|
||||
it("Should not find an intersections between this line and circle", () => {
|
||||
let A = new freesewing.Point(5, 5).attr("data-circle", 5);
|
||||
let B = new freesewing.Point(0, 0);
|
||||
let C = new freesewing.Point(-10, 0);
|
||||
|
@ -297,9 +298,9 @@ it("Should not find an intersections between this line and circle", () => {
|
|||
C
|
||||
);
|
||||
expect(intersections).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find two intersections between this line and circle", () => {
|
||||
it("Should find two intersections between this line and circle", () => {
|
||||
let A = new freesewing.Point(6, 7).attr("data-circle", 5);
|
||||
let B = new freesewing.Point(0, 10);
|
||||
let C = new freesewing.Point(10, 0);
|
||||
|
@ -335,9 +336,9 @@ it("Should find two intersections between this line and circle", () => {
|
|||
expect(round(intersections1[0].y)).to.equal(2.3);
|
||||
expect(round(intersections1[1].x)).to.equal(1.3);
|
||||
expect(round(intersections1[1].y)).to.equal(8.7);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find the intersections of a line and circle", () => {
|
||||
it("Should find the intersections of a line and circle", () => {
|
||||
let A = new freesewing.Point(45, 45).attr("data-circle", 35);
|
||||
let B = new freesewing.Point(5, 50);
|
||||
let C = new freesewing.Point(25, 30);
|
||||
|
@ -350,9 +351,9 @@ it("Should find the intersections of a line and circle", () => {
|
|||
expect(intersections.length).to.equal(1);
|
||||
expect(round(intersections[0].x)).to.equal(10);
|
||||
expect(round(intersections[0].y)).to.equal(45);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not find intersections of this line and circle", () => {
|
||||
it("Should not find intersections of this line and circle", () => {
|
||||
let A = new freesewing.Point(75, 75).attr("data-circle", 35);
|
||||
let B = new freesewing.Point(5, 5);
|
||||
let C = new freesewing.Point(10, 5);
|
||||
|
@ -363,9 +364,9 @@ it("Should not find intersections of this line and circle", () => {
|
|||
C
|
||||
);
|
||||
expect(intersections).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not find intersections of this line and circle", () => {
|
||||
it("Should not find intersections of this line and circle", () => {
|
||||
let A = new freesewing.Point(45, 45).attr("data-circle", 35);
|
||||
let B = new freesewing.Point(40, 40);
|
||||
let C = new freesewing.Point(52, 50);
|
||||
|
@ -376,9 +377,9 @@ it("Should not find intersections of this line and circle", () => {
|
|||
C
|
||||
);
|
||||
expect(intersections).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find intersections between circles", () => {
|
||||
it("Should find intersections between circles", () => {
|
||||
let A = new freesewing.Point(10, 10).attr("data-circle", 15);
|
||||
let B = new freesewing.Point(30, 30).attr("data-circle", 35);
|
||||
|
||||
|
@ -405,9 +406,9 @@ it("Should find intersections between circles", () => {
|
|||
expect(round(intersections2[0].y)).to.equal(-2.81);
|
||||
expect(round(intersections2[1].x)).to.equal(-2.81);
|
||||
expect(round(intersections2[1].y)).to.equal(17.81);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not find intersections between non-overlapping circles", () => {
|
||||
it("Should not find intersections between non-overlapping circles", () => {
|
||||
let A = new freesewing.Point(10, 10).attr("data-circle", 15);
|
||||
let B = new freesewing.Point(90, 90).attr("data-circle", 35);
|
||||
|
||||
|
@ -418,9 +419,9 @@ it("Should not find intersections between non-overlapping circles", () => {
|
|||
B.attributes.get("data-circle")
|
||||
);
|
||||
expect(intersections).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not find intersections between contained circles", () => {
|
||||
it("Should not find intersections between contained circles", () => {
|
||||
let A = new freesewing.Point(10, 10).attr("data-circle", 15);
|
||||
let B = new freesewing.Point(10, 10).attr("data-circle", 35);
|
||||
|
||||
|
@ -431,9 +432,9 @@ it("Should not find intersections between contained circles", () => {
|
|||
B.attributes.get("data-circle")
|
||||
);
|
||||
expect(intersections).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not find intersections between identical circles", () => {
|
||||
it("Should not find intersections between identical circles", () => {
|
||||
let A = new freesewing.Point(10, 10).attr("data-circle", 35);
|
||||
let B = new freesewing.Point(10, 10).attr("data-circle", 35);
|
||||
|
||||
|
@ -444,19 +445,19 @@ it("Should not find intersections between identical circles", () => {
|
|||
B.attributes.get("data-circle")
|
||||
);
|
||||
expect(intersections).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return scale for a given amount of stretch", () => {
|
||||
it("Should return scale for a given amount of stretch", () => {
|
||||
expect(freesewing.utils.stretchToScale(0)).to.equal(1);
|
||||
expect(freesewing.utils.stretchToScale(0.25)).to.equal(0.8);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should capitalize a string", () => {
|
||||
it("Should capitalize a string", () => {
|
||||
expect(utils.capitalize("test")).to.equal("Test");
|
||||
expect(utils.capitalize("Freesewing")).to.equal("Freesewing");
|
||||
});
|
||||
});
|
||||
|
||||
it("Should split a curve", () => {
|
||||
it("Should split a curve", () => {
|
||||
let a = new freesewing.Point(0, 0);
|
||||
let b = new freesewing.Point(50, 0);
|
||||
let c = new freesewing.Point(50, 100);
|
||||
|
@ -471,9 +472,9 @@ it("Should split a curve", () => {
|
|||
expect(round(c2.cp1.y)).to.equal(75);
|
||||
expect(round(c2.cp2.x)).to.equal(75);
|
||||
expect(round(c2.cp2.y)).to.equal(100);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find where a curve intersects a given X-value", () => {
|
||||
it("Should find where a curve intersects a given X-value", () => {
|
||||
let a = new freesewing.Point(0, 0);
|
||||
let b = new freesewing.Point(50, 0);
|
||||
let c = new freesewing.Point(50, 100);
|
||||
|
@ -481,9 +482,9 @@ it("Should find where a curve intersects a given X-value", () => {
|
|||
let i = utils.curveIntersectsX(a, b, c, d, 30);
|
||||
expect(round(i.x)).to.equal(30);
|
||||
expect(round(i.y)).to.equal(16);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should find where a curve intersects a given Y-value", () => {
|
||||
it("Should find where a curve intersects a given Y-value", () => {
|
||||
let a = new freesewing.Point(0, 0);
|
||||
let b = new freesewing.Point(50, 0);
|
||||
let c = new freesewing.Point(50, 100);
|
||||
|
@ -491,34 +492,34 @@ it("Should find where a curve intersects a given Y-value", () => {
|
|||
let i = utils.curveIntersectsY(a, b, c, d, 30);
|
||||
expect(round(i.x)).to.equal(39.49);
|
||||
expect(round(i.y)).to.equal(30);
|
||||
});
|
||||
});
|
||||
|
||||
// Recreate issue #1206
|
||||
it("Should find intersecting beams when a line is almost vertical", () => {
|
||||
// Recreate issue #1206
|
||||
it("Should find intersecting beams when a line is almost vertical", () => {
|
||||
let a = new freesewing.Point(225.72, 241);
|
||||
let b = new freesewing.Point(225.71999999999997, 600);
|
||||
let i = utils.beamIntersectsY(a, b, 400);
|
||||
expect(round(i.y)).to.equal(400);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should check for valid coordinate", () => {
|
||||
it("Should check for valid coordinate", () => {
|
||||
expect(utils.isCoord(23423.23)).to.equal(true);
|
||||
expect(utils.isCoord(0)).to.equal(true);
|
||||
expect(utils.isCoord()).to.equal(false);
|
||||
expect(utils.isCoord(null)).to.equal(false);
|
||||
expect(utils.isCoord('hi')).to.equal(false);
|
||||
expect(utils.isCoord(NaN)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return the correct sample style", () => {
|
||||
it("Should return the correct sample style", () => {
|
||||
expect(utils.sampleStyle(0, 5)).to.equal("stroke: hsl(-66, 100%, 35%);")
|
||||
expect(utils.sampleStyle(1, 5)).to.equal("stroke: hsl(0, 100%, 35%);")
|
||||
expect(utils.sampleStyle(2, 5)).to.equal("stroke: hsl(66, 100%, 35%);")
|
||||
expect(utils.sampleStyle(3, 5)).to.equal("stroke: hsl(132, 100%, 35%);")
|
||||
expect(utils.sampleStyle(4, 5)).to.equal("stroke: hsl(198, 100%, 35%);")
|
||||
});
|
||||
});
|
||||
|
||||
it("Should return the correct sample styles", () => {
|
||||
it("Should return the correct sample styles", () => {
|
||||
const styles = [
|
||||
"stroke: red;",
|
||||
"stroke: blue;",
|
||||
|
@ -527,28 +528,28 @@ it("Should return the correct sample styles", () => {
|
|||
"stroke: orange;",
|
||||
]
|
||||
for (let i=0;i<5;i++) expect(utils.sampleStyle(i, 5, styles)).to.equal(styles[i])
|
||||
});
|
||||
});
|
||||
|
||||
it("Should convert degrees to radians", () => {
|
||||
it("Should convert degrees to radians", () => {
|
||||
expect(utils.deg2rad(0)).to.equal(0);
|
||||
expect(round(utils.deg2rad(69))).to.equal(1.2);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should convert radians to degrees", () => {
|
||||
it("Should convert radians to degrees", () => {
|
||||
expect(utils.rad2deg(0)).to.equal(0);
|
||||
expect(round(utils.rad2deg(69))).to.equal(3953.41);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should shoulder return two methods for pctBasedOn", () => {
|
||||
it("Should shoulder return two methods for pctBasedOn", () => {
|
||||
const result = utils.pctBasedOn('chest')
|
||||
expect(typeof result.toAbs).to.equal("function");
|
||||
expect(typeof result.fromAbs).to.equal("function");
|
||||
const measurements = { chest: 1000 }
|
||||
expect(result.toAbs(0.0123, { measurements })).to.equal(12.3)
|
||||
expect(result.fromAbs(12.3, { measurements })).to.equal(0.0123)
|
||||
});
|
||||
});
|
||||
|
||||
it("Should generate a part transform", () => {
|
||||
it("Should generate a part transform", () => {
|
||||
let pattern = new freesewing.Pattern();
|
||||
pattern.settings.mode = "draft";
|
||||
let part = new pattern.Part();
|
||||
|
@ -561,6 +562,7 @@ it("Should generate a part transform", () => {
|
|||
part.stack();
|
||||
const transform = utils.generatePartTransform(30,60,90,true,true,part)
|
||||
expect(transform.transform).to.equal(`translate(${30 + part.topLeft.x + part.bottomRight.x} ${60 + part.topLeft.y + part.bottomRight.y}) scale(-1 -1) rotate(90 ${part.topLeft.x + part.width/2} ${part.topLeft.y + part.height/2})`);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue