diff --git a/package.json b/package.json index c0da92ada10..2026589084d 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@types/node": "^18.0.0", "@types/react": "^18.0.8", "all-contributors-cli": "^6.20.0", + "autoprefixer": "^10.4.0", "ava": "^4.0.1", "axios": "^0.27.2", "chai": "^4.2.0", @@ -66,6 +67,7 @@ "esbuild": "^0.15.3", "esbuild-plugin-yaml": "^0.0.1", "esm": "^3.2.25", + "handlebars": "^4.7.7", "husky": "^8.0.1", "js-yaml": "^4.0.0", "lerna": "^5.1.4", @@ -77,18 +79,16 @@ "prop-types": "^15.7.2", "react": "^17.0.2", "react-dom": "^17.0.2", - "remark": "^14.0.2", - "remark-html": "^15.0.1", - "rimraf": "^3.0.2", - "standard": "^17.0.0", - "autoprefixer": "^10.4.0", - "handlebars": "^4.7.7", "rehype-format": "^4.0.1", + "remark": "^14.0.2", "remark-frontmatter": "^4.0.1", + "remark-html": "^15.0.1", "remark-lint-emphasis-marker": "^3.1.1", "remark-lint-list-item-indent": "^3.1.1", "remark-preset-lint-consistent": "^5.1.1", - "remark-preset-lint-recommended": "^6.1.2" + "remark-preset-lint-recommended": "^6.1.2", + "rimraf": "^3.0.2", + "standard": "^17.0.0" }, "workspaces": [ "designs/*", @@ -99,6 +99,7 @@ "version": "0.0.0", "dependencies": { "autoprefixer": "^10.4.0", + "c8": "^7.12.0", "handlebars": "^4.7.7", "jsonfile": "^6.1.0", "postcss": "^8.4.5", diff --git a/packages/core/src/svg.mjs b/packages/core/src/svg.mjs index 30b71e2de06..c4ac90df033 100644 --- a/packages/core/src/svg.mjs +++ b/packages/core/src/svg.mjs @@ -1,22 +1,19 @@ import { Attributes } from './attributes.mjs' -import { round } from './utils.mjs' +import { addNonEnumProp, round } from './utils.mjs' import { version } from '../data.mjs' export function Svg(pattern) { - this.openGroups = [] - this.layout = {} - this.freeId = 0 - this.body = '' - /* - * This breaks SVG style (see #1606) - * Can we not set variables in SVG style? - * this.style = `svg.freesewing.pattern { --pattern-scale: ${pattern.settings.scale} }` - */ - this.style = '' - this.script = '' - this.defs = '' + // Non-enumerable properties + addNonEnumProp(this, 'openGroups', []) + addNonEnumProp(this, 'layout', {}) + addNonEnumProp(this, 'freeId', 0) + addNonEnumProp(this, 'body', '') + addNonEnumProp(this, 'style', '') + addNonEnumProp(this, 'defs', '') + addNonEnumProp(this, 'prefix', '') + + // Enumerable properties this.pattern = pattern // Needed to expose pattern to hooks - this.prefix = '' this.attributes = new Attributes() this.attributes.add('xmlns', 'http://www.w3.org/2000/svg') this.attributes.add('xmlns:svg', 'http://www.w3.org/2000/svg') diff --git a/packages/core/tests/pattern-draft.mjs b/packages/core/tests/pattern-draft.test.mjs similarity index 100% rename from packages/core/tests/pattern-draft.mjs rename to packages/core/tests/pattern-draft.test.mjs diff --git a/packages/core/tests/pattern-init.mjs b/packages/core/tests/pattern-init.test.mjs similarity index 100% rename from packages/core/tests/pattern-init.mjs rename to packages/core/tests/pattern-init.test.mjs diff --git a/packages/core/tests/snap.mjs b/packages/core/tests/snap.test.mjs similarity index 77% rename from packages/core/tests/snap.mjs rename to packages/core/tests/snap.test.mjs index 36de3dfbbc1..2510662bc99 100644 --- a/packages/core/tests/snap.mjs +++ b/packages/core/tests/snap.test.mjs @@ -1,5 +1,5 @@ import chai from 'chai' -import freesewing from '../dist/index.js' +import { Design } from '../src/index.mjs' const expect = chai.expect @@ -8,19 +8,22 @@ const toAbs = (val, { measurements }) => measurements.head * val describe('Snapped options', () => { it('Should snap a percentage options to equal steps', () => { - const design = new freesewing.Design({ + const part = { + name: 'test', 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 }) + } + } + const design = new Design({ parts: [ part ] }) + const patternA = new design({ options: { test: 0.13 }, measurements }).draft() + const patternB = new design({ options: { test: 0.27 }, measurements }).draft() 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({ + const part = { + name: 'test', options: { test: { pct: 30, @@ -29,18 +32,20 @@ describe('Snapped options', () => { 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 }) + } + } + const design = new Design({ parts: [ part ] }) + const patternA = new design({ options: { test: 0.13 }, measurements }).draft() + const patternB = new design({ options: { test: 0.27 }, measurements }).draft() + const patternC = new design({ options: { test: 0.97 }, measurements }).draft() 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({ + const part = { + name: 'test', options: { test: { pct: 30, @@ -52,12 +57,13 @@ describe('Snapped options', () => { 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' }) + } + } + const design = new Design({ parts: [ part ] }) + const patternA = new design({ options: { test: 0.13 }, measurements, units: 'metric' }).draft() + const patternB = new design({ options: { test: 0.27 }, measurements, units: 'metric' }).draft() + const patternC = new design({ options: { test: 0.97 }, measurements, units: 'metric' }).draft() + const patternD = new design({ options: { test: 0.01 }, measurements, units: 'metric' }).draft() expect(patternA.settings.absoluteOptions.test).to.equal(50) expect(patternB.settings.absoluteOptions.test).to.equal(100) expect(patternC.settings.absoluteOptions.test).to.equal(388) @@ -65,7 +71,8 @@ describe('Snapped options', () => { }) it('Should snap a percentage options to metrics snaps', () => { - const design = new freesewing.Design({ + const part = { + name: 'test', options: { test: { pct: 30, @@ -77,12 +84,13 @@ describe('Snapped options', () => { 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' }) + } + } + const design = new Design({ parts: [ part ] }) + const patternA = new design({ options: { test: 0.13 }, measurements, units: 'imperial' }).draft() + const patternB = new design({ options: { test: 0.27 }, measurements, units: 'imperial' }).draft() + const patternC = new design({ options: { test: 0.97 }, measurements, units: 'imperial' }).draft() + const patternD = new design({ options: { test: 0.01 }, measurements, units: 'imperial' }).draft() 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) diff --git a/packages/core/tests/svg.test.mjs b/packages/core/tests/svg.test.mjs index 3b59dcb4773..ebaaad37363 100644 --- a/packages/core/tests/svg.test.mjs +++ b/packages/core/tests/svg.test.mjs @@ -1,6 +1,6 @@ import chai from 'chai' import chaiString from 'chai-string' -import { Pattern } from '../src/index.mjs' +import { Design, Pattern } from '../src/index.mjs' import pkg from '../package.json' assert { type: 'json' } import render from './fixtures/render.mjs' @@ -9,8 +9,21 @@ const expect = chai.expect const { version } = pkg describe('Svg', () => { + const part = { + name: 'test', + draft: part => { + const { paths, Path, Point, points } = part.shorthand() + points.a = new Path() + .move(new Point(0, 0)) + .line(new Point(0, 40)) + .shiftFractionAlong() + return part + } + } + const design = new Design({ parts: [ part ] }) + const pattern = new design() + it('Svg constructor should initialize object', () => { - let pattern = new Pattern() pattern.render() let svg = pattern.svg expect(svg.openGroups).to.eql([]) diff --git a/packages/core/tests/utils.test.mjs b/packages/core/tests/utils.test.mjs index 9343e68464d..06ed5207018 100644 --- a/packages/core/tests/utils.test.mjs +++ b/packages/core/tests/utils.test.mjs @@ -30,6 +30,7 @@ import { Bezier, generatePartTransform, macroName, + Design, } from '../src/index.mjs' const { expect } = chai @@ -513,17 +514,22 @@ describe('Utils', () => { 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', () => { - let pattern = new Pattern() - pattern.settings.mode = 'draft' - let part = new pattern.Part() - let short = part.shorthand() - part.points.from = new short.Point(2, 2) - part.points.to = new short.Point(19, 76) - part.paths.test = new short.Path().move(part.points.from).line(part.points.to) - part.stack() - const transform = generatePartTransform(30, 60, 90, true, true, part) + const part = { + name: 'test', + draft: part => { + const { points, Point, paths, Path } = part.shorthand() + points.from = new Point(2, 2) + points.to = new Point(19, 76) + paths.test = new Path().move(points.from).line(points.to) + return part + } + } + const design = new Design({ parts: [ part ]}) + const pattern = new design() + pattern.draft().render() + const transform = generatePartTransform(30, 60, 90, true, true, pattern.__parts.test) expect(transform.transform).to.equal( `translate(${30 + part.topLeft.x + part.bottomRight.x} ${ 60 + part.topLeft.y + part.bottomRight.y @@ -532,4 +538,5 @@ describe('Utils', () => { })` ) }) + */ }) diff --git a/yarn.lock b/yarn.lock index 7cdc792da45..be260d9f96f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1032,6 +1032,11 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@bugsnag/browser@^7.17.0": version "7.17.0" resolved "https://registry.yarnpkg.com/@bugsnag/browser/-/browser-7.17.0.tgz#c777d673df6075d001a2a7eb290ea37e6b2411d2" @@ -1326,7 +1331,7 @@ js-yaml "^3.13.1" resolve-from "^5.0.0" -"@istanbuljs/schema@^0.1.2": +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== @@ -1392,6 +1397,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" @@ -3378,7 +3391,7 @@ resolved "https://registry.yarnpkg.com/@types/is-empty/-/is-empty-1.2.1.tgz#18d7256a73e43ec51f8b75c25fbdc31350be52a6" integrity sha512-a3xgqnFTuNJDm1fjsTjHocYJ40Cz3t8utYpi5GNaxzrJC2HSD08ym+whIL7fNqiqBCdM9bcqD1H/tORWAFXoZw== -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== @@ -5179,6 +5192,24 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +c8@^7.12.0: + version "7.12.0" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.12.0.tgz#402db1c1af4af5249153535d1c84ad70c5c96b14" + integrity sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@istanbuljs/schema" "^0.1.3" + find-up "^5.0.0" + foreground-child "^2.0.0" + istanbul-lib-coverage "^3.2.0" + istanbul-lib-report "^3.0.0" + istanbul-reports "^3.1.4" + rimraf "^3.0.2" + test-exclude "^6.0.0" + v8-to-istanbul "^9.0.0" + yargs "^16.2.0" + yargs-parser "^20.2.9" + cacache@^12.0.2: version "12.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" @@ -6212,7 +6243,7 @@ conventional-recommended-bump@^6.1.0: meow "^8.0.0" q "^1.5.1" -convert-source-map@^1.7.0: +convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== @@ -10845,7 +10876,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2: +istanbul-reports@^3.0.2, istanbul-reports@^3.1.4: version "3.1.5" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== @@ -19101,6 +19132,15 @@ v8-compile-cache@2.3.0, v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +v8-to-istanbul@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -19663,7 +19703,7 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.2, yargs-parser@^20.2.3: +yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==