Skip to content

Commit

Permalink
Merge 977212a into 4307438
Browse files Browse the repository at this point in the history
  • Loading branch information
qfox committed Jan 17, 2017
2 parents 4307438 + 977212a commit 7d37486
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 1 deletion.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,59 @@ const cell = new BemCell({
cell.id; // ➜ "button__text@desktop.css"
```

Debuggability
-------------

In Node.js, `console.log()` calls `util.inspect()` on each argument without a formatting placeholder.

`BemCell` has `inspect()` method to get custom string representation of the object.

```js
const BemCell = require('@bem/cell');
const BemEntityName = require('@bem/entity-name');

const cell = new BemCell({
entity: new BemEntityName({ block: 'input', mod: 'available' }),
tech: 'css'
});

console.log(cell);

// ➜ BemCell { entity: { block: 'input', mod: { name: 'available' } }, tech: 'css' }
```

You can also convert `BemCell` object to `string`.

```js
const BemCell = require('@bem/cell');
const BemEntityName = require('@bem/entity-name');

const cell = new BemCell({
entity: new BemEntityName({ block: 'input', mod: 'available' }),
tech: 'css'
});

console.log(`cell: ${cell}`);

// ➜ cell: input_available.css
```

Also `BemCell` has `toJson` method to support `JSON.stringify()` behaviour.

```js
const BemCell = require('@bem/cell');
const BemEntityName = require('@bem/entity-name');

const cell = new BemCell({
entity: new BemEntityName({ block: 'input', mod: 'available' }),
tech: 'css'
});

console.log(JSON.stringify(cell));

// ➜ {"entity":{"block":"input","mod":{"name":"available","val":true}},"tech":"css"}
```

License
-------

Expand Down
84 changes: 84 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const assert = require('assert');
const util = require('util');

const BemEntityName = require('@bem/entity-name');

Expand Down Expand Up @@ -104,4 +105,87 @@ module.exports = class BemCell {

return this._id;
}

/**
* Returns string representing the bem cell.
*
* Important: If you want to get string representation in accordance with the provisions naming convention
* you should use `bem-naming` package.
*
* @example
* const BemCell = require('@bem/cell');
* const BemEntityName = require('@bem/entity-name');
* const cell = new BemCell({ entity: new BemEntityName({ block: 'button', mod: 'focused' }) });
*
* cell.toString(); // button_focused
*
* @returns {string}
*/
toString() { return this.id; }

/**
* Returns object representing the bem cell. Is needed for debug in Node.js.
*
* In some browsers `console.log()` calls `valueOf()` on each argument.
* This method will be called to get custom string representation of the object.
*
* The representation object contains only `block`, `elem` and `mod` fields
* without private and deprecated fields (`modName` and `modVal`).
*
* @example
* const BemCell = require('@bem/cell');
* const BemEntityName = require('@bem/entity-name');
* const cell = new BemCell({ entity: new BemEntityName({ block: 'button', mod: 'focused' }) });
*
* cell.valueOf();
*
* // ➜ { entity: { block: 'button', mod: { name: 'focused', value: true } },
* // tech: null,
* // layer: null }
*
* @returns {{ entity: {block: string, elem: ?string, mod: ?{name: string, val: *}}, tech: *, layer: *}}
*/
valueOf() {
const res = { entity: this._entity.valueOf() };
this._tech && (res.tech = this._tech);
this._layer && (res.layer = this._layer);
return res;
}

/**
* Returns object representing the bem cell. Is needed for debug in Node.js.
*
* In Node.js, `console.log()` calls `util.inspect()` on each argument without a formatting placeholder.
* This method will be called to get custom string representation of the object.
*
* The representation object contains only `entity`, `tech` and `layer` fields
* without private fields.
*
* @example
* const BemCell = require('@bem/cell');
* const BemEntityName = require('@bem/entity-name');
* const cell = new BemCell({ entity: new BemEntityName({ block: 'button' }) });
*
* console.log(cell); // BemCell { entity: { block: 'button' }, tech: null, layer: null }
*
* @param {integer} depth — tells inspect how many times to recurse while formatting the object.
* @param {object} options — An optional `options` object may be passed
* that alters certain aspects of the formatted string.
*
* @returns {string}
*/
inspect(depth, options) {
const stringRepresentation = util.inspect(this.valueOf(), options);

return `BemCell ${stringRepresentation}`;
}

/**
* Return raw data for `JSON.stringify()`.
*
* @returns {{ entity: {block: string, elem: ?string, mod: ?{name: string, val: *}}, tech: *, layer: *}}
*/
toJSON() {
return this.valueOf();
}
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"coveralls": "^2.11.9",
"eslint": "^3.0.0",
"eslint-config-pedant": "^0.8.0",
"nyc": "^10.0.0"
"nyc": "^10.0.0",
"sinon": "^1.17.7"
},
"scripts": {
"pretest": "npm run lint",
Expand Down
28 changes: 28 additions & 0 deletions test/inspect.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const test = require('ava');
const sinon = require('sinon');
const BemEntityName = require('@bem/entity-name');

const BemCell = require('../index');

const EOL = require('os').EOL;

test.beforeEach(t => {
t.context.stdoutWriteStub = sinon.stub(process.stdout, 'write');
});

test.afterEach(t => {
t.context.stdoutWriteStub.restore();
});

test('should return entity object', t => {
const cell = new BemCell({
entity: new BemEntityName({ block: 'block' }),
tech: 'css'
});

console.log(cell);

const message = `BemCell { entity: { block: 'block' }, tech: 'css' }${EOL}`;

t.true(t.context.stdoutWriteStub.calledWith(message));
});
13 changes: 13 additions & 0 deletions test/to-json.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const test = require('ava');
const BemEntityName = require('@bem/entity-name');

const BemCell = require('../index');

test('should return stringified cell', t => {
const cell = new BemCell({
entity: new BemEntityName({ block: 'button' }),
tech: 'olala'
});

t.is(JSON.stringify([cell]), '[{"entity":{"block":"button"},"tech":"olala"}]');
});
12 changes: 12 additions & 0 deletions test/to-string.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const test = require('ava');
const BemEntityName = require('@bem/entity-name');

const BemCell = require('../index');

test('should return string', t => {
const cell = new BemCell({
entity: new BemEntityName({ block: 'block' })
});

t.truthy(typeof cell.toString() === 'string');
});
40 changes: 40 additions & 0 deletions test/value-of.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const test = require('ava');
const BemEntityName = require('@bem/entity-name');

const BemCell = require('../index');

test('should return cell with entity', t => {
const cell = new BemCell({
entity: new BemEntityName({ block: 'block' })
});

t.deepEqual(cell.valueOf(), { entity: { block: 'block' } });
});

test('should return cell with entity and tech', t => {
const cell = new BemCell({
entity: new BemEntityName({ block: 'block' }),
tech: 'css'
});

t.deepEqual(cell.valueOf(), { entity: { block: 'block' }, tech: 'css' });
});

test('should return cell with entity and layer', t => {
const cell = new BemCell({
entity: new BemEntityName({ block: 'block' }),
layer: 'desktop'
});

t.deepEqual(cell.valueOf(), { entity: { block: 'block' }, layer: 'desktop' });
});

test('should return cell with entity and tech and layer', t => {
const cell = new BemCell({
entity: new BemEntityName({ block: 'block' }),
tech: 'css',
layer: 'desktop'
});

t.deepEqual(cell.valueOf(), { entity: { block: 'block' }, tech: 'css', layer: 'desktop' });
});

0 comments on commit 7d37486

Please sign in to comment.