From cc51b60d815f3226b0b7340603130df970325a32 Mon Sep 17 00:00:00 2001 From: Sergey Berezhnoy Date: Wed, 18 Sep 2013 14:52:23 +0400 Subject: [PATCH 1/5] close #459: deps: possibility to declare dependence without explicit including item --- lib/techs/deps.js.js | 22 +++++++++++------- test/deps.js | 55 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/lib/techs/deps.js.js b/lib/techs/deps.js.js index ae9a3bb3..ddad62bb 100644 --- a/lib/techs/deps.js.js +++ b/lib/techs/deps.js.js @@ -90,10 +90,14 @@ var Deps = exports.Deps = INHERIT({ add: function(target, depsType, item) { var items = this.items, targetKey = target.buildKey(), - itemKey = item.buildKey(); + itemKey = item.buildKey(), + itemByKey = items[itemKey]; - if(!items[itemKey]) { + if(!itemByKey) { items[itemKey] = item; + item.include && this.itemsByOrder.push(itemKey); + } else if(!itemByKey.include && item.include) { + itemByKey.include = true; this.itemsByOrder.push(itemKey); } @@ -300,11 +304,13 @@ var Deps = exports.Deps = INHERIT({ var key = i.buildKey(), ctxTech = ctx && ctx.item.tech || ''; if(!uniq.hasOwnProperty(key) || !uniq[key].hasOwnProperty(ctxTech)) { - (uniq[key] || (uniq[key] = {}))[ctxTech] = true; - var newCtx = ctx || i; - _this.forEach(fn, uniq, i.mustDeps, newCtx); - fn.call(_this, i, newCtx); - _this.forEach(fn, uniq, i.shouldDeps, newCtx); + if(i.include) { + (uniq[key] || (uniq[key] = {}))[ctxTech] = true; + var newCtx = ctx || i; + _this.forEach(fn, uniq, i.mustDeps, newCtx); + fn.call(_this, i, newCtx); + _this.forEach(fn, uniq, i.shouldDeps, newCtx); + } } } }); @@ -364,7 +370,7 @@ var DepsItem = exports.DepsItem = INHERIT({ this.item = {}; this.extendByCtx({ item: item }); this.extendByCtx(ctx); - + this.include = item.include !== false; }, extendByCtx: function(ctx) { diff --git a/test/deps.js b/test/deps.js index 8b61ec7b..8b4cb95a 100644 --- a/test/deps.js +++ b/test/deps.js @@ -181,6 +181,29 @@ describe('Deps', function() { }); + describe('include: false', function() { + + it('block', assertDepsParse( + [ + { + block: 'b1', + shouldDeps: [ + { block: 'b2', include: false }, + { block: 'b3', include: false } + ], + mustDeps: [ + { block: 'b4', include: false }, + { block: 'b5', include: false } + ] + }, + { block: 'b3' }, + { block: 'b4' } + ], + { '': { '': [ { block: 'b4' }, { block: 'b1' }, { block: 'b3' } ] } } + )); + + }); + }); describe('serialize:', function() { @@ -205,9 +228,13 @@ describe('Deps', function() { describe('clone', function() { - var deps1 = new Deps().parse([{ block: 'b1', bla: 1 }, 'b2']), - deps2 = deps1.clone(), + var deps1, deps2, deps; + + beforeEach(function(){ + deps1 = new Deps().parse([{ block: 'b1', bla: 1 }, 'b2']); + deps2 = deps1.clone(); deps = [deps1, deps2]; + }); it('.items', function() { assert.deepEqual(deps[1].items, deps[0].items); @@ -221,24 +248,28 @@ describe('Deps', function() { describe('subtract', function() { - var deps1 = new DEPS.Deps().parse([ + var deps1, deps2, deps3; + + beforeEach(function() { + deps1 = new DEPS.Deps().parse([ { block: 'b1' }, { block: 'b2' }, { block: 'b3' }, { block: 'b5' } - ]), + ]); deps2 = new DEPS.Deps().parse([ { block: 'b1' }, { block: 'b3' }, { block: 'b4' } - ]), + ]); deps3 = new DEPS.Deps().parse([ { block: 'b5' } ]); - deps1.subtract(deps2).subtract(deps3); + deps1.subtract(deps2).subtract(deps3); + }); it('works correctly', function() { assert.deepEqual(deps1.serialize(), { @@ -252,18 +283,21 @@ describe('Deps', function() { describe('intersect', function() { - var deps1 = new DEPS.Deps().parse([ + var deps1, deps2, deps3; + + beforeEach(function() { + deps1 = new DEPS.Deps().parse([ { block: 'b1' }, { block: 'b2' }, { block: 'b3' }, { block: 'b5' } - ]), + ]); deps2 = new DEPS.Deps().parse([ { block: 'b3' }, { block: 'b1' }, { block: 'b4' } - ]), + ]); deps3 = new DEPS.Deps().parse([ { block: 'b3' }, @@ -271,7 +305,8 @@ describe('Deps', function() { { block: 'b1' } ]); - deps1.intersect(deps2).intersect(deps3); + deps1.intersect(deps2).intersect(deps3); + }); it('works correctly', function() { assert.deepEqual(deps1.serialize(), { From 028778c29243531eccf4d5f2a40dec375f81fb11 Mon Sep 17 00:00:00 2001 From: Dmitry Filatov Date: Wed, 18 Sep 2013 16:46:59 +0400 Subject: [PATCH 2/5] port to v2 --- lib/techs/v2/deps.js.js | 21 ++- test/v2-deps.js | 390 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 404 insertions(+), 7 deletions(-) create mode 100644 test/v2-deps.js diff --git a/lib/techs/v2/deps.js.js b/lib/techs/v2/deps.js.js index 6f698fd0..9d35c74d 100644 --- a/lib/techs/v2/deps.js.js +++ b/lib/techs/v2/deps.js.js @@ -186,10 +186,14 @@ var Deps = exports.Deps = INHERIT({ add: function(target, depsType, item) { var items = this.items, targetKey = target.buildKey(), - itemKey = item.buildKey(); + itemKey = item.buildKey(), + itemByKey = items[itemKey]; - if(!items[itemKey]) { + if(!itemByKey) { items[itemKey] = item; + item.include && this.itemsByOrder.push(itemKey); + } else if(!itemByKey.include && item.include) { + itemByKey.include = true; this.itemsByOrder.push(itemKey); } @@ -414,11 +418,13 @@ var Deps = exports.Deps = INHERIT({ var key = i.buildKey(), ctxTech = ctx && ctx.item.tech || ''; if(!uniq.hasOwnProperty(key) || !uniq[key].hasOwnProperty(ctxTech)) { - (uniq[key] || (uniq[key] = {}))[ctxTech] = true; - var newCtx = ctx || i; - _this.forEach(fn, uniq, i.mustDeps, newCtx); - fn.call(_this, i, newCtx); - _this.forEach(fn, uniq, i.shouldDeps, newCtx); + if(i.include) { + (uniq[key] || (uniq[key] = {}))[ctxTech] = true; + var newCtx = ctx || i; + _this.forEach(fn, uniq, i.mustDeps, newCtx); + fn.call(_this, i, newCtx); + _this.forEach(fn, uniq, i.shouldDeps, newCtx); + } } } }); @@ -478,6 +484,7 @@ var DepsItem = exports.DepsItem = INHERIT({ this.item = {}; this.extendByCtx({ item: item }); this.extendByCtx(ctx); + this.include = item.include !== false; }, extendByCtx: function(ctx) { diff --git a/test/v2-deps.js b/test/v2-deps.js new file mode 100644 index 00000000..4e5c76ea --- /dev/null +++ b/test/v2-deps.js @@ -0,0 +1,390 @@ +'use strict'; + +var assert = require('chai').assert, + DEPS = require('..').require('./techs/v2/deps.js.js'), + Deps = DEPS.Deps, + DepsItem = DEPS.DepsItem; + +/** + * Mocha BDD interface. + * + * @name describe @function + * @name it @function + * @name before @function + * @name after @function + * @name beforeEach @function + * @name afterEach @function + */ + +function assertDepsParse(deps, expected) { + return function () { + assert.deepEqual(new Deps().parse(deps).serialize(), expected); + }; +} + +function assertBuildKey(item, expected) { + return function () { + assert.equal(new DepsItem(item).buildKey(), expected); + }; +} + +describe('Deps', function() { + + describe('parsing:', function() { + + describe('old format with names', function() { + + it('block', assertDepsParse( + [ { name: 'b1' } ], + { '': { '': [ { block: 'b1' } ] } } + )); + + it('block with elem', assertDepsParse( + [ { name: 'b1', elems: [ { name: 'e1' } ] } ], + { '': { '': [ { block: 'b1' }, { block: 'b1', elem: 'e1' } ] } } + )); + + it('block with elem with mods with vals', assertDepsParse( + [ + { name: 'b1', elems: [ + { name: 'e1', mods: [ + { name: 'm1', vals: [ 'v1', 'v2' ] } ] } ] } + ], + { '': { '': [ + { block: 'b1' }, + { block: 'b1', elem: 'e1' }, + { block: 'b1', elem: 'e1', mod: 'm1' }, + { block: 'b1', elem: 'e1', mod: 'm1', val: 'v1' }, + { block: 'b1', elem: 'e1', mod: 'm1', val: 'v2' } + ] } } + )); + + it('block with mods with vals and with elems', assertDepsParse( + [ { name: 'b1', + elems: [ 'e1', 'e2' ], + mods: [ + { name: 'm1', val: 'v1' }, + { name: 'm2', val: 'v2' } + ] + } ], + { '': { '': [ + { block: 'b1' }, + { block: 'b1', elem: 'e1' }, + { block: 'b1', elem: 'e2' }, + { block: 'b1', mod: 'm1', val: 'v1' }, + { block: 'b1', mod: 'm2', val: 'v2' } + ] } } + )); + + }); + + describe('new format', function() { + + it('block', assertDepsParse( + [ { block: 'b1' } ], + { '': { '': [ { block: 'b1' } ] } } + )); + + it('elem', assertDepsParse( + [ { block: 'b1', elem: 'e1' } ], + { '': { '': [ { block: 'b1', elem: 'e1' } ] } } + )); + + it('block with shouldDeps and mustDeps', assertDepsParse( + [ { block: 'b1', shouldDeps: [ { block: 'b2', mustDeps: 'b3' }, 'b3' ] } ], + { '': { '': [ { block: 'b1' }, { block: 'b3' }, { block: 'b2' } ] } } + )); + + it('simple blocks', assertDepsParse( + [ 'b1', 'b2' ], + { '': { '': [ { block: 'b1' }, { block: 'b2' } ] } } + )); + + it('block with elems', assertDepsParse( + [ { block: 'b1', elems: [ 'e1', 'e2' ] } ], + { '': { '': [ + {block: 'b1'}, + {block: 'b1', elem: 'e1'}, + {block: 'b1', elem: 'e2'}, + ] } } + )); + + // TODO: https://github.com/bem/bem-tools/issues/401 + xit('block with elem array', assertDepsParse( + [ { block: 'b1', elem: ['e1', 'e2'] } ], + { '': {'': [ + {block: 'b1', elem: 'e1'}, + {block: 'b1', elem: 'e2'} + ] } } + )); + + }); + + describe('new format with techs', function() { + + it('block', assertDepsParse( + [ { tech: 't1', block: 'b1' } ], + { 't1': { 't1': [ { tech: 't1', block: 'b1' } ] } } + )); + + it('elem', assertDepsParse( + [ { block: 'b1', elem: 'e1' } ], + { '': { '': [ { block: 'b1', elem: 'e1' } ] } } + )); + + it('block with tech', assertDepsParse( + { block: 'b1', tech: 't1', shouldDeps: [ 'b2', 'b3' ], mustDeps: [ 'b0', 'b4' ] }, + { 't1': { 't1': [ + { block: 'b0', tech: 't1' }, + { block: 'b4', tech: 't1' }, + { block: 'b1', tech: 't1' }, + { block: 'b2', tech: 't1' }, + { block: 'b3', tech: 't1' } + ] } } + )); + + it('block with techs', assertDepsParse( + { block: 'b1', tech: 't1', shouldDeps: { block: 'b2', tech: 't2' } }, + { 't1': { + 't1': [ { block: 'b1', tech: 't1' } ], + 't2': [ { block: 'b2', tech: 't2' } ] + } } + )); + + // TODO: https://github.com/bem/bem-tools/issues/413 + xit('block with tech shortcut', assertDepsParse( + {block: 'b1', tech: 't1', shouldDeps: {tech: 't2'}}, + { 't1': { + 't1': [ { block: 'b1', tech: 't1'} ], + 't2': [ { block: 'b1', tech: 't2'} ] + } + } + )); + + it('block with and without tech', assertDepsParse( + { block: 'b1', shouldDeps: { block: 'b2', tech: 't2', shouldDeps: { block: 'b3' } } }, + { '': { + '': [ { block: 'b1' } ], + 't2': [ { block: 'b2', tech: 't2' }, { block: 'b3', tech: 't2' } ] + } } + )); + + }); + + describe('noDeps', function() { + + it('block', assertDepsParse( + [ + { block: 'b1', shouldDeps: [ 'b2', 'b3' ], mustDeps: [ 'b0', 'b4' ] }, + { block: 'b1', noDeps: ['b2', 'b4'] } + ], + { '': { '': [ { block: 'b0' }, { block: 'b1' }, { block: 'b3' } ] } } + )); + + }); + + describe('include: false', function() { + + it('block', assertDepsParse( + [ + { + block: 'b1', + shouldDeps: [ + { block: 'b2', include: false }, + { block: 'b3', include: false } + ], + mustDeps: [ + { block: 'b4', include: false }, + { block: 'b5', include: false } + ] + }, + { block: 'b3' }, + { block: 'b4' } + ], + { '': { '': [ { block: 'b4' }, { block: 'b1' }, { block: 'b3' } ] } } + )); + + }); + + }); + + describe('serialize:', function() { + + describe('empty deps serialize to {}', function() { + + var empty = {}; + + it('empty deps object: new Deps()', function() { + assert.deepEqual(new Deps().serialize(), empty); + }); + + it('empty object: {}', assertDepsParse({}, empty)); + + it('empty array: []', assertDepsParse([], empty)); + + it('undefined', assertDepsParse(undefined, empty)); + + }); + + }); + + describe('clone', function() { + + var deps1, deps2, deps; + + beforeEach(function(){ + deps1 = new Deps().parse([{ block: 'b1', bla: 1 }, 'b2']); + deps2 = deps1.clone(); + deps = [deps1, deps2]; + }); + + it('.items', function() { + assert.deepEqual(deps[1].items, deps[0].items); + }); + + it('.itemsByOrder', function() { + assert.deepEqual(deps[1].itemsByOrder, deps[0].itemsByOrder); + }); + + }); + + describe('subtract', function() { + + var deps1, deps2, deps3; + + beforeEach(function() { + deps1 = new DEPS.Deps().parse([ + { block: 'b1' }, + { block: 'b2' }, + { block: 'b3' }, + { block: 'b5' } + ]); + + deps2 = new DEPS.Deps().parse([ + { block: 'b1' }, + { block: 'b3' }, + { block: 'b4' } + ]); + + deps3 = new DEPS.Deps().parse([ + { block: 'b5' } + ]); + + deps1.subtract(deps2).subtract(deps3); + }); + + it('works correctly', function() { + assert.deepEqual(deps1.serialize(), { + '': { + '': [ { block: 'b2' } ] + } + }); + }); + + }); + + describe('intersect', function() { + + var deps1, deps2, deps3; + + beforeEach(function() { + deps1 = new DEPS.Deps().parse([ + { block: 'b1' }, + { block: 'b2' }, + { block: 'b3' }, + { block: 'b5' } + ]); + + deps2 = new DEPS.Deps().parse([ + { block: 'b3' }, + { block: 'b1' }, + { block: 'b4' } + ]); + + deps3 = new DEPS.Deps().parse([ + { block: 'b3' }, + { block: 'b6' }, + { block: 'b1' } + ]); + + deps1.intersect(deps2).intersect(deps3); + }); + + it('works correctly', function() { + assert.deepEqual(deps1.serialize(), { + '': { + '': [ + { block: 'b1' }, + { block: 'b3' } + ] + } + }); + }); + + }); + + describe('DepsItem', function() { + + describe('buildKey', function() { + + it('block without tech', assertBuildKey( + { block: 'b1' }, + 'b1')); + + it('block modifier without tech', assertBuildKey( + { block: 'b1', mod: 'm1' }, + 'b1_m1')); + + it('block modifier value without tech', assertBuildKey( + { block: 'b1', mod: 'm1', val: 'v1' }, + 'b1_m1_v1')); + + it('block element without tech', assertBuildKey( + { block: 'b1', elem: 'e1' }, + 'b1__e1')); + + it('element modifier without tech', assertBuildKey( + { block: 'b1', elem: 'e1', mod: 'm1' }, + 'b1__e1_m1')); + + it('element modifier value without tech', assertBuildKey( + { block: 'b1', elem: 'e1', mod: 'm1', val: 'v1' }, + 'b1__e1_m1_v1')); + + it('block with tech', assertBuildKey( + { tech: 't1', block: 'b1' }, + 'b1.t1')); + + it('block modifier with tech', assertBuildKey( + { tech: 't1', block: 'b1', mod: 'm1' }, + 'b1_m1.t1')); + + it('block modifier value with tech', assertBuildKey( + { tech: 't1', block: 'b1', mod: 'm1', val: 'v1' }, + 'b1_m1_v1.t1')); + + it('block element with tech', assertBuildKey( + { tech: 't1', block: 'b1', elem: 'e1' }, + 'b1__e1.t1')); + + it('element modifier with tech', assertBuildKey( + { tech: 't1', block: 'b1', elem: 'e1', mod: 'm1' }, + 'b1__e1_m1.t1')); + + it('element modifier value with tech', assertBuildKey( + { tech: 't1', block: 'b1', elem: 'e1', mod: 'm1', val: 'v1' }, + 'b1__e1_m1_v1.t1')); + + it('just tech', assertBuildKey( + { tech: 't1' }, + '.t1')); + + it('empty', assertBuildKey( + {}, + '')); + + }); + + }); + +}); From 67461b20da50edaa172c13e1ce0f4d6b36298603 Mon Sep 17 00:00:00 2001 From: Sergey Berezhnoy Date: Wed, 18 Sep 2013 17:02:03 +0400 Subject: [PATCH 3/5] fix jshint tests --- test/v2-deps.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/test/v2-deps.js b/test/v2-deps.js index 4e5c76ea..81df0513 100644 --- a/test/v2-deps.js +++ b/test/v2-deps.js @@ -10,6 +10,7 @@ var assert = require('chai').assert, * * @name describe @function * @name it @function + * @name xit @function * @name before @function * @name after @function * @name beforeEach @function @@ -110,13 +111,13 @@ describe('Deps', function() { )); // TODO: https://github.com/bem/bem-tools/issues/401 - xit('block with elem array', assertDepsParse( - [ { block: 'b1', elem: ['e1', 'e2'] } ], - { '': {'': [ - {block: 'b1', elem: 'e1'}, - {block: 'b1', elem: 'e2'} - ] } } - )); + //xit('block with elem array', assertDepsParse( + //[ { block: 'b1', elem: ['e1', 'e2'] } ], + //{ '': {'': [ + //{block: 'b1', elem: 'e1'}, + //{block: 'b1', elem: 'e2'} + //] } } + //)); }); @@ -152,14 +153,14 @@ describe('Deps', function() { )); // TODO: https://github.com/bem/bem-tools/issues/413 - xit('block with tech shortcut', assertDepsParse( - {block: 'b1', tech: 't1', shouldDeps: {tech: 't2'}}, - { 't1': { - 't1': [ { block: 'b1', tech: 't1'} ], - 't2': [ { block: 'b1', tech: 't2'} ] - } - } - )); + //xit('block with tech shortcut', assertDepsParse( + //{block: 'b1', tech: 't1', shouldDeps: {tech: 't2'}}, + //{ 't1': { + //'t1': [ { block: 'b1', tech: 't1'} ], + //'t2': [ { block: 'b1', tech: 't2'} ] + //} + //} + //)); it('block with and without tech', assertDepsParse( { block: 'b1', shouldDeps: { block: 'b2', tech: 't2', shouldDeps: { block: 'b3' } } }, From 407d1db9ec02824f90ab4a24bd84ad949b2c0746 Mon Sep 17 00:00:00 2001 From: Dmitry Filatov Date: Wed, 25 Sep 2013 17:16:11 +0400 Subject: [PATCH 4/5] add comments, xit -> it.skip --- lib/techs/v2/deps.js.js | 3 ++- test/v2-deps.js | 31 +++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/techs/v2/deps.js.js b/lib/techs/v2/deps.js.js index 9d35c74d..ce7a2ce3 100644 --- a/lib/techs/v2/deps.js.js +++ b/lib/techs/v2/deps.js.js @@ -193,6 +193,7 @@ var Deps = exports.Deps = INHERIT({ items[itemKey] = item; item.include && this.itemsByOrder.push(itemKey); } else if(!itemByKey.include && item.include) { + // update `include` for existing item in case of adding of new item without `include: false` itemByKey.include = true; this.itemsByOrder.push(itemKey); } @@ -418,7 +419,7 @@ var Deps = exports.Deps = INHERIT({ var key = i.buildKey(), ctxTech = ctx && ctx.item.tech || ''; if(!uniq.hasOwnProperty(key) || !uniq[key].hasOwnProperty(ctxTech)) { - if(i.include) { + if(i.include) { // include only items without `include: false` (uniq[key] || (uniq[key] = {}))[ctxTech] = true; var newCtx = ctx || i; _this.forEach(fn, uniq, i.mustDeps, newCtx); diff --git a/test/v2-deps.js b/test/v2-deps.js index 81df0513..d1fedd58 100644 --- a/test/v2-deps.js +++ b/test/v2-deps.js @@ -10,7 +10,6 @@ var assert = require('chai').assert, * * @name describe @function * @name it @function - * @name xit @function * @name before @function * @name after @function * @name beforeEach @function @@ -111,13 +110,13 @@ describe('Deps', function() { )); // TODO: https://github.com/bem/bem-tools/issues/401 - //xit('block with elem array', assertDepsParse( - //[ { block: 'b1', elem: ['e1', 'e2'] } ], - //{ '': {'': [ - //{block: 'b1', elem: 'e1'}, - //{block: 'b1', elem: 'e2'} - //] } } - //)); + it.skip('block with elem array', assertDepsParse( + [ { block: 'b1', elem: ['e1', 'e2'] } ], + { '': {'': [ + {block: 'b1', elem: 'e1'}, + {block: 'b1', elem: 'e2'} + ] } } + )); }); @@ -153,14 +152,14 @@ describe('Deps', function() { )); // TODO: https://github.com/bem/bem-tools/issues/413 - //xit('block with tech shortcut', assertDepsParse( - //{block: 'b1', tech: 't1', shouldDeps: {tech: 't2'}}, - //{ 't1': { - //'t1': [ { block: 'b1', tech: 't1'} ], - //'t2': [ { block: 'b1', tech: 't2'} ] - //} - //} - //)); + it.skip('block with tech shortcut', assertDepsParse( + {block: 'b1', tech: 't1', shouldDeps: {tech: 't2'}}, + { 't1': { + 't1': [ { block: 'b1', tech: 't1'} ], + 't2': [ { block: 'b1', tech: 't2'} ] + } + } + )); it('block with and without tech', assertDepsParse( { block: 'b1', shouldDeps: { block: 'b2', tech: 't2', shouldDeps: { block: 'b3' } } }, From 01b4fb99d8fffdb6dc9d063819b8546d0ab13dd6 Mon Sep 17 00:00:00 2001 From: Sergey Berezhnoy Date: Thu, 26 Sep 2013 16:18:50 +0400 Subject: [PATCH 5/5] comments --- lib/techs/deps.js.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/techs/deps.js.js b/lib/techs/deps.js.js index ddad62bb..7a0e7a50 100644 --- a/lib/techs/deps.js.js +++ b/lib/techs/deps.js.js @@ -97,6 +97,7 @@ var Deps = exports.Deps = INHERIT({ items[itemKey] = item; item.include && this.itemsByOrder.push(itemKey); } else if(!itemByKey.include && item.include) { + // update `include` for existing item in case of adding of new item without `include: false` itemByKey.include = true; this.itemsByOrder.push(itemKey); } @@ -304,7 +305,7 @@ var Deps = exports.Deps = INHERIT({ var key = i.buildKey(), ctxTech = ctx && ctx.item.tech || ''; if(!uniq.hasOwnProperty(key) || !uniq[key].hasOwnProperty(ctxTech)) { - if(i.include) { + if(i.include) { // include only items without `include: false` (uniq[key] || (uniq[key] = {}))[ctxTech] = true; var newCtx = ctx || i; _this.forEach(fn, uniq, i.mustDeps, newCtx);