Skip to content
This repository was archived by the owner on Feb 4, 2018. It is now read-only.

Commit 6664366

Browse files
authored
Merge pull request #71 from bem-sdk/belongs-to
feat: add belongsTo method
2 parents 94ebc5e + 22eb626 commit 6664366

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ API
6767
* [type](#type)
6868
* [isSimpleMod()](#issimplemod)
6969
* [isEqual(entityName)](#isequalentityname)
70+
* [belongsTo(entityName)](#belongstoentityname)
7071
* [toString()](#tostring)
7172
* [valueOf()](#valueof)
7273
* [toJSON()](#tojson)
@@ -227,6 +228,29 @@ inputName.isEqual(buttonName); // false
227228
buttonName.isEqual(buttonName); // true
228229
```
229230

231+
### belongsTo(entityName)
232+
233+
Parameter | Type | Description
234+
-------------|-----------------|-----------------------
235+
`entityName` | `BemEntityName` | The entity to compare.
236+
237+
Determines whether specified entity belongs to this.
238+
239+
```js
240+
const BemEntityName = require('@bem/entity-name');
241+
242+
const buttonName = new BemEntityName({ block: 'button' });
243+
const buttonTextName = new BemEntityName({ block: 'button', elem: 'text' });
244+
const buttonTextBoldName = new BemEntityName(
245+
{ block: 'button', elem: 'text', mod: { name: 'bold', val: true } }
246+
);
247+
248+
buttonTextName.belongsTo(buttonName); // true
249+
buttonName.belongsTo(buttonTextName); // false
250+
buttonTextBoldName.belongsTo(buttonTextName); // true
251+
buttonTextBoldName.belongsTo(buttonName); // false
252+
```
253+
230254
### toString()
231255

232256
Returns string representing the entity name.

index.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,35 @@ class BemEntityName {
310310
return entityName && (this.id === entityName.id);
311311
}
312312

313+
/**
314+
* Determines whether specified entity belongs to this.
315+
*
316+
* @example
317+
* const BemEntityName = require('@bem/entity-name');
318+
*
319+
* const buttonName = new BemEntityName({ block: 'button' });
320+
* const buttonTextName = new BemEntityName({ block: 'button', elem: 'text' });
321+
* const buttonTextBoldName = new BemEntityName(
322+
* { block: 'button', elem: 'text', mod: { name: 'bold', val: true } }
323+
* );
324+
*
325+
* buttonTextName.belongsTo(buttonName); // true
326+
* buttonName.belongsTo(buttonTextName); // false
327+
* buttonTextBoldName.belongsTo(buttonTextName); // true
328+
* buttonTextBoldName.belongsTo(buttonName); // false
329+
*
330+
* @param {BemEntityName} entityName - the entity to compare.
331+
*
332+
* @returns {boolean}
333+
*/
334+
belongsTo(entityName) {
335+
return entityName && entityName.id !== this.id && this.id.startsWith(entityName.id) &&
336+
(entityName.type !== 'block' || this.type !== 'elemMod') &&
337+
(!entityName.elem || this.elem === entityName.elem) &&
338+
(!entityName.modName || this.modName === entityName.modName) &&
339+
(!entityName.modVal || entityName.modVal === true || this.modVal === entityName.modVal);
340+
}
341+
313342
/**
314343
* Determines whether specified entity is instance of BemEntityName.
315344
*

test/belongs-to.test.js

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
const test = require('ava');
2+
3+
const BemEntityName = require('../index');
4+
5+
test('should not detect belonging between block and itself', t => {
6+
const blockName = new BemEntityName({ block: 'block' });
7+
8+
t.false(blockName.belongsTo(blockName));
9+
});
10+
11+
test('should not detect belonging between elem and itself', t => {
12+
const elemName = new BemEntityName({ block: 'block', elem: 'elem' });
13+
14+
t.false(elemName.belongsTo(elemName));
15+
});
16+
17+
test('should not detect belonging between block mod and itself', t => {
18+
const modName = new BemEntityName({ block: 'block', mod: 'mod' });
19+
20+
t.false(modName.belongsTo(modName));
21+
});
22+
23+
test('should not detect belonging between elem mod and itself', t => {
24+
const modName = new BemEntityName({ block: 'block', elem: 'elem', mod: 'mod' });
25+
26+
t.false(modName.belongsTo(modName));
27+
});
28+
29+
test('should resolve belonging between block and its elem', t => {
30+
const blockName = new BemEntityName({ block: 'block' });
31+
const elemName = new BemEntityName({ block: 'block', elem: 'elem' });
32+
33+
t.true(elemName.belongsTo(blockName));
34+
t.false(blockName.belongsTo(elemName));
35+
});
36+
37+
test('should not detect belonging between two block', t => {
38+
const name1 = new BemEntityName({ block: 'block1' });
39+
const name2 = new BemEntityName({ block: 'block2' });
40+
41+
t.false(name1.belongsTo(name2));
42+
t.false(name2.belongsTo(name1));
43+
});
44+
45+
test('should not detect belonging between two mods of block', t => {
46+
const modName1 = new BemEntityName({ block: 'block', mod: 'mod1' });
47+
const modName2 = new BemEntityName({ block: 'block', mod: 'mod2' });
48+
49+
t.false(modName1.belongsTo(modName2));
50+
t.false(modName2.belongsTo(modName1));
51+
});
52+
53+
test('should not detect belonging between two elems of block', t => {
54+
const elemName1 = new BemEntityName({ block: 'block', elem: 'elem1' });
55+
const elemName2 = new BemEntityName({ block: 'block', elem: 'elem2' });
56+
57+
t.false(elemName1.belongsTo(elemName2));
58+
t.false(elemName2.belongsTo(elemName1));
59+
});
60+
61+
test('should resolve belonging between block and its mod', t => {
62+
const blockName = new BemEntityName({ block: 'block' });
63+
const modName = new BemEntityName({ block: 'block', mod: { name: 'mod', val: 'key' } });
64+
65+
t.true(modName.belongsTo(blockName));
66+
t.false(blockName.belongsTo(modName));
67+
});
68+
69+
test('should resolve belonging between elem and its mod', t => {
70+
const elemName = new BemEntityName({ block: 'block', elem: 'elem' });
71+
const modName = new BemEntityName({ block: 'block', elem: 'elem', mod: { name: 'mod', val: 'key' } });
72+
73+
t.true(modName.belongsTo(elemName));
74+
t.false(elemName.belongsTo(modName));
75+
});
76+
77+
test('should not detect belonging between block and its elem mod', t => {
78+
const blockName = new BemEntityName({ block: 'block' });
79+
const elemModName = new BemEntityName({ block: 'block', elem: 'elem', mod: { name: 'mod', val: 'key' } });
80+
81+
t.false(elemModName.belongsTo(blockName));
82+
t.false(blockName.belongsTo(elemModName));
83+
});
84+
85+
test('should not detect belonging between block and its elem with the same mod', t => {
86+
const blockModName = new BemEntityName({ block: 'block', mod: 'mod' });
87+
const elemModName = new BemEntityName({ block: 'block', elem: 'elem', mod: 'mod' });
88+
89+
t.false(elemModName.belongsTo(blockModName));
90+
t.false(blockModName.belongsTo(elemModName));
91+
});
92+
93+
test('should resolve belonging between boolean and key-value mod of block', t => {
94+
const boolModName = new BemEntityName({ block: 'block', mod: { name: 'mod', val: true } });
95+
const modName = new BemEntityName({ block: 'block', mod: { name: 'mod', val: 'key' } });
96+
97+
t.true(modName.belongsTo(boolModName));
98+
t.false(boolModName.belongsTo(modName));
99+
});
100+
101+
test('should resolve belonging between boolean and key-value mod of element', t => {
102+
const boolModName = new BemEntityName({ block: 'block', elem: 'elem', mod: { name: 'mod', val: true } });
103+
const modName = new BemEntityName({ block: 'block', elem: 'elem', mod: { name: 'mod', val: 'key' } });
104+
105+
t.true(modName.belongsTo(boolModName));
106+
t.false(boolModName.belongsTo(modName));
107+
});
108+
109+
test('should not detect belonging between key-value mods of block', t => {
110+
const modName1 = new BemEntityName({ block: 'block', mod: { name: 'mod', val: 'key1' } });
111+
const modName2 = new BemEntityName({ block: 'block', mod: { name: 'mod', val: 'key2' } });
112+
113+
t.false(modName1.belongsTo(modName2));
114+
t.false(modName2.belongsTo(modName1));
115+
});
116+
117+
test('should not detect belonging between key-value mods of elem', t => {
118+
const modName1 = new BemEntityName({ block: 'block', elem: 'elem', mod: { name: 'mod', val: 'key1' } });
119+
const modName2 = new BemEntityName({ block: 'block', elem: 'elem', mod: { name: 'mod', val: 'key2' } });
120+
121+
t.false(modName1.belongsTo(modName2));
122+
t.false(modName2.belongsTo(modName1));
123+
});

0 commit comments

Comments
 (0)