mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Separate more JS util logic to be unit tested (#705)
* Move featureClassNames to js util * Add tests for featureClassNames * Strip empty feature class names * Move canToggleDomain to js util * Add tests for canToggleDomain * Refactor canToggleDomain to ensure boolean return * Switch to chai assert for richer syntax options * Move canToggleState to js util * Tests for canToggleState * Enable linting for mocha tests * Move stateCardType to js util * Add tests for stateCardType * Move stateMoreInfoType to js util * Tests for stateMoreInfoType * Include mdn Array includes polyfill
This commit is contained in:
parent
c1e7f4cc77
commit
a723c62f4f
11
js/common/util/can_toggle_domain.js
Normal file
11
js/common/util/can_toggle_domain.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default function canToggleDomain(hass, domain) {
|
||||||
|
const services = hass.config.services[domain];
|
||||||
|
if (!services) { return false; }
|
||||||
|
|
||||||
|
if (domain === 'lock') {
|
||||||
|
return 'lock' in services;
|
||||||
|
} else if (domain === 'cover') {
|
||||||
|
return 'open_cover' in services;
|
||||||
|
}
|
||||||
|
return 'turn_on' in services;
|
||||||
|
}
|
11
js/common/util/can_toggle_state.js
Normal file
11
js/common/util/can_toggle_state.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import canToggleDomain from './can_toggle_domain.js';
|
||||||
|
import computeStateDomain from './compute_state_domain.js';
|
||||||
|
|
||||||
|
export default function canToggleState(hass, stateObj) {
|
||||||
|
const domain = computeStateDomain(stateObj);
|
||||||
|
if (domain === 'group') {
|
||||||
|
return stateObj.state === 'on' || stateObj.state === 'off';
|
||||||
|
}
|
||||||
|
|
||||||
|
return canToggleDomain(hass, domain);
|
||||||
|
}
|
10
js/common/util/feature_class_names.js
Normal file
10
js/common/util/feature_class_names.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Expects classNames to be an object mapping feature-bit -> className
|
||||||
|
export default function featureClassNames(stateObj, classNames) {
|
||||||
|
if (!stateObj || !stateObj.attributes.supported_features) return '';
|
||||||
|
|
||||||
|
const features = stateObj.attributes.supported_features;
|
||||||
|
|
||||||
|
return Object.keys(classNames).map(feature => (
|
||||||
|
(features & feature) !== 0 ? classNames[feature] : ''
|
||||||
|
)).filter(attr => attr !== '').join(' ');
|
||||||
|
}
|
31
js/common/util/state_card_type.js
Normal file
31
js/common/util/state_card_type.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import canToggleState from './can_toggle_state.js';
|
||||||
|
import computeStateDomain from './compute_state_domain.js';
|
||||||
|
|
||||||
|
const DOMAINS_WITH_CARD = [
|
||||||
|
'climate',
|
||||||
|
'cover',
|
||||||
|
'configurator',
|
||||||
|
'input_select',
|
||||||
|
'input_number',
|
||||||
|
'input_text',
|
||||||
|
'media_player',
|
||||||
|
'scene',
|
||||||
|
'script',
|
||||||
|
'weblink',
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function stateCardType(hass, stateObj) {
|
||||||
|
if (stateObj.state === 'unavailable') {
|
||||||
|
return 'display';
|
||||||
|
}
|
||||||
|
|
||||||
|
const domain = computeStateDomain(stateObj);
|
||||||
|
|
||||||
|
if (DOMAINS_WITH_CARD.includes(domain)) {
|
||||||
|
return domain;
|
||||||
|
} else if (canToggleState(hass, stateObj) &&
|
||||||
|
stateObj.attributes.control !== 'hidden') {
|
||||||
|
return 'toggle';
|
||||||
|
}
|
||||||
|
return 'display';
|
||||||
|
}
|
23
js/common/util/state_more_info_type.js
Normal file
23
js/common/util/state_more_info_type.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import computeStateDomain from './compute_state_domain.js';
|
||||||
|
|
||||||
|
const DOMAINS_WITH_MORE_INFO = [
|
||||||
|
'alarm_control_panel', 'automation', 'camera', 'climate', 'configurator',
|
||||||
|
'cover', 'fan', 'group', 'history_graph', 'light', 'lock', 'media_player', 'script',
|
||||||
|
'sun', 'updater', 'vacuum', 'input_datetime',
|
||||||
|
];
|
||||||
|
|
||||||
|
const HIDE_MORE_INFO = [
|
||||||
|
'input_select', 'scene', 'input_number', 'input_text'
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function stateMoreInfoType(stateObj) {
|
||||||
|
const domain = computeStateDomain(stateObj);
|
||||||
|
|
||||||
|
if (DOMAINS_WITH_MORE_INFO.includes(domain)) {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
if (HIDE_MORE_INFO.includes(domain)) {
|
||||||
|
return 'hidden';
|
||||||
|
}
|
||||||
|
return 'default';
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'mdn-polyfills/Array.prototype.includes';
|
||||||
import 'unfetch/polyfill';
|
import 'unfetch/polyfill';
|
||||||
import objAssign from 'es6-object-assign';
|
import objAssign from 'es6-object-assign';
|
||||||
|
|
||||||
|
10
js/util.js
10
js/util.js
@ -7,11 +7,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import attributeClassNames from './common/util/attribute_class_names.js';
|
import attributeClassNames from './common/util/attribute_class_names.js';
|
||||||
|
import canToggleDomain from './common/util/can_toggle_domain.js';
|
||||||
|
import canToggleState from './common/util/can_toggle_state.js';
|
||||||
import computeStateDomain from './common/util/compute_state_domain.js';
|
import computeStateDomain from './common/util/compute_state_domain.js';
|
||||||
import computeStateDisplay from './common/util/compute_state_display.js';
|
import computeStateDisplay from './common/util/compute_state_display.js';
|
||||||
|
import featureClassNames from './common/util/feature_class_names.js';
|
||||||
import formatDate from './common/util/format_date.js';
|
import formatDate from './common/util/format_date.js';
|
||||||
import formatDateTime from './common/util/format_date_time.js';
|
import formatDateTime from './common/util/format_date_time.js';
|
||||||
import formatTime from './common/util/format_time.js';
|
import formatTime from './common/util/format_time.js';
|
||||||
|
import stateCardType from './common/util/state_card_type.js';
|
||||||
|
import stateMoreInfoType from './common/util/state_more_info_type.js';
|
||||||
|
|
||||||
window.hassUtil = window.hassUtil || {};
|
window.hassUtil = window.hassUtil || {};
|
||||||
|
|
||||||
@ -21,8 +26,13 @@ const language = navigator.languages ?
|
|||||||
window.fecha.masks.haDateTime = window.fecha.masks.shortTime + ' ' + window.fecha.masks.mediumDate;
|
window.fecha.masks.haDateTime = window.fecha.masks.shortTime + ' ' + window.fecha.masks.mediumDate;
|
||||||
|
|
||||||
window.hassUtil.attributeClassNames = attributeClassNames;
|
window.hassUtil.attributeClassNames = attributeClassNames;
|
||||||
|
window.hassUtil.canToggleDomain = canToggleDomain;
|
||||||
|
window.hassUtil.canToggleState = canToggleState;
|
||||||
window.hassUtil.computeDomain = computeStateDomain;
|
window.hassUtil.computeDomain = computeStateDomain;
|
||||||
window.hassUtil.computeStateDisplay = computeStateDisplay;
|
window.hassUtil.computeStateDisplay = computeStateDisplay;
|
||||||
|
window.hassUtil.featureClassNames = featureClassNames;
|
||||||
window.hassUtil.formatDate = dateObj => formatDate(dateObj, language);
|
window.hassUtil.formatDate = dateObj => formatDate(dateObj, language);
|
||||||
window.hassUtil.formatDateTime = dateObj => formatDateTime(dateObj, language);
|
window.hassUtil.formatDateTime = dateObj => formatDateTime(dateObj, language);
|
||||||
window.hassUtil.formatTime = dateObj => formatTime(dateObj, language);
|
window.hassUtil.formatTime = dateObj => formatTime(dateObj, language);
|
||||||
|
window.hassUtil.stateCardType = stateCardType;
|
||||||
|
window.hassUtil.stateMoreInfoType = stateMoreInfoType;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
"dev-watch": "npm run gulp watch_ru_all gen-service-worker",
|
"dev-watch": "npm run gulp watch_ru_all gen-service-worker",
|
||||||
"dev-es5": "npm run gulp ru_all_es5 gen-service-worker-es5",
|
"dev-es5": "npm run gulp ru_all_es5 gen-service-worker-es5",
|
||||||
"dev-watch-es5": "npm run gulp watch_ru_all_es5 gen-service-worker-es5",
|
"dev-watch-es5": "npm run gulp watch_ru_all_es5 gen-service-worker-es5",
|
||||||
"lint_js": "eslint src panels js --ext js,html",
|
"lint_js": "eslint src panels js test-mocha --ext js,html",
|
||||||
"lint_html": "ls -1 src/home-assistant.html panels/**/ha-panel-*.html | xargs polymer lint --input",
|
"lint_html": "ls -1 src/home-assistant.html panels/**/ha-panel-*.html | xargs polymer lint --input",
|
||||||
"mocha": "node_modules/.bin/mocha --opts test-mocha/mocha.opts",
|
"mocha": "node_modules/.bin/mocha --opts test-mocha/mocha.opts",
|
||||||
"test": "npm run lint_js && npm run lint_html && npm run mocha"
|
"test": "npm run lint_js && npm run lint_html && npm run mocha"
|
||||||
@ -29,6 +29,7 @@
|
|||||||
"babel-plugin-transform-react-jsx": "^6.24.1",
|
"babel-plugin-transform-react-jsx": "^6.24.1",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"bower": "^1.8.2",
|
"bower": "^1.8.2",
|
||||||
|
"chai": "^4.1.2",
|
||||||
"css-slam": "^2.0.2",
|
"css-slam": "^2.0.2",
|
||||||
"del": "^3.0.0",
|
"del": "^3.0.0",
|
||||||
"es6-object-assign": "^1.1.0",
|
"es6-object-assign": "^1.1.0",
|
||||||
@ -58,6 +59,7 @@
|
|||||||
"gulp-vinyl-zip": "^2.1.0",
|
"gulp-vinyl-zip": "^2.1.0",
|
||||||
"home-assistant-js-websocket": "^1.1.2",
|
"home-assistant-js-websocket": "^1.1.2",
|
||||||
"html-minifier": "^3.5.6",
|
"html-minifier": "^3.5.6",
|
||||||
|
"mdn-polyfills": "^5.5.0",
|
||||||
"merge-stream": "^1.0.1",
|
"merge-stream": "^1.0.1",
|
||||||
"mocha": "^4.0.1",
|
"mocha": "^4.0.1",
|
||||||
"parse5": "^3.0.3",
|
"parse5": "^3.0.3",
|
||||||
|
@ -11,67 +11,8 @@ window.hassUtil.DEFAULT_ICON = 'mdi:bookmark';
|
|||||||
|
|
||||||
window.hassUtil.OFF_STATES = ['off', 'closed', 'unlocked'];
|
window.hassUtil.OFF_STATES = ['off', 'closed', 'unlocked'];
|
||||||
|
|
||||||
window.hassUtil.DOMAINS_WITH_CARD = [
|
|
||||||
'climate',
|
|
||||||
'cover',
|
|
||||||
'configurator',
|
|
||||||
'input_select',
|
|
||||||
'input_number',
|
|
||||||
'input_text',
|
|
||||||
'media_player',
|
|
||||||
'scene',
|
|
||||||
'script',
|
|
||||||
'weblink',
|
|
||||||
];
|
|
||||||
|
|
||||||
window.hassUtil.DOMAINS_WITH_MORE_INFO = [
|
|
||||||
'alarm_control_panel', 'automation', 'camera', 'climate', 'configurator',
|
|
||||||
'cover', 'fan', 'group', 'history_graph', 'light', 'lock', 'media_player', 'script',
|
|
||||||
'sun', 'updater', 'vacuum', 'input_datetime',
|
|
||||||
];
|
|
||||||
|
|
||||||
window.hassUtil.DOMAINS_WITH_NO_HISTORY = ['camera', 'configurator', 'history_graph', 'scene'];
|
window.hassUtil.DOMAINS_WITH_NO_HISTORY = ['camera', 'configurator', 'history_graph', 'scene'];
|
||||||
|
|
||||||
window.hassUtil.HIDE_MORE_INFO = [
|
|
||||||
'input_select', 'scene', 'input_number', 'input_text'
|
|
||||||
];
|
|
||||||
|
|
||||||
// Expects featureClassNames to be an object mapping feature-bit -> className
|
|
||||||
window.hassUtil.featureClassNames = function (stateObj, featureClassNames) {
|
|
||||||
if (!stateObj || !stateObj.attributes.supported_features) return '';
|
|
||||||
|
|
||||||
var features = stateObj.attributes.supported_features;
|
|
||||||
|
|
||||||
return Object.keys(featureClassNames).map(function (feature) {
|
|
||||||
return (features & feature) !== 0 ? featureClassNames[feature] : '';
|
|
||||||
}).join(' ');
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
window.hassUtil.canToggleState = function (hass, stateObj) {
|
|
||||||
var domain = window.hassUtil.computeDomain(stateObj);
|
|
||||||
if (domain === 'group') {
|
|
||||||
return stateObj.state === 'on' || stateObj.state === 'off';
|
|
||||||
}
|
|
||||||
|
|
||||||
return window.hassUtil.canToggleDomain(hass, domain);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.hassUtil.canToggleDomain = function (hass, domain) {
|
|
||||||
var turnOnService;
|
|
||||||
var services = hass.config.services[domain];
|
|
||||||
|
|
||||||
if (domain === 'lock') {
|
|
||||||
turnOnService = 'lock';
|
|
||||||
} else if (domain === 'cover') {
|
|
||||||
turnOnService = 'open_cover';
|
|
||||||
} else {
|
|
||||||
turnOnService = 'turn_on';
|
|
||||||
}
|
|
||||||
|
|
||||||
return services && turnOnService in services;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Update root's child element to be newElementTag replacing another existing child if any.
|
// Update root's child element to be newElementTag replacing another existing child if any.
|
||||||
// Copy attributes into the child element.
|
// Copy attributes into the child element.
|
||||||
window.hassUtil.dynamicContentUpdater = function (root, newElementTag, attributes) {
|
window.hassUtil.dynamicContentUpdater = function (root, newElementTag, attributes) {
|
||||||
@ -133,34 +74,6 @@ window.hassUtil.relativeTime.tests = [
|
|||||||
7, 'day',
|
7, 'day',
|
||||||
];
|
];
|
||||||
|
|
||||||
window.hassUtil.stateCardType = function (hass, stateObj) {
|
|
||||||
if (stateObj.state === 'unavailable') {
|
|
||||||
return 'display';
|
|
||||||
}
|
|
||||||
|
|
||||||
var domain = window.hassUtil.computeDomain(stateObj);
|
|
||||||
|
|
||||||
if (window.hassUtil.DOMAINS_WITH_CARD.indexOf(domain) !== -1) {
|
|
||||||
return domain;
|
|
||||||
} else if (window.hassUtil.canToggleState(hass, stateObj) &&
|
|
||||||
stateObj.attributes.control !== 'hidden') {
|
|
||||||
return 'toggle';
|
|
||||||
}
|
|
||||||
return 'display';
|
|
||||||
};
|
|
||||||
|
|
||||||
window.hassUtil.stateMoreInfoType = function (stateObj) {
|
|
||||||
var domain = window.hassUtil.computeDomain(stateObj);
|
|
||||||
|
|
||||||
if (window.hassUtil.DOMAINS_WITH_MORE_INFO.indexOf(domain) !== -1) {
|
|
||||||
return domain;
|
|
||||||
}
|
|
||||||
if (window.hassUtil.HIDE_MORE_INFO.indexOf(domain) !== -1) {
|
|
||||||
return 'hidden';
|
|
||||||
}
|
|
||||||
return 'default';
|
|
||||||
};
|
|
||||||
|
|
||||||
window.hassUtil.domainIcon = function (domain, state) {
|
window.hassUtil.domainIcon = function (domain, state) {
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case 'alarm_control_panel':
|
case 'alarm_control_panel':
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import attributeClassNames from '../../../js/common/util/attribute_class_names';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import attributeClassNames from '../../../js/common/util/attribute_class_names';
|
||||||
|
|
||||||
describe('attributeClassNames', () => {
|
describe('attributeClassNames', () => {
|
||||||
const attrs = ['mock_attr1', 'mock_attr2'];
|
const attrs = ['mock_attr1', 'mock_attr2'];
|
||||||
|
39
test-mocha/common/util/can_toggle_domain_test.js
Normal file
39
test-mocha/common/util/can_toggle_domain_test.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { assert } from 'chai';
|
||||||
|
|
||||||
|
import canToggleDomain from '../../../js/common/util/can_toggle_domain';
|
||||||
|
|
||||||
|
describe('canToggleDomain', () => {
|
||||||
|
const hass = {
|
||||||
|
config: {
|
||||||
|
services: {
|
||||||
|
light: {
|
||||||
|
turn_on: null, // Service keys only need to be present for test
|
||||||
|
turn_off: null,
|
||||||
|
},
|
||||||
|
lock: {
|
||||||
|
lock: null,
|
||||||
|
unlock: null,
|
||||||
|
},
|
||||||
|
sensor: {
|
||||||
|
custom_service: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
it('Detects lights toggle', () => {
|
||||||
|
assert.isTrue(canToggleDomain(hass, 'light'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Detects locks toggle', () => {
|
||||||
|
assert.isTrue(canToggleDomain(hass, 'lock'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Detects sensors do not toggle', () => {
|
||||||
|
assert.isFalse(canToggleDomain(hass, 'sensor'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Detects binary sensors do not toggle', () => {
|
||||||
|
assert.isFalse(canToggleDomain(hass, 'binary_sensor'));
|
||||||
|
});
|
||||||
|
});
|
40
test-mocha/common/util/can_toggle_state_test.js
Normal file
40
test-mocha/common/util/can_toggle_state_test.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { assert } from 'chai';
|
||||||
|
|
||||||
|
import canToggleState from '../../../js/common/util/can_toggle_state';
|
||||||
|
|
||||||
|
describe('canToggleState', () => {
|
||||||
|
const hass = {
|
||||||
|
config: {
|
||||||
|
services: {
|
||||||
|
light: {
|
||||||
|
turn_on: null, // Service keys only need to be present for test
|
||||||
|
turn_off: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
it('Detects lights toggle', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'light.bla',
|
||||||
|
state: 'on',
|
||||||
|
};
|
||||||
|
assert.isTrue(canToggleState(hass, stateObj));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Detects group with toggle', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'group.bla',
|
||||||
|
state: 'on',
|
||||||
|
};
|
||||||
|
assert.isTrue(canToggleState(hass, stateObj));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Detects group without toggle', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'group.devices',
|
||||||
|
state: 'home',
|
||||||
|
};
|
||||||
|
assert.isFalse(canToggleState(hass, stateObj));
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import computeDomain from '../../../js/common/util/compute_domain';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import computeDomain from '../../../js/common/util/compute_domain';
|
||||||
|
|
||||||
describe('computeDomain', () => {
|
describe('computeDomain', () => {
|
||||||
it('Returns domains', () => {
|
it('Returns domains', () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import computeStateDisplay from '../../../js/common/util/compute_state_display';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import computeStateDisplay from '../../../js/common/util/compute_state_display';
|
||||||
|
|
||||||
describe('computeStateDisplay', () => {
|
describe('computeStateDisplay', () => {
|
||||||
const haLocalize = function (namespace, message, ...args) {
|
const haLocalize = function (namespace, message, ...args) {
|
||||||
@ -156,7 +156,7 @@ describe('computeStateDisplay', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Localizes custom state', () => {
|
it('Localizes custom state', () => {
|
||||||
const altHaLocalize = function (namespace, message, ...args) {
|
const altHaLocalize = function () {
|
||||||
// No matches can be found
|
// No matches can be found
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import computeStateDomain from '../../../js/common/util/compute_state_domain.js';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import computeStateDomain from '../../../js/common/util/compute_state_domain.js';
|
||||||
|
|
||||||
describe('computeStateDomain', () => {
|
describe('computeStateDomain', () => {
|
||||||
it('Detects sensor domain', () => {
|
it('Detects sensor domain', () => {
|
||||||
|
56
test-mocha/common/util/feature_class_names_test.js
Normal file
56
test-mocha/common/util/feature_class_names_test.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { assert } from 'chai';
|
||||||
|
|
||||||
|
import featureClassNames from '../../../js/common/util/feature_class_names';
|
||||||
|
|
||||||
|
describe('featureClassNames', () => {
|
||||||
|
const classNames = {
|
||||||
|
1: 'has-feature_a',
|
||||||
|
2: 'has-feature_b',
|
||||||
|
4: 'has-feature_c',
|
||||||
|
8: 'has-feature_d',
|
||||||
|
};
|
||||||
|
|
||||||
|
it('Skips null states', () => {
|
||||||
|
const stateObj = null;
|
||||||
|
assert.strictEqual(
|
||||||
|
featureClassNames(stateObj, classNames),
|
||||||
|
''
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Matches no features', () => {
|
||||||
|
const stateObj = {
|
||||||
|
attributes: {
|
||||||
|
supported_features: 64,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
assert.strictEqual(
|
||||||
|
featureClassNames(stateObj, classNames),
|
||||||
|
''
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Matches one feature', () => {
|
||||||
|
const stateObj = {
|
||||||
|
attributes: {
|
||||||
|
supported_features: 72,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
assert.strictEqual(
|
||||||
|
featureClassNames(stateObj, classNames),
|
||||||
|
'has-feature_d'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Matches two features', () => {
|
||||||
|
const stateObj = {
|
||||||
|
attributes: {
|
||||||
|
supported_features: 73,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
assert.strictEqual(
|
||||||
|
featureClassNames(stateObj, classNames),
|
||||||
|
'has-feature_a has-feature_d'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import formatDate from '../../../js/common/util/format_date';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import formatDate from '../../../js/common/util/format_date';
|
||||||
|
|
||||||
describe('formatDate', () => {
|
describe('formatDate', () => {
|
||||||
const dateObj = new Date(
|
const dateObj = new Date(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import formatDateTime from '../../../js/common/util/format_date_time';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import formatDateTime from '../../../js/common/util/format_date_time';
|
||||||
|
|
||||||
describe('formatDateTime', () => {
|
describe('formatDateTime', () => {
|
||||||
const dateObj = new Date(
|
const dateObj = new Date(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import formatTime from '../../../js/common/util/format_time';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import formatTime from '../../../js/common/util/format_time';
|
||||||
|
|
||||||
describe('formatTime', () => {
|
describe('formatTime', () => {
|
||||||
const dateObj = new Date(
|
const dateObj = new Date(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { hasLocation } from '../../../js/common/util/location';
|
import { assert } from 'chai';
|
||||||
|
|
||||||
const assert = require('assert');
|
import { hasLocation } from '../../../js/common/util/location';
|
||||||
|
|
||||||
describe('hasLocation', () => {
|
describe('hasLocation', () => {
|
||||||
it('flags states with location', () => {
|
it('flags states with location', () => {
|
||||||
|
55
test-mocha/common/util/state_card_type_test.js
Normal file
55
test-mocha/common/util/state_card_type_test.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { assert } from 'chai';
|
||||||
|
|
||||||
|
import stateCardType from '../../../js/common/util/state_card_type';
|
||||||
|
|
||||||
|
describe('stateCardType', () => {
|
||||||
|
const hass = {
|
||||||
|
config: {
|
||||||
|
services: {
|
||||||
|
light: {
|
||||||
|
turn_on: null, // Service keys only need to be present for test
|
||||||
|
turn_off: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
it('Returns display for unavailable states', () => {
|
||||||
|
const stateObj = {
|
||||||
|
state: 'unavailable',
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateCardType(hass, stateObj), 'display');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns media_player for media_player states', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'media_player.bla',
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateCardType(hass, stateObj), 'media_player');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns toggle for states that can toggle', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'light.bla',
|
||||||
|
attributes: {},
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateCardType(hass, stateObj), 'toggle');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns display for states with hidden control', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'light.bla',
|
||||||
|
attributes: {
|
||||||
|
control: 'hidden',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateCardType(hass, stateObj), 'display');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns display for entities that cannot toggle', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'sensor.bla',
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateCardType(hass, stateObj), 'display');
|
||||||
|
});
|
||||||
|
});
|
28
test-mocha/common/util/state_more_info_type_test.js
Normal file
28
test-mocha/common/util/state_more_info_type_test.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { assert } from 'chai';
|
||||||
|
|
||||||
|
import stateMoreInfoType from '../../../js/common/util/state_more_info_type';
|
||||||
|
|
||||||
|
describe('stateMoreInfoType', () => {
|
||||||
|
it('Returns media_player for media_player states', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'media_player.bla',
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateMoreInfoType(stateObj), 'media_player');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns hidden for input_select states', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'input_select.bla',
|
||||||
|
attributes: {},
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateMoreInfoType(stateObj), 'hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns default for switch states', () => {
|
||||||
|
const stateObj = {
|
||||||
|
entity_id: 'switch.bla',
|
||||||
|
attributes: {},
|
||||||
|
};
|
||||||
|
assert.strictEqual(stateMoreInfoType(stateObj), 'default');
|
||||||
|
});
|
||||||
|
});
|
@ -1707,7 +1707,7 @@ chai@^3.5.0:
|
|||||||
deep-eql "^0.1.3"
|
deep-eql "^0.1.3"
|
||||||
type-detect "^1.0.0"
|
type-detect "^1.0.0"
|
||||||
|
|
||||||
chai@^4.0.2:
|
chai@^4.0.2, chai@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c"
|
resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -5194,6 +5194,10 @@ md5@^2.2.1:
|
|||||||
crypt "~0.0.1"
|
crypt "~0.0.1"
|
||||||
is-buffer "~1.1.1"
|
is-buffer "~1.1.1"
|
||||||
|
|
||||||
|
mdn-polyfills@^5.5.0:
|
||||||
|
version "5.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdn-polyfills/-/mdn-polyfills-5.5.0.tgz#b8ce237a0a7cbae66c56a6fdd0334b659360d364"
|
||||||
|
|
||||||
media-typer@0.3.0:
|
media-typer@0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user