diff --git a/config/dependencies.yaml b/config/dependencies.yaml index d9d7109c0da..b991c64b10e 100644 --- a/config/dependencies.yaml +++ b/config/dependencies.yaml @@ -62,6 +62,9 @@ core: dev: 'eslint': &eslint '8.34.0' 'nyc': '15.1.0' + 'mocha': *mocha + 'chai': *chai + 'sinon': &sinon '^15.0.1' diana: peer: '@freesewing/brian': *freesewing diff --git a/packages/core/package.json b/packages/core/package.json index e6ff0e2940f..bb3a265071c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -60,7 +60,10 @@ }, "devDependencies": { "eslint": "8.34.0", - "nyc": "15.1.0" + "nyc": "15.1.0", + "mocha": "10.0.0", + "chai": "4.2.0", + "sinon": "^15.0.1" }, "files": [ "dist/*", diff --git a/packages/core/src/pattern-draft-queue.mjs b/packages/core/src/pattern-draft-queue.mjs index db8355459a4..30014d57f42 100644 --- a/packages/core/src/pattern-draft-queue.mjs +++ b/packages/core/src/pattern-draft-queue.mjs @@ -9,7 +9,7 @@ PatternDraftQueue.prototype.start = function () { } PatternDraftQueue.prototype.addPart = function (partName) { - this.queue.push(partName) + if (!this.contains(partName)) this.queue.push(partName) return this } @@ -27,6 +27,10 @@ PatternDraftQueue.prototype.next = function () { return next } +PatternDraftQueue.prototype.contains = function (partName) { + return this.queue.indexOf(partName) !== -1 +} + /** * Resolves the draft order based on the configuation * diff --git a/packages/core/src/pattern.mjs b/packages/core/src/pattern.mjs index 33b260007c7..5eefc19056f 100644 --- a/packages/core/src/pattern.mjs +++ b/packages/core/src/pattern.mjs @@ -67,8 +67,11 @@ export function Pattern(designConfig = {}) { * It might be useful to not resolve immediately if a number of parts will be added over multiple calls * @return {object} this - The Pattern instance */ -Pattern.prototype.addPart = function (part, resolveImmediately = false) { - if (this.__configResolver.isPartValid(part) && this.designConfig.parts.indexOf(part) === -1) { +Pattern.prototype.addPart = function (part, resolveImmediately = true) { + if ( + this.__configResolver.isPartValid(part) && + !this.designConfig.parts.find((p) => p.name == part.name) + ) { this.designConfig.parts.push(part) if (resolveImmediately) { if (this.__configResolver.addPart(part) && typeof this.draftQueue !== 'undefined') diff --git a/packages/core/tests/pattern-runtime-parts.test.mjs b/packages/core/tests/pattern-runtime-parts.test.mjs index 4d8587b1142..f272afcf495 100644 --- a/packages/core/tests/pattern-runtime-parts.test.mjs +++ b/packages/core/tests/pattern-runtime-parts.test.mjs @@ -1,5 +1,6 @@ import chai from 'chai' import { Design } from '../src/index.mjs' +import sinon from 'sinon' const expect = chai.expect @@ -22,11 +23,6 @@ describe('Pattern', () => { draft: ({ part }) => part, } - describe('with runtime: true, resolveImmediately: true', () => { - it('adds the part to the current draft cycle') - it('does not add the part to subsequent draft cycles') - }) - describe('with resolveImmediately: true', () => { it('Should add the part to parts object', () => { const design = new Design({ parts: [part1] }) @@ -152,6 +148,51 @@ describe('Pattern', () => { pattern.addPart(part3, true) expect(pattern.config.options.opt1).to.equal(opt1) }) + + describe('during drafting', () => { + it('adds the part to the draft queue', () => { + const design = new Design({ parts: [part1] }) + const pattern = new design() + pattern.use({ + name: 'draftTimePartPlugin', + hooks: { + postPartDraft: (pattern) => { + const newPart = { + name: 'newPartTest', + draft: ({ part }) => part, + } + + pattern.addPart(newPart) + }, + }, + }) + + pattern.draft() + expect(pattern.draftQueue.contains('newPartTest')).to.be.true + }) + it('drafts the part', () => { + const design = new Design({ parts: [part1] }) + const pattern = new design() + const part2Draft = ({ part }) => part + const draftSpy = sinon.spy(part2Draft) + pattern.use({ + name: 'draftTimePartPlugin', + hooks: { + postPartDraft: (pattern) => { + const newPart = { + name: 'newPartTest', + draft: draftSpy, + } + + pattern.addPart(newPart) + }, + }, + }) + + pattern.draft() + expect(draftSpy.calledOnce).to.be.true + }) + }) }) describe('with resolveImmediately: false', () => { diff --git a/yarn.lock b/yarn.lock index ef9769e133b..ca701533563 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4750,6 +4750,34 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@10.0.2", "@sinonjs/fake-timers@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== + dependencies: + "@sinonjs/commons" "^2.0.0" + +"@sinonjs/samsam@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-7.0.1.tgz#5b5fa31c554636f78308439d220986b9523fc51f" + integrity sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw== + dependencies: + "@sinonjs/commons" "^2.0.0" + lodash.get "^4.4.2" + type-detect "^4.0.8" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" + integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== + "@socket.io/component-emitter@~3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" @@ -12259,6 +12287,11 @@ just-diff@^5.0.1: resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-5.0.3.tgz#4c9c514dec5526b25ab977590e3c39a0cf271554" integrity sha512-a8p80xcpJ6sdurk5PxDKb4mav9MeKjA3zFKZpCWBIfvg8mznfnmb13MKZvlrwJ+Lhis0wM3uGAzE0ArhFHvIcg== +just-extend@^4.0.2: + version "4.2.1" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" + integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== + jwa@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" @@ -14337,6 +14370,17 @@ next@13.1.6: "@next/swc-win32-ia32-msvc" "13.1.6" "@next/swc-win32-x64-msvc" "13.1.6" +nise@^5.1.2: + version "5.1.4" + resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.4.tgz#491ce7e7307d4ec546f5a659b2efe94a18b4bbc0" + integrity sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg== + dependencies: + "@sinonjs/commons" "^2.0.0" + "@sinonjs/fake-timers" "^10.0.2" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + path-to-regexp "^1.7.0" + nlcst-to-string@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/nlcst-to-string/-/nlcst-to-string-2.0.4.tgz#9315dfab80882bbfd86ddf1b706f53622dc400cc" @@ -15535,6 +15579,13 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -18346,6 +18397,18 @@ simple-wcswidth@^1.0.1: resolved "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.0.1.tgz#8ab18ac0ae342f9d9b629604e54d2aa1ecb018b2" integrity sha512-xMO/8eNREtaROt7tJvWJqHBDTMFN4eiQ5I4JRMuilwfnFcV5W9u7RUkueNkdw0jPqGMX36iCywelS5yilTuOxg== +sinon@^15.0.1: + version "15.0.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-15.0.1.tgz#ce062611a0b131892e2c18f03055b8eb6e8dc234" + integrity sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg== + dependencies: + "@sinonjs/commons" "^2.0.0" + "@sinonjs/fake-timers" "10.0.2" + "@sinonjs/samsam" "^7.0.1" + diff "^5.0.0" + nise "^5.1.2" + supports-color "^7.2.0" + sirv@^1.0.7: version "1.0.19" resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" @@ -19131,7 +19194,7 @@ supports-color@^5.3.0, supports-color@^5.5.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -19650,7 +19713,7 @@ type-component@0.0.1: resolved "https://registry.yarnpkg.com/type-component/-/type-component-0.0.1.tgz#952a6c81c21efd24d13d811d0c8498cb860e1956" integrity sha512-mDZRBQS2yZkwRQKfjJvQ8UIYJeBNNWCq+HBNstl9N5s9jZ4dkVYXEGkVPsSCEh5Ld4JM1kmrZTzjnrqSAIQ7dw== -type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==