-
Notifications
You must be signed in to change notification settings - Fork 2
Implement parse method #9
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,25 @@ | ||
| var bemNaming = require('bem-naming'); | ||
| var path = require('path'), | ||
| bemNaming = require('bem-naming'); | ||
|
|
||
| module.exports = { | ||
| path: function(entity, tech, options) { | ||
| options || (options = {}); | ||
| var naming = bemNaming(options.naming); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I think this is not optimal to create the same thing many times per build. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but each level may have its own naming settings There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pass in naming object instead of creating it on each call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| return naming.stringify(entity) + '.' + tech; | ||
| }, | ||
| parse: function(str, options) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. jsdoc |
||
| if (path.basename(str) !== str) { | ||
| return; | ||
| } | ||
|
|
||
| options || (options = {}); | ||
| var naming = bemNaming(options.naming), | ||
| splittedPath = str.split('.'); | ||
|
|
||
| return { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use here BemUnnamedObject? To reduce hidden classes quantity There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WAT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Object like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand profit of such naming so such simple things. Can't we refactor it later when we end up with some name and found real cases for it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, we can.
We decided to call it BemCell or BemCytus for now
https://github.com/bem-sdk/bem-decl/blob/master/lib/normalize.js#L13 |
||
| entity: naming.parse(splittedPath[0]), | ||
| tech: splittedPath.slice(1).join('.') | ||
| }; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,48 @@ module.exports = { | |
| entity.modName ? modFolder : ''); | ||
|
|
||
| return path.join(folder, | ||
| naming.stringify(entity) + '.' + tech); | ||
| naming.stringify(entity) + (tech ? '.' + tech : '')); | ||
| }, | ||
| parse: function(str, options) { | ||
| options || (options = {}); | ||
| var naming = bemNaming(options.naming), | ||
| splittedPath = str.split(path.sep).filter(Boolean), | ||
| file = splittedPath.pop(), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. basename = path.basename(str);There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need mutated |
||
| splittedFile = file.split('.'), | ||
| entity = naming.parse(splittedFile[0]), | ||
| tech = splittedFile.slice(1).join('.'); | ||
|
|
||
| // support for paths without filename, e.g. 'b1/__e1/' | ||
| if (!entity) { | ||
| entity = naming.parse(splittedPath.join('') + splittedFile[0]); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what exactly confuses you? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we should parse directories as entities? Any real life case for that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cd level1/b1/__e1
bem create _m1_v1.css # b1__e1_m1_v1.cssThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice catch 👍 |
||
| } | ||
|
|
||
| if (splittedPath.length && entity.block !== splittedPath[0]) { | ||
| return; | ||
| } | ||
|
|
||
| // check if path is valid | ||
| for (var i = 1; i < splittedPath.length; i++) { | ||
| var chunk = splittedPath[i]; | ||
|
|
||
| // __e1 or _m1 | ||
| if (i === 1 && | ||
| (chunk.indexOf(naming.elemDelim) !== 0 && | ||
| chunk.indexOf(naming.modDelim) !== 0) | ||
| ) { return; } | ||
|
|
||
| // __e1/_m1 | ||
| if (i === 2 && | ||
| (splittedPath[i - 1].indexOf(naming.elemDelim) !== 0 || | ||
| chunk.indexOf(naming.modDelim) !== 0) | ||
| ) { return; } | ||
|
|
||
| if (i > 2) { return; } | ||
| } | ||
|
|
||
| return { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. result should be bem-cell |
||
| entity: entity, | ||
| tech: tech | ||
| }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my implementation: function parseBemPath(filePath) {
const filePath_ = path.normalize(filePath);
const cell = _parseComplexBemPath(filePath_); // With directories-technologies
// null is a signal 'incorrect cell found'
return cell || cell !== null && _parseSimpleBemPath(filePath_) || null;
}function _parseComplexBemPath(filePath) {
const chunks = filePath.split(path.sep);
const block = chunks[1];
const secondChunk = splitAtFirst(chunks[2], '.'); // E.g. ['suggest2', 'priv.js']
if(!secondChunk[1]) { // Directory-technology, e.g. button2. < examples >/
return; // skip, go to next processor
}
const cell = BemCell(secondChunk);
return cell && !compareEntities(cell.entity, {block: block}).length ? cell : null;
}function _parseSimpleBemPath(filePath) {
const name = path.basename(filePath);
const cellFromName = BemCell(splitAtFirst(name, '.'));
if(!cellFromName) {
return null;
}
const entityFromDir = parseDirAsBemCell(path.dirname(filePath));
const diff = compareEntities(cellFromName.entity, entityFromDir);
return !diff.length || _.isEqual(diff, ['modVal']) ? cellFromName : null;
}There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. compareEntities There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @a-x- а pr прислать ты не хочешь ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, it's mine yep, i can, but i afraid it useless and what would be changed if i do? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can see all of helpers in the internal pr: lego/islands-ci-helpers/pull/233 |
||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,22 @@ | ||
| var expect = require('chai').expect, | ||
| scheme = require('..'); | ||
|
|
||
| describe('default', function() { | ||
|
|
||
| it('should return path + tech', function() { | ||
| expect('a/a.js') | ||
| .eql(scheme().path({ block: 'a' }, 'js')); | ||
| }); | ||
| describe('path', function() { | ||
| describe('default', function() { | ||
| it('should return path + tech', function() { | ||
| expect(scheme().path({ block: 'a' }, 'js')) | ||
| .eql('a/a.js'); | ||
| }); | ||
|
|
||
| it('should return nested scheme by default', function() { | ||
| expect(scheme().path({ block: 'a', elem: 'e1' }, 'js')) | ||
| .eql('a/__e1/a__e1.js'); | ||
| }); | ||
| it('should return nested scheme by default', function() { | ||
| expect(scheme().path({ block: 'a', elem: 'e1' }, 'js')) | ||
| .eql('a/__e1/a__e1.js'); | ||
| }); | ||
|
|
||
| it('should return error', function() { | ||
| var s = scheme; | ||
| expect(s.bind(s, 'scheme-not-found')).to.throw(/Scheme not found/); | ||
| it('should return error', function() { | ||
| var s = scheme; | ||
| expect(s.bind(s, 'scheme-not-found')).to.throw(/Scheme not found/); | ||
| }); | ||
| }); | ||
|
|
||
| it('should support optional naming style', function() { | ||
|
|
@@ -131,3 +132,139 @@ describe('default', function() { | |
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('parse', function() { | ||
| describe('default', function() { | ||
|
|
||
| }); | ||
|
|
||
| describe('nested', function() { | ||
| it('should parse block', function() { | ||
| var expected = { entity: { block: 'b1' }, tech: '' }; | ||
|
|
||
| expect(scheme().parse('b1')).eql(expected); | ||
| expect(scheme().parse('b1/')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse elem', function() { | ||
| var expected = { entity: { block: 'b1', elem: 'e1' }, tech: '' }; | ||
|
|
||
| expect(scheme().parse('b1__e1')).eql(expected); | ||
| expect(scheme().parse('b1/__e1')).eql(expected); | ||
| expect(scheme().parse('b1/__e1/')).eql(expected); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure that it is a block_elem, but not block ? |
||
| expect(scheme().parse('b1/__e1/b1__e1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse block with boolean modifier', function() { | ||
| var expected = { entity: { block: 'b1', modName: 'm1', modVal: true }, tech: '' }; | ||
|
|
||
| expect(scheme().parse('b1_m1')).eql(expected); | ||
| expect(scheme().parse('b1/_m1')).eql(expected); | ||
| expect(scheme().parse('b1/_m1/')).eql(expected); | ||
| expect(scheme().parse('b1/_m1/b1_m1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse block with key-value modifier', function() { | ||
| var expected = { entity: { block: 'b1', modName: 'm1', modVal: 'v1' }, tech: '' }; | ||
|
|
||
| expect(scheme().parse('b1_m1_v1')).eql(expected); | ||
| expect(scheme().parse('b1/_m1/b1_m1_v1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse elem with boolean modifier', function() { | ||
| var expected = { entity: { block: 'b1', elem: 'e1', modName: 'm1', modVal: true }, tech: '' }; | ||
|
|
||
| expect(scheme().parse('b1__e1_m1')).eql(expected); | ||
| expect(scheme().parse('b1/__e1/_m1')).eql(expected); | ||
| expect(scheme().parse('b1/__e1/_m1/')).eql(expected); | ||
| expect(scheme().parse('b1/__e1/_m1/b1__e1_m1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse elem with key-value modifier', function() { | ||
| var expected = { entity: { block: 'b1', elem: 'e1', modName: 'm1', modVal: 'v1' }, tech: '' }; | ||
|
|
||
| expect(scheme().parse('b1__e1_m1_v1')).eql(expected); | ||
| expect(scheme().parse('b1/__e1/_m1/b1__e1_m1_v1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse tech', function() { | ||
| var expectedBlock = { entity: { block: 'b1' }, tech: 'spec.js' }, | ||
| expectedBlockMod = { entity: { block: 'b1', modName: 'm1', modVal: true }, tech: 'spec.js' }, | ||
| expectedElem = { entity: { block: 'b1', elem: 'e1' }, tech: 'spec.js' }, | ||
| expectedElemMod = { entity: { block: 'b1', elem: 'e1', modName: 'm1', modVal: 'v1' }, tech: 'spec.js' }; | ||
|
|
||
| expect(scheme().parse('b1.spec.js')).eql(expectedBlock); | ||
| expect(scheme().parse('b1/b1.spec.js')).eql(expectedBlock); | ||
|
|
||
| expect(scheme().parse('b1_m1.spec.js')).eql(expectedBlockMod); | ||
| expect(scheme().parse('b1/_m1/b1_m1.spec.js')).eql(expectedBlockMod); | ||
|
|
||
| expect(scheme().parse('b1__e1.spec.js')).eql(expectedElem); | ||
| expect(scheme().parse('b1/__e1/b1__e1.spec.js')).eql(expectedElem); | ||
|
|
||
| expect(scheme().parse('b1__e1_m1_v1.spec.js')).eql(expectedElemMod); | ||
| expect(scheme().parse('b1/__e1/_m1/b1__e1_m1_v1.spec.js')).eql(expectedElemMod); | ||
| }); | ||
|
|
||
| it('should not parse wrong paths', function() { | ||
| expect(scheme().parse('b1/b2')).eql(undefined); | ||
| expect(scheme().parse('b1/b2/b3')).eql(undefined); | ||
| expect(scheme().parse('b1/b2/b1')).eql(undefined); | ||
| expect(scheme().parse('b1/b2/b1__e1')).eql(undefined); | ||
| expect(scheme().parse('b1/b2/b1__e1.t1')).eql(undefined); | ||
| expect(scheme().parse('b1/_m1/__e1/b1__e1_m1.t1')).eql(undefined); | ||
| expect(scheme().parse('blah/b1/_m1/__e1/b1__e1_m1.t1')).eql(undefined); | ||
| expect(scheme().parse('blah/b1/_m1/__e1/b1__e1_m1/b1__e1_m1.t1')).eql(undefined); | ||
| }); | ||
| }); | ||
|
|
||
| describe('flat', function() { | ||
| it('should parse block', function() { | ||
| var expected = { entity: { block: 'b1' }, tech: '' }; | ||
|
|
||
| expect(scheme('flat').parse('b1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse elem', function() { | ||
| var expected = { entity: { block: 'b1', elem: 'e1' }, tech: '' }; | ||
|
|
||
| expect(scheme('flat').parse('b1__e1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse block with boolean modifier', function() { | ||
| var expected = { entity: { block: 'b1', modName: 'm1', modVal: true }, tech: '' }; | ||
|
|
||
| expect(scheme('flat').parse('b1_m1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse block with key-value modifier', function() { | ||
| var expected = { entity: { block: 'b1', modName: 'm1', modVal: 'v1' }, tech: '' }; | ||
|
|
||
| expect(scheme('flat').parse('b1_m1_v1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse elem with boolean modifier', function() { | ||
| var expected = { entity: { block: 'b1', elem: 'e1', modName: 'm1', modVal: true }, tech: '' }; | ||
|
|
||
| expect(scheme('flat').parse('b1__e1_m1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse elem with key-value modifier', function() { | ||
| var expected = { entity: { block: 'b1', elem: 'e1', modName: 'm1', modVal: 'v1' }, tech: '' }; | ||
|
|
||
| expect(scheme('flat').parse('b1__e1_m1_v1')).eql(expected); | ||
| }); | ||
|
|
||
| it('should parse tech', function() { | ||
| var expectedBlock = { entity: { block: 'b1' }, tech: 'spec.js' }, | ||
| expectedBlockMod = { entity: { block: 'b1', modName: 'm1', modVal: true }, tech: 'spec.js' }, | ||
| expectedElem = { entity: { block: 'b1', elem: 'e1' }, tech: 'spec.js' }, | ||
| expectedElemMod = { entity: { block: 'b1', elem: 'e1', modName: 'm1', modVal: 'v1' }, tech: 'spec.js' }; | ||
|
|
||
| expect(scheme('flat').parse('b1.spec.js')).eql(expectedBlock); | ||
| expect(scheme('flat').parse('b1_m1.spec.js')).eql(expectedBlockMod); | ||
| expect(scheme('flat').parse('b1__e1.spec.js')).eql(expectedElem); | ||
| expect(scheme('flat').parse('b1__e1_m1_v1.spec.js')).eql(expectedElemMod); | ||
| }); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bem/naming