Compute state display tests (#643)
* Move computeDomain and format functions to js * Add tests for computeStateDisplay * Always recalculate state display * Remove LANGUAGE from hassUtils object * Move AppLocalizeBehavior import to mixins * Import mixins to state-card-display * Safety check on computeStateDisplay * Don't store computed domains on stateObj * Integration tests for state-card-display * Include extractDomain code in polymer repo * Remove util function null checking * Dont render test element without hass and stateObj * Revert "Don't store computed domains on stateObj" This reverts commite3509d7182
. * Revert "Always recalculate state display" This reverts commit27c24e2694
.
This commit is contained in:
parent
7e77a7c32c
commit
3412edb843
|
@ -0,0 +1,7 @@
|
|||
export default function computeDomain(stateObj) {
|
||||
if (!stateObj._domain) {
|
||||
stateObj._domain = stateObj.entity_id.substr(0, stateObj.entity_id.indexOf('.'));
|
||||
}
|
||||
|
||||
return stateObj._domain;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import computeDomain from './compute_domain';
|
||||
import formatDateTime from './format_date_time';
|
||||
import formatDate from './format_date';
|
||||
import formatTime from './format_time';
|
||||
|
||||
export default function computeStateDisplay(haLocalize, stateObj, language) {
|
||||
if (!stateObj._stateDisplay) {
|
||||
const domain = computeDomain(stateObj);
|
||||
if (domain === 'binary_sensor') {
|
||||
// Try device class translation, then default binary sensor translation
|
||||
if (stateObj.attributes.device_class) {
|
||||
stateObj._stateDisplay =
|
||||
haLocalize(`state.${domain}.${stateObj.attributes.device_class}`, stateObj.state);
|
||||
}
|
||||
if (!stateObj._stateDisplay) {
|
||||
stateObj._stateDisplay = haLocalize(`state.${domain}.default`, stateObj.state);
|
||||
}
|
||||
} else if (stateObj.attributes.unit_of_measurement) {
|
||||
stateObj._stateDisplay = stateObj.state + ' ' + stateObj.attributes.unit_of_measurement;
|
||||
} else if (domain === 'input_datetime') {
|
||||
let date;
|
||||
if (!stateObj.attributes.has_time) {
|
||||
date = new Date(
|
||||
stateObj.attributes.year,
|
||||
stateObj.attributes.month - 1,
|
||||
stateObj.attributes.day
|
||||
);
|
||||
stateObj._stateDisplay = formatDate(date, language);
|
||||
} else if (!stateObj.attributes.has_date) {
|
||||
date = new Date(
|
||||
1970, 0, 1,
|
||||
stateObj.attributes.hour,
|
||||
stateObj.attributes.minute
|
||||
);
|
||||
stateObj._stateDisplay = formatTime(date, language);
|
||||
} else {
|
||||
date = new Date(
|
||||
stateObj.attributes.year, stateObj.attributes.month - 1,
|
||||
stateObj.attributes.day, stateObj.attributes.hour,
|
||||
stateObj.attributes.minute
|
||||
);
|
||||
stateObj._stateDisplay = formatDateTime(date, language);
|
||||
}
|
||||
} else if (domain === 'zwave') {
|
||||
if (['initializing', 'dead'].includes(stateObj.state)) {
|
||||
stateObj._stateDisplay = haLocalize('state.zwave.query_stage', stateObj.state, 'query_stage', stateObj.attributes.query_stage);
|
||||
} else {
|
||||
stateObj._stateDisplay = haLocalize('state.zwave.default', stateObj.state);
|
||||
}
|
||||
} else {
|
||||
stateObj._stateDisplay = haLocalize(`state.${domain}`, stateObj.state);
|
||||
}
|
||||
// Fall back to default or raw state if nothing else matches.
|
||||
stateObj._stateDisplay = stateObj._stateDisplay
|
||||
|| haLocalize('state.default', stateObj.state) || stateObj.state;
|
||||
}
|
||||
|
||||
return stateObj._stateDisplay;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Check for support of native locale string options
|
||||
function toLocaleDateStringSupportsOptions() {
|
||||
try {
|
||||
new Date().toLocaleDateString('i');
|
||||
} catch (e) {
|
||||
return e.name === 'RangeError';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export default (toLocaleDateStringSupportsOptions() ?
|
||||
function (dateObj, locales) {
|
||||
return dateObj.toLocaleDateString(
|
||||
locales,
|
||||
{ year: 'numeric', month: 'long', day: 'numeric' },
|
||||
);
|
||||
} : function (dateObj, locales) { // eslint-disable-line no-unused-vars
|
||||
return window.fecha.format(dateObj, 'mediumDate');
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
// Check for support of native locale string options
|
||||
function toLocaleStringSupportsOptions() {
|
||||
try {
|
||||
new Date().toLocaleString('i');
|
||||
} catch (e) {
|
||||
return e.name === 'RangeError';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export default (toLocaleStringSupportsOptions() ?
|
||||
function (dateObj, locales) {
|
||||
return dateObj.toLocaleString(locales, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
});
|
||||
} : function (dateObj, locales) { // eslint-disable-line no-unused-vars
|
||||
return window.fecha.format(dateObj, 'haDateTime');
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
// Check for support of native locale string options
|
||||
function toLocaleTimeStringSupportsOptions() {
|
||||
try {
|
||||
new Date().toLocaleTimeString('i');
|
||||
} catch (e) {
|
||||
return e.name === 'RangeError';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export default (toLocaleTimeStringSupportsOptions() ?
|
||||
function (dateObj, locales) {
|
||||
return dateObj.toLocaleTimeString(
|
||||
locales,
|
||||
{ hour: 'numeric', minute: '2-digit' }
|
||||
);
|
||||
} : function (dateObj, locales) { // eslint-disable-line no-unused-vars
|
||||
return window.fecha.format(dateObj, 'shortTime');
|
||||
});
|
15
js/util.js
15
js/util.js
|
@ -7,7 +7,22 @@
|
|||
*/
|
||||
|
||||
import attributeClassNames from './common/util/attribute_class_names';
|
||||
import computeDomain from './common/util/compute_domain';
|
||||
import computeStateDisplay from './common/util/compute_state_display';
|
||||
import formatDate from './common/util/format_date';
|
||||
import formatDateTime from './common/util/format_date_time';
|
||||
import formatTime from './common/util/format_time';
|
||||
|
||||
window.hassUtil = window.hassUtil || {};
|
||||
|
||||
const language = navigator.languages ?
|
||||
navigator.languages[0] : navigator.language || navigator.userLanguage;
|
||||
|
||||
window.fecha.masks.haDateTime = window.fecha.masks.shortTime + ' ' + window.fecha.masks.mediumDate;
|
||||
|
||||
window.hassUtil.attributeClassNames = attributeClassNames;
|
||||
window.hassUtil.computeDomain = computeDomain;
|
||||
window.hassUtil.computeStateDisplay = computeStateDisplay;
|
||||
window.hassUtil.formatDate = dateObj => formatDate(dateObj, language);
|
||||
window.hassUtil.formatDateTime = dateObj => formatDateTime(dateObj, language);
|
||||
window.hassUtil.formatTime = dateObj => formatTime(dateObj, language);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<link rel="import" href="../cards/ha-badges-card.html">
|
||||
<link rel="import" href="../cards/ha-card-chooser.html">
|
||||
|
||||
<link rel="import" href="../util/hass-util.html">
|
||||
|
||||
<dom-module id="ha-cards">
|
||||
<template>
|
||||
<style is="custom-style" include="iron-flex iron-flex-factors"></style>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<script>
|
||||
Polymer.setPassiveTouchGestures(true);
|
||||
</script>
|
||||
<link rel='import' href='../bower_components/app-localize-behavior/app-localize-behavior.html'>
|
||||
<link rel='import' href='./util/roboto.html'>
|
||||
<link rel='import' href='../bower_components/paper-styles/typography.html'>
|
||||
<link rel='import' href='../bower_components/iron-flex-layout/iron-flex-layout-classes.html'>
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
|
||||
<link rel="import" href="../components/entity/state-info.html">
|
||||
<link rel="import" href="../util/hass-mixins.html">
|
||||
<link rel="import" href="../util/hass-util.html">
|
||||
|
||||
<dom-module id="state-card-display">
|
||||
<template>
|
||||
|
@ -20,7 +22,7 @@
|
|||
|
||||
<div class='horizontal justified layout'>
|
||||
<state-info state-obj="[[stateObj]]" in-dialog='[[inDialog]]'></state-info>
|
||||
<div class='state'>[[computeStateDisplay(haLocalize, stateObj)]]</div>
|
||||
<div class='state'>[[computeStateDisplay(haLocalize, stateObj, language)]]</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
@ -40,55 +42,8 @@ class StateCardDisplay extends window.hassMixins.LocalizeMixin(Polymer.Element)
|
|||
};
|
||||
}
|
||||
|
||||
computeStateDisplay(haLocalize, stateObj) {
|
||||
if (!stateObj._stateDisplay) {
|
||||
const domain = window.hassUtil.computeDomain(stateObj);
|
||||
if (domain === 'binary_sensor') {
|
||||
// Try device class translation, then default binary sensor translation
|
||||
stateObj._stateDisplay =
|
||||
haLocalize(`state.${domain}.${stateObj.attributes.device_class}`, stateObj.state)
|
||||
|| haLocalize(`state.${domain}.default`, stateObj.state);
|
||||
} else if (stateObj.attributes.unit_of_measurement) {
|
||||
stateObj._stateDisplay = stateObj.state + ' ' + stateObj.attributes.unit_of_measurement;
|
||||
} else if (domain === 'input_datetime') {
|
||||
let date;
|
||||
if (!stateObj.attributes.has_time) {
|
||||
date = new Date(
|
||||
stateObj.attributes.year,
|
||||
stateObj.attributes.month - 1,
|
||||
stateObj.attributes.day
|
||||
);
|
||||
stateObj._stateDisplay = window.hassUtil.formatDate(date);
|
||||
} else if (!stateObj.attributes.has_date) {
|
||||
date = new Date(
|
||||
1970, 0, 1,
|
||||
stateObj.attributes.hour,
|
||||
stateObj.attributes.minute
|
||||
);
|
||||
stateObj._stateDisplay = window.hassUtil.formatTime(date);
|
||||
} else {
|
||||
date = new Date(
|
||||
stateObj.attributes.year, stateObj.attributes.month - 1,
|
||||
stateObj.attributes.day, stateObj.attributes.hour,
|
||||
stateObj.attributes.minute
|
||||
);
|
||||
stateObj._stateDisplay = window.hassUtil.formatDateTime(date);
|
||||
}
|
||||
} else if (domain === 'zwave') {
|
||||
if (['initializing', 'dead'].includes(stateObj.state)) {
|
||||
stateObj._stateDisplay = haLocalize('state.zwave.query_stage', stateObj.state, 'query_stage', stateObj.attributes.query_stage);
|
||||
} else {
|
||||
stateObj._stateDisplay = haLocalize('state.zwave.default', stateObj.state);
|
||||
}
|
||||
} else {
|
||||
stateObj._stateDisplay = haLocalize(`state.${domain}`, stateObj.state);
|
||||
}
|
||||
// Fall back to default or raw state if nothing else matches.
|
||||
stateObj._stateDisplay = stateObj._stateDisplay
|
||||
|| haLocalize('state.default', stateObj.state) || stateObj.state;
|
||||
}
|
||||
|
||||
return stateObj._stateDisplay;
|
||||
computeStateDisplay(haLocalize, stateObj, language) {
|
||||
return window.hassUtil.computeStateDisplay(haLocalize, stateObj, language);
|
||||
}
|
||||
}
|
||||
customElements.define(StateCardDisplay.is, StateCardDisplay);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<link rel='import' href='../../bower_components/app-localize-behavior/app-localize-behavior.html'>
|
||||
|
||||
<script>
|
||||
|
||||
// Polymer legacy event helpers used courtesy of the Polymer project.
|
||||
|
|
|
@ -36,9 +36,6 @@ window.hassUtil.HIDE_MORE_INFO = [
|
|||
'input_select', 'scene', 'input_number', 'input_text'
|
||||
];
|
||||
|
||||
window.hassUtil.LANGUAGE = navigator.languages ?
|
||||
navigator.languages[0] : navigator.language || navigator.userLanguage;
|
||||
|
||||
// Expects featureClassNames to be an object mapping feature-bit -> className
|
||||
window.hassUtil.featureClassNames = function (stateObj, featureClassNames) {
|
||||
if (!stateObj || !stateObj.attributes.supported_features) return '';
|
||||
|
@ -107,77 +104,6 @@ window.hassUtil.dynamicContentUpdater = function (root, newElementTag, attribute
|
|||
}
|
||||
};
|
||||
|
||||
// Check for support of native locale string options
|
||||
function toLocaleStringSupportsOptions() {
|
||||
try {
|
||||
new Date().toLocaleString('i');
|
||||
} catch (e) {
|
||||
return e.name === 'RangeError';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function toLocaleDateStringSupportsOptions() {
|
||||
try {
|
||||
new Date().toLocaleDateString('i');
|
||||
} catch (e) {
|
||||
return e.name === 'RangeError';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function toLocaleTimeStringSupportsOptions() {
|
||||
try {
|
||||
new Date().toLocaleTimeString('i');
|
||||
} catch (e) {
|
||||
return e.name === 'RangeError';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
window.fecha.masks.haDateTime = (window.fecha.masks.shortTime + ' ' +
|
||||
window.fecha.masks.mediumDate);
|
||||
|
||||
if (toLocaleStringSupportsOptions()) {
|
||||
window.hassUtil.formatDateTime = function (dateObj) {
|
||||
return dateObj.toLocaleString(window.hassUtil.LANGUAGE, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
});
|
||||
};
|
||||
} else {
|
||||
window.hassUtil.formatDateTime = function (dateObj) {
|
||||
return window.fecha.format(dateObj, 'haDateTime');
|
||||
};
|
||||
}
|
||||
|
||||
if (toLocaleDateStringSupportsOptions()) {
|
||||
window.hassUtil.formatDate = function (dateObj) {
|
||||
return dateObj.toLocaleDateString(
|
||||
window.hassUtil.LANGUAGE,
|
||||
{ year: 'numeric', month: 'long', day: 'numeric' }
|
||||
);
|
||||
};
|
||||
} else {
|
||||
window.hassUtil.formatDate = function (dateObj) {
|
||||
return window.fecha.format(dateObj, 'mediumDate');
|
||||
};
|
||||
}
|
||||
|
||||
if (toLocaleTimeStringSupportsOptions()) {
|
||||
window.hassUtil.formatTime = function (dateObj) {
|
||||
return dateObj.toLocaleTimeString(
|
||||
window.hassUtil.LANGUAGE,
|
||||
{ hour: 'numeric', minute: '2-digit' }
|
||||
);
|
||||
};
|
||||
} else {
|
||||
window.hassUtil.formatTime = function (dateObj) {
|
||||
return window.fecha.format(dateObj, 'shortTime');
|
||||
};
|
||||
}
|
||||
|
||||
window.hassUtil.relativeTime = function (dateObj) {
|
||||
var delta = Math.abs(new Date() - dateObj) / 1000;
|
||||
var format = new Date() > dateObj ? '%s ago' : 'in %s';
|
||||
|
@ -437,14 +363,6 @@ window.hassUtil.stateIcon = function (state) {
|
|||
return window.hassUtil.domainIcon(domain, state.state);
|
||||
};
|
||||
|
||||
window.hassUtil.computeDomain = function (stateObj) {
|
||||
if (!stateObj._domain) {
|
||||
stateObj._domain = window.HAWS.extractDomain(stateObj.entity_id);
|
||||
}
|
||||
|
||||
return stateObj._domain;
|
||||
};
|
||||
|
||||
window.hassUtil.computeObjectId = function (stateObj) {
|
||||
if (!stateObj._object_id) {
|
||||
stateObj._object_id = window.HAWS.extractObjectId(stateObj.entity_id);
|
||||
|
|
|
@ -5,14 +5,14 @@ const assert = require('assert');
|
|||
describe('attributeClassNames', function() {
|
||||
const attrs = ['mock_attr1', 'mock_attr2'];
|
||||
|
||||
it('null state', function() {
|
||||
it('Skips null states', function() {
|
||||
const stateObj = null;
|
||||
assert.strictEqual(
|
||||
attributeClassNames(stateObj, attrs),
|
||||
'');
|
||||
});
|
||||
|
||||
it('matches no attrbutes', function() {
|
||||
it('Matches no attrbutes', function() {
|
||||
const stateObj = {
|
||||
attributes: {
|
||||
other_attr_1: 1,
|
||||
|
@ -24,7 +24,7 @@ describe('attributeClassNames', function() {
|
|||
'');
|
||||
});
|
||||
|
||||
it('matches one attrbute', function() {
|
||||
it('Matches one attrbute', function() {
|
||||
const stateObj = {
|
||||
attributes: {
|
||||
other_attr_1: 1,
|
||||
|
@ -37,7 +37,7 @@ describe('attributeClassNames', function() {
|
|||
'has-mock_attr1');
|
||||
});
|
||||
|
||||
it('matches two attrbutes', function() {
|
||||
it('Matches two attrbutes', function() {
|
||||
const stateObj = {
|
||||
attributes: {
|
||||
other_attr_1: 1,
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import computeDomain from '../../../js/common/util/compute_domain';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
describe('computeDomain', function() {
|
||||
it('Detects sensor domain', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'sensor.test',
|
||||
};
|
||||
assert.strictEqual(computeDomain(stateObj), 'sensor');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,184 @@
|
|||
import computeStateDisplay from '../../../js/common/util/compute_state_display';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
describe('computeStateDisplay', function() {
|
||||
const haLocalize = function(namespace, message, ...args) {
|
||||
// Mock Localize function for testing
|
||||
return namespace + '.' + message + (args.length ? ': ' + args.join(',') : '');
|
||||
};
|
||||
|
||||
it('Localizes binary sensor defaults', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'binary_sensor.test',
|
||||
state: 'off',
|
||||
attributes: {
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'state.binary_sensor.default.off');
|
||||
});
|
||||
|
||||
it('Localizes binary sensor device class', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'binary_sensor.test',
|
||||
state: 'off',
|
||||
attributes: {
|
||||
device_class: 'moisture',
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'state.binary_sensor.moisture.off');
|
||||
});
|
||||
|
||||
it('Localizes binary sensor invalid device class', function() {
|
||||
const altHaLocalize = function(namespace, message, ...args) {
|
||||
if (namespace === 'state.binary_sensor.invalid_device_class') return null;
|
||||
return haLocalize(namespace, message, ...args);
|
||||
};
|
||||
const stateObj = {
|
||||
entity_id: 'binary_sensor.test',
|
||||
state: 'off',
|
||||
attributes: {
|
||||
device_class: 'invalid_device_class',
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(altHaLocalize, stateObj, 'en'), 'state.binary_sensor.default.off');
|
||||
});
|
||||
|
||||
it('Localizes sensor value with units', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'sensor.test',
|
||||
state: '123',
|
||||
attributes: {
|
||||
unit_of_measurement: 'm',
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), '123 m');
|
||||
});
|
||||
|
||||
it('Localizes input_datetime with full date time', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'input_datetime.test',
|
||||
state: '123',
|
||||
attributes: {
|
||||
has_date: true,
|
||||
has_time: true,
|
||||
year: 2017,
|
||||
month: 11,
|
||||
day: 18,
|
||||
hour: 11,
|
||||
minute: 12,
|
||||
second: 13,
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'November 18, 2017, 11:12 AM');
|
||||
});
|
||||
|
||||
it('Localizes input_datetime with date', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'input_datetime.test',
|
||||
state: '123',
|
||||
attributes: {
|
||||
has_date: true,
|
||||
has_time: false,
|
||||
year: 2017,
|
||||
month: 11,
|
||||
day: 18,
|
||||
hour: 11,
|
||||
minute: 12,
|
||||
second: 13,
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'November 18, 2017');
|
||||
});
|
||||
|
||||
it('Localizes input_datetime with time', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'input_datetime.test',
|
||||
state: '123',
|
||||
attributes: {
|
||||
has_date: false,
|
||||
has_time: true,
|
||||
year: 2017,
|
||||
month: 11,
|
||||
day: 18,
|
||||
hour: 11,
|
||||
minute: 12,
|
||||
second: 13,
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), '11:12 AM');
|
||||
});
|
||||
|
||||
it('Localizes zwave ready', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'zwave.test',
|
||||
state: 'ready',
|
||||
attributes: {
|
||||
query_stage: 'Complete',
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'state.zwave.default.ready');
|
||||
});
|
||||
|
||||
it('Localizes zwave initializing', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'zwave.test',
|
||||
state: 'initializing',
|
||||
attributes: {
|
||||
query_stage: 'Probe',
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'state.zwave.query_stage.initializing: query_stage,Probe');
|
||||
});
|
||||
|
||||
it('Localizes cover open', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'cover.test',
|
||||
state: 'open',
|
||||
attributes: {
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'state.cover.open');
|
||||
});
|
||||
|
||||
it('Localizes unavailable', function() {
|
||||
const altHaLocalize = function(namespace, message, ...args) {
|
||||
if (namespace === 'state.sensor') return null;
|
||||
return haLocalize(namespace, message, ...args);
|
||||
};
|
||||
const stateObj = {
|
||||
entity_id: 'sensor.test',
|
||||
state: 'unavailable',
|
||||
attributes: {
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(altHaLocalize, stateObj, 'en'), 'state.default.unavailable');
|
||||
});
|
||||
|
||||
it('Localizes custom state', function() {
|
||||
const altHaLocalize = function(namespace, message, ...args) {
|
||||
// No matches can be found
|
||||
return null;
|
||||
};
|
||||
const stateObj = {
|
||||
entity_id: 'sensor.test',
|
||||
state: 'My Custom State',
|
||||
attributes: {
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(altHaLocalize, stateObj, 'en'), 'My Custom State');
|
||||
});
|
||||
|
||||
it('Only calculates state display once per immutable state object', function() {
|
||||
const stateObj = {
|
||||
entity_id: 'cover.test',
|
||||
state: 'open',
|
||||
attributes: {
|
||||
},
|
||||
};
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'state.cover.open');
|
||||
|
||||
stateObj.state = 'closing';
|
||||
assert.strictEqual(computeStateDisplay(haLocalize, stateObj, 'en'), 'state.cover.open');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
import formatDate from '../../../js/common/util/format_date';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
describe('formatDate', function() {
|
||||
const dateObj = new Date(
|
||||
2017, 10, 18,
|
||||
11, 12, 13, 1400,
|
||||
);
|
||||
|
||||
it('Formats English dates', function() {
|
||||
assert.strictEqual(formatDate(dateObj, 'en'), 'November 18, 2017');
|
||||
});
|
||||
|
||||
// Node only contains intl support for english formats. This test at least ensures
|
||||
// the fallback to a different locale
|
||||
it('Formats other dates', function() {
|
||||
assert.strictEqual(formatDate(dateObj, 'fr'), '2017 M11 18');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
import formatDateTime from '../../../js/common/util/format_date_time';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
describe('formatDateTime', function() {
|
||||
const dateObj = new Date(
|
||||
2017, 10, 18,
|
||||
11, 12, 13, 1400,
|
||||
);
|
||||
|
||||
it('Formats English date times', function() {
|
||||
assert.strictEqual(formatDateTime(dateObj, 'en'), 'November 18, 2017, 11:12 AM');
|
||||
});
|
||||
|
||||
// Node only contains intl support for english formats. This test at least ensures
|
||||
// the fallback to a different locale
|
||||
it('Formats other date times', function() {
|
||||
assert.strictEqual(formatDateTime(dateObj, 'fr'), '2017 M11 18 11:12');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
import formatTime from '../../../js/common/util/format_time';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
describe('formatTime', function() {
|
||||
const dateObj = new Date(
|
||||
2017, 10, 18,
|
||||
11, 12, 13, 1400,
|
||||
);
|
||||
|
||||
it('Formats English times', function() {
|
||||
assert.strictEqual(formatTime(dateObj, 'en'), '11:12 AM');
|
||||
});
|
||||
|
||||
// Node only contains intl support for english formats. This test at least ensures
|
||||
// the fallback to a different locale
|
||||
it('Formats other times', function() {
|
||||
assert.strictEqual(formatTime(dateObj, 'fr'), '11:12');
|
||||
});
|
||||
});
|
|
@ -11,6 +11,8 @@
|
|||
WCT.loadSuites([
|
||||
'state-info-test.html?dom=shadow',
|
||||
'state-info-test.html?dom=shady',
|
||||
'state-card-display-test.html?dom=shadow',
|
||||
'state-card-display-test.html?dom=shady',
|
||||
]);
|
||||
</script>
|
||||
</body></html>
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
|
||||
<script src="../../web-component-tester/browser.js"></script>
|
||||
|
||||
<!--
|
||||
Temporarily load core.js here so window.HAWS is available. We can remove
|
||||
this once hass-util includes the helper function directly.
|
||||
-->
|
||||
<script src="../build/core.js"></script>
|
||||
<link rel="import" href="../src/state-summary/state-card-display.html">
|
||||
</head>
|
||||
<body>
|
||||
<test-fixture id="stateCardDisplay">
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
function lightOrShadow(elem, selector) {
|
||||
return elem.shadowRoot ?
|
||||
elem.shadowRoot.querySelector(selector) :
|
||||
elem.querySelector(selector);
|
||||
}
|
||||
|
||||
suite('state-card-display', function() {
|
||||
let wrapper;
|
||||
let card;
|
||||
|
||||
setup(function() {
|
||||
wrapper = fixture('stateCardDisplay');
|
||||
card = new StateCardDisplay();
|
||||
card.stateObj = {
|
||||
entity_id: 'binary_sensor.demo',
|
||||
state: 'off',
|
||||
attributes: {
|
||||
device_class: 'moisture',
|
||||
},
|
||||
};
|
||||
card.hass = {
|
||||
language: 'en',
|
||||
resources: {
|
||||
'en': {
|
||||
'state.binary_sensor.moisture.off': 'Mock Off Text',
|
||||
},
|
||||
},
|
||||
};
|
||||
wrapper.appendChild(card);
|
||||
});
|
||||
|
||||
test('state display text', function(done) {
|
||||
flush(function() {
|
||||
const stateDiv = lightOrShadow(card, '.state');
|
||||
assert.isOk(stateDiv);
|
||||
assert.deepEqual(stateDiv.innerText, 'Mock Off Text');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -29,10 +29,6 @@
|
|||
|
||||
setup(function() {
|
||||
si = fixture('stateInfo');
|
||||
window.HAWS = {};
|
||||
window.HAWS.extractDomain = function (entityId) {
|
||||
return entityId.substr(0, entityId.indexOf('.'));
|
||||
};
|
||||
});
|
||||
|
||||
test('default values', function() {
|
||||
|
|
Loading…
Reference in New Issue