pimatic
Version:
A home automation server and framework for the Raspberry PI running on node.js
606 lines (515 loc) • 17.8 kB
text/coffeescript
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()
provider = null
sensorDummy = null
before ->
provider = new env.predicates.PresencePredicateProvider(frameworkDummy)
class PresenceDummySensor extends env.devices.PresenceSensor
constructor: () ->
= 'test'
= '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()
provider = null
sensorDummy = null
before ->
provider = new env.predicates.ContactPredicateProvider(frameworkDummy)
class ContactDummySensor extends env.devices.ContactSensor
constructor: () ->
= 'test'
= '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()
provider = null
switchDummy = null
before ->
provider = new env.predicates.SwitchPredicateProvider(frameworkDummy)
class SwitchDummyDevice extends env.devices.SwitchActuator
constructor: () ->
= 'test'
= 'test device'
= 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()
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: () ->
= 'test'
= '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: () ->
= 'test'
= '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"