UNPKG

pimatic

Version:

A home automation server and framework for the Raspberry PI running on node.js

606 lines (515 loc) 17.8 kB
cassert = require "cassert" assert = require "assert" events = require "events" Promise = require 'bluebird' _ = require 'lodash' t = require('decl-api').types M = require '../lib/matcher' # Setup the environment env = require('../startup').env createDummyParseContext = -> variables = {} functions = {} return M.createParseContext(variables, functions) describe "PresencePredicateProvider", -> frameworkDummy = deviceManager: devices: {} getDevices: -> _.values(@devices) provider = null sensorDummy = null before -> provider = new env.predicates.PresencePredicateProvider(frameworkDummy) class PresenceDummySensor extends env.devices.PresenceSensor constructor: () -> @id = 'test' @name = 'test device' super() sensorDummy = new PresenceDummySensor frameworkDummy.deviceManager.devices = test: sensorDummy describe '#parsePredicate()', -> testCases = [ { inputs: [ "test is present" "test device is present" "test signals present" "test reports present" ] checkOutput: (input, result) -> assert result? assert.equal(result.token, input) assert.equal(result.nextInput, "") assert result.predicateHandler? assert.equal(result.predicateHandler.negated, no) assert.deepEqual(result.predicateHandler.device, sensorDummy) }, { inputs: [ "test is absent" "test is not present" "test device is not present" "test signals absent" "test reports absent" ] checkOutput: (input, result) -> assert result? assert.equal(result.token, input) assert.equal(result.nextInput, "") assert result.predicateHandler? assert.equal(result.predicateHandler.negated, yes) assert.deepEqual(result.predicateHandler.device, sensorDummy) } ] for testCase in testCases do (testCase) => for input in testCase.inputs do (input) => it "should parse \"#{input}\"", => context = createDummyParseContext() result = provider.parsePredicate(input, context) testCase.checkOutput(input, result) it 'should return null if id is wrong', -> result = provider.parsePredicate "foo is present" assert(not info?) describe "PresencePredicateHandler", -> describe '#on "change"', -> predicateHandler = null before -> context = createDummyParseContext() result = provider.parsePredicate("test is present", context) assert result? predicateHandler = result.predicateHandler predicateHandler.setup() after -> predicateHandler.destroy() it "should notify when device is present", (finish) -> sensorDummy._presence = no predicateHandler.once 'change', changeListener = (state)-> assert.equal state, true finish() sensorDummy._setPresence yes it "should notify when device is absent", (finish) -> sensorDummy._presence = yes predicateHandler.once 'change', changeListener = (state)-> assert.equal state, false finish() sensorDummy._setPresence no describe "ContactPredicateProvider", -> frameworkDummy = deviceManager: devices: {} getDevices: -> _.values(@devices) provider = null sensorDummy = null before -> provider = new env.predicates.ContactPredicateProvider(frameworkDummy) class ContactDummySensor extends env.devices.ContactSensor constructor: () -> @id = 'test' @name = 'test device' super() sensorDummy = new ContactDummySensor frameworkDummy.deviceManager.devices = test: sensorDummy describe '#parsePredicate()', -> testCases = [ { inputs: [ "test is closed" "test device is closed" "test is close" "test device is close" ] checkOutput: (input, result) -> assert result? assert.equal(result.token, input) assert.equal(result.nextInput, "") assert result.predicateHandler? assert.equal(result.predicateHandler.negated, no) assert.deepEqual(result.predicateHandler.device, sensorDummy) }, { inputs: [ "test is opened" "test device is opened" "test is open" "test device is open" ] checkOutput: (input, result) -> assert result? assert.equal(result.token, input) assert.equal(result.nextInput, "") assert result.predicateHandler? assert.equal(result.predicateHandler.negated, yes) assert.deepEqual(result.predicateHandler.device, sensorDummy) } ] for testCase in testCases do (testCase) => for input in testCase.inputs do (input) => it "should parse \"#{input}\"", => context = createDummyParseContext() result = provider.parsePredicate(input, context) testCase.checkOutput(input, result) it 'should return null if id is wrong', -> result = provider.parsePredicate "foo is closed" assert(not info?) describe "PresencePredicateHandler", -> describe '#on "change"', -> predicateHandler = null before -> context = createDummyParseContext() result = provider.parsePredicate("test is closed", context) assert result? predicateHandler = result.predicateHandler predicateHandler.setup() after -> predicateHandler.destroy() it "should notify when device is opened", (finish) -> sensorDummy._contact = no predicateHandler.once 'change', changeListener = (state)-> assert.equal state, true finish() sensorDummy._setContact yes it "should notify when device is closed", (finish) -> sensorDummy._contact = yes predicateHandler.once 'change', changeListener = (state)-> assert.equal state, false finish() sensorDummy._setContact no describe "SwitchPredicateProvider", -> frameworkDummy = deviceManager: devices: {} getDevices: -> _.values(@devices) provider = null switchDummy = null before -> provider = new env.predicates.SwitchPredicateProvider(frameworkDummy) class SwitchDummyDevice extends env.devices.SwitchActuator constructor: () -> @id = 'test' @name = 'test device' @_state = on super() switchDummy = new SwitchDummyDevice() frameworkDummy.deviceManager.devices = test: switchDummy describe '#parsePredicate()', -> testCases = [ { inputs: [ "test is on" "test device is on" "test is turned on" "test is switched on" ] checkOutput: (input, result) -> assert result? assert.equal(result.token, input) assert.equal(result.nextInput, "") assert result.predicateHandler? assert.equal(result.predicateHandler.state, on) assert.deepEqual(result.predicateHandler.device, switchDummy) }, { inputs: [ "test is off" "test device is off" "test is turned off" "test is switched off" ] checkOutput: (input, result) -> assert result? assert.equal(result.token, input) assert.equal(result.nextInput, "") assert result.predicateHandler? assert.equal(result.predicateHandler.state, off) assert.deepEqual(result.predicateHandler.device, switchDummy) } ] for testCase in testCases do (testCase) => for input in testCase.inputs do (input) => it "should parse \"#{input}\"", => context = createDummyParseContext() result = provider.parsePredicate input, context testCase.checkOutput(input, result) describe "SwitchPredicateHandler", -> describe '#on "change"', -> predicateHandler = null before -> context = createDummyParseContext() result = provider.parsePredicate "test is on", context assert result? predicateHandler = result.predicateHandler predicateHandler.setup() after -> predicateHandler.destroy() it "should notify when switch is on", (finish) -> switchDummy._state = off predicateHandler.once 'change', changeListener = (state)-> assert.equal state, on finish() switchDummy._setState on it "should notify when switch is off", (finish) -> switchDummy._state = on predicateHandler.once 'change', changeListener = (state)-> assert.equal state, off finish() switchDummy._setState off describe "DeviceAttributePredicateProvider", -> frameworkDummy = deviceManager: devices: {} getDevices: -> _.values(@devices) provider = null sensorDummy = null before -> provider = new env.predicates.DeviceAttributePredicateProvider(frameworkDummy) class DummySensor extends env.devices.Sensor attributes: testvalue: description: "a testvalue" type: t.number unit: '°C' constructor: () -> @id = 'test' @name = 'test sensor' super() sensorDummy = new DummySensor() frameworkDummy.deviceManager.devices = test: sensorDummy describe '#parsePredicate()', -> comparators = 'is': '==' 'is equal': '==' 'is equal to': '==' 'equals': '==' 'is not': '!=' 'is less': '<' 'less': '<' 'less than': '<' 'is less than': '<' 'lower as': '<' 'lower': '<' 'is lower': '<' 'below': '<' 'is below': '<' 'is above': '>' 'above': '>' 'greater': '>' 'higher': '>' 'greater than': '>' 'is greater than': '>' 'is greater or equal than': '>=' 'is equal or greater than': '>=' 'is less or equal than': '<=' 'is equal or less than': '<=' for comp, sign of comparators do (comp, sign) -> testPredicate = "testvalue of test sensor #{comp} 42" it "should parse \"#{testPredicate}\"", -> context = createDummyParseContext() result = provider.parsePredicate testPredicate, context cassert result? cassert result.predicateHandler? predHandler = result.predicateHandler cassert predHandler.device.id is "test" cassert predHandler.comparator is sign cassert predHandler.attribute is 'testvalue' cassert predHandler.referenceValue is 42 cassert result.token is testPredicate cassert result.nextInput is "" it "should parse predicate with unit: testvalue of test sensor is 42 °C", -> context = createDummyParseContext() result = provider.parsePredicate "testvalue of test sensor is 42 °C", context cassert result? cassert result.predicateHandler? predHandler = result.predicateHandler cassert predHandler.device.id is "test" cassert predHandler.comparator is "==" cassert predHandler.attribute is 'testvalue' cassert predHandler.referenceValue is 42 cassert result.token is "testvalue of test sensor is 42 °C" cassert result.nextInput is "" it "should parse predicate with unit: testvalue of test sensor is 42 C", -> context = createDummyParseContext() result = provider.parsePredicate "testvalue of test sensor is 42 C", context cassert result? cassert result.predicateHandler? predHandler = result.predicateHandler cassert predHandler.device.id is "test" cassert predHandler.comparator is "==" cassert predHandler.attribute is 'testvalue' cassert predHandler.referenceValue is 42 cassert result.token is "testvalue of test sensor is 42 C" cassert result.nextInput is "" describe "DeviceAttributePredicateHandler", -> describe '#on "change"', -> predicateHandler = null before -> context = createDummyParseContext() result = provider.parsePredicate "testvalue of test is greater than 20", context assert result? predicateHandler = result.predicateHandler predicateHandler.setup() after -> predicateHandler.destroy() it "should notify when value is greater than 20 and value is 21", (finish) -> predicateHandler.once 'change', (state) -> cassert state is true finish() sensorDummy.emit 'testvalue', 21 it "should notify when value is greater than 20 and value is 19", (finish) -> predicateHandler.once 'change', (state)-> cassert state is false finish() sensorDummy.emit 'testvalue', 19 describe "VariablePredicateProvider", -> frameworkDummy = new events.EventEmitter() frameworkDummy.variableManager = new env.variables.VariableManager(frameworkDummy, [ { name: 'a' value: '1' }, { name: 'b' value: '2' }, { name: 'c', value: '3' } ]) frameworkDummy.variableManager.init() provider = null sensorDummy = null before -> provider = new env.predicates.VariablePredicateProvider(frameworkDummy) class DummySensor extends env.devices.Sensor attributes: testvalue: description: "a testvalue" type: t.number unit: '°C' constructor: () -> @id = 'test' @name = 'test sensor' super() getTestvalue: -> Promise.resolve(42) sensorDummy = new DummySensor() frameworkDummy.emit 'deviceAdded', sensorDummy describe '#parsePredicate()', -> testCases = [ { input: "1 + 2 < 4" result: value: true } { input: "1 + 3 <= 4" result: value: true } { input: "1 + 3 > 4" result: value: false } { input: "$a + 2 == 3" result: value: true } { input: "$a + 2 == 1 + $b" result: value: true } { input: "$a == $b - 1" result: value: true } { input: "$test.testvalue == 42" result: value: true } { input: "$test.testvalue == 21" result: value: false } ] for tc in testCases do (tc) => it "should parse \"#{tc.input}\"", (finish) => context = createDummyParseContext() varsAndFuns = frameworkDummy.variableManager.getVariablesAndFunctions() context.variables = varsAndFuns.variables context.functions = varsAndFuns.functions result = provider.parsePredicate(tc.input, context) assert result? result.predicateHandler.getValue().then( (val) => assert.equal val, tc.result.value finish() ).catch(finish) return describe "VariablePredicateHandler", -> describe '#on "change"', -> predicateHandler = null after -> predicateHandler.destroy() it "should notify when $a is greater than 20", (finish) -> context = createDummyParseContext() varsAndFuns = frameworkDummy.variableManager.getVariablesAndFunctions() context.variables = varsAndFuns.variables context.functions = varsAndFuns.functions result = provider.parsePredicate "$a > 20", context assert result? predicateHandler = result.predicateHandler predicateHandler.setup() predicateHandler.once 'change', (state) -> cassert state is true finish() frameworkDummy.variableManager.setVariableToValue('a', '21') describe '#on "change"', -> predicateHandler = null after -> predicateHandler.destroy() it "should notify when $test.testvalue is greater than 42", (finish) -> context = createDummyParseContext() varsAndFuns = frameworkDummy.variableManager.getVariablesAndFunctions() context.variables = varsAndFuns.variables context.functions = varsAndFuns.functions result = provider.parsePredicate "$test.testvalue > 42", context assert result? predicateHandler = result.predicateHandler predicateHandler.setup() predicateHandler.once 'change', (state) -> cassert state is true finish() sensorDummy.getTestvalue = => Promise.resolve(50) sensorDummy.emit 'testvalue', 50 # describe '#on "change"', -> # predicateHandler = null # after -> predicateHandler.destroy() # it "should throw an error, when comparing strings", (finish) -> # context = createDummyParseContext() # varsAndFuns = frameworkDummy.variableManager.getVariablesAndFunctions() # context.variables = varsAndFuns.variables # context.functions = varsAndFuns.functions # result = provider.parsePredicate "$test.testvalue > 42", context # assert result? # predicateHandler = result.predicateHandler # predicateHandler.setup() # predicateHandler.once 'change', (state) -> # cassert state is true # finish() # sensorDummy.getTestvalue = => Promise.resolve("a") # sensorDummy.attributes.testvalue.type = "string" # sensorDummy.emit 'testvalue', "a"