rspec-openhab-scripting 0.0.15-java → 0.0.18-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rspec/openhab/api.rb +18 -1
- data/lib/rspec/openhab/core/mocks/channel_type_provider.rb +30 -0
- data/lib/rspec/openhab/core/mocks/item_channel_link_provider.rb +36 -0
- data/lib/rspec/openhab/core/mocks/persistence_service.rb +144 -0
- data/lib/rspec/openhab/core/mocks/thing_handler.rb +48 -0
- data/lib/rspec/openhab/core/mocks/thing_type_provider.rb +30 -0
- data/lib/rspec/openhab/core/osgi.rb +5 -1
- data/lib/rspec/openhab/dsl/imports.rb +114 -11
- data/lib/rspec/openhab/helpers.rb +7 -0
- data/lib/rspec/openhab/hooks.rb +2 -0
- data/lib/rspec/openhab/items.rb +166 -0
- data/lib/rspec/openhab/version.rb +1 -1
- data/lib/rspec-openhab-scripting.rb +10 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ea44768dd3bccdfc7276944f329030e21182d161126e433126970f096543f46
|
4
|
+
data.tar.gz: 81be4550cd3ab271f43e15616959709bb9e5d1cf14a999dd8565e0b148d3a8d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d70a68375f21fab304d05b620125cf79b5767f3522d5e22a0608301b56e4ed3b2f6baba7942bdfcdb9ffed742378452720b79b7bfc5d7523544087a0bcb15bc
|
7
|
+
data.tar.gz: d2ce66901858dc37eb7c76b5f37f82da6147f1b471b8fc70097037099d677eb01c6e4e25d77e12105847e28156a919e059d5420271f9ce5cfcb0c9af933b4383
|
data/lib/rspec/openhab/api.rb
CHANGED
@@ -4,11 +4,12 @@ require "faraday"
|
|
4
4
|
|
5
5
|
module OpenHAB
|
6
6
|
class API
|
7
|
-
def initialize(url)
|
7
|
+
def initialize(url, token = nil)
|
8
8
|
@faraday = Faraday.new(url) do |f|
|
9
9
|
f.response :raise_error
|
10
10
|
f.response :json
|
11
11
|
f.path_prefix = "/rest/"
|
12
|
+
f.headers = { "X-OPENHAB-TOKEN" => token } if token
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
@@ -36,6 +37,22 @@ module OpenHAB
|
|
36
37
|
nil
|
37
38
|
end
|
38
39
|
|
40
|
+
def channel_types
|
41
|
+
@faraday.get("channel-types").body
|
42
|
+
end
|
43
|
+
|
44
|
+
def thing_types
|
45
|
+
@faraday.get("thing-types").body
|
46
|
+
end
|
47
|
+
|
48
|
+
def things
|
49
|
+
@faraday.get("things").body
|
50
|
+
end
|
51
|
+
|
52
|
+
def authenticated?
|
53
|
+
@faraday.headers.key?("X-OPENHAB-TOKEN")
|
54
|
+
end
|
55
|
+
|
39
56
|
private
|
40
57
|
|
41
58
|
def root_data
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module OpenHAB
|
5
|
+
module Core
|
6
|
+
module Mocks
|
7
|
+
class ChannelTypeProvider
|
8
|
+
include org.openhab.core.thing.type.ChannelTypeProvider
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@types = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(type)
|
16
|
+
@types[type.uid] = type
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_channel_types(_locale)
|
20
|
+
@types.values
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_channel_type(uid, _locale)
|
24
|
+
@types[uid]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module OpenHAB
|
5
|
+
module Core
|
6
|
+
module Mocks
|
7
|
+
class ItemChannelLinkProvider
|
8
|
+
include org.openhab.core.thing.link.ItemChannelLinkProvider
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@listeners = []
|
13
|
+
@links = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_provider_change_listener(listener)
|
17
|
+
@listeners << listener
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove_provider_change_listener(listener)
|
21
|
+
@listeners.delete(listener)
|
22
|
+
end
|
23
|
+
|
24
|
+
def all
|
25
|
+
@links
|
26
|
+
end
|
27
|
+
|
28
|
+
def add(link)
|
29
|
+
@links << link
|
30
|
+
@listeners.each { |l| l.added(self, link) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module OpenHAB
|
5
|
+
module Core
|
6
|
+
module Mocks
|
7
|
+
class PersistenceService
|
8
|
+
include org.openhab.core.persistence.ModifiablePersistenceService
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
class HistoricItem
|
12
|
+
include org.openhab.core.persistence.HistoricItem
|
13
|
+
|
14
|
+
attr_reader :timestamp, :state, :name
|
15
|
+
|
16
|
+
def initialize(timestamp, state, name)
|
17
|
+
@timestamp = timestamp
|
18
|
+
@state = state
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :id
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@id = "default"
|
27
|
+
reset
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset
|
31
|
+
@data = Hash.new { |h, k| h[k] = [] }
|
32
|
+
end
|
33
|
+
|
34
|
+
def store(item, date = nil, state = nil)
|
35
|
+
date = nil if date.is_a?(String) # alias overload
|
36
|
+
state ||= item.state
|
37
|
+
date ||= ZonedDateTime.now
|
38
|
+
|
39
|
+
new_item = HistoricItem.new(date, state, item.name)
|
40
|
+
|
41
|
+
item_history = @data[item.name]
|
42
|
+
|
43
|
+
insert_index = item_history.bsearch_index do |i|
|
44
|
+
i.timestamp.compare_to(date).positive?
|
45
|
+
end
|
46
|
+
|
47
|
+
return item_history << new_item unless insert_index
|
48
|
+
|
49
|
+
return item_history[insert_index].state = state if item_history[insert_index].timestamp == date
|
50
|
+
|
51
|
+
item_history.insert(insert_index, new_item)
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove(filter)
|
55
|
+
query_internal(filter) do |item_history, index|
|
56
|
+
historic_item = item_history.delete_at(index)
|
57
|
+
@data.delete(historic_item.name) if item_history.empty?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def query(filter)
|
62
|
+
result = []
|
63
|
+
|
64
|
+
query_internal(filter) do |item_history, index|
|
65
|
+
result << item_history[index]
|
66
|
+
|
67
|
+
return result if filter.page_number.zero? && result.length == filter.page_size && filter.item_name
|
68
|
+
end
|
69
|
+
|
70
|
+
result.sort_by! { |hi| hi.timestamp.to_instant.to_epoch_milli } unless filter.item_name
|
71
|
+
|
72
|
+
unless filter.page_number.zero?
|
73
|
+
result = result.slice(filter.page_number * filter.page_size, filter.page_size)
|
74
|
+
end
|
75
|
+
|
76
|
+
result
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_item_info # rubocop:disable Naming/AccessorMethodName must match Java interface
|
80
|
+
@data.map do |(n, entries)|
|
81
|
+
[n, entries.length, entries.first.timestamp, entries.last.timestamp]
|
82
|
+
end.to_set
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_default_strategies # rubocop:disable Naming/AccessorMethodName must match Java interface
|
86
|
+
[org.openhab.core.persistence.strategy.PersistenceStrategy::Globals::CHANGE]
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def query_internal(filter, &block)
|
92
|
+
if filter.item_name
|
93
|
+
return unless @data.key?(filter.item_name)
|
94
|
+
|
95
|
+
query_item_internal(@data[filter.item_name], filter, &block)
|
96
|
+
else
|
97
|
+
@data.each_value do |item_history|
|
98
|
+
query_item_internal(item_history, filter, &block)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def query_item_internal(item_history, filter)
|
104
|
+
first_index = 0
|
105
|
+
last_index = item_history.length
|
106
|
+
|
107
|
+
if filter.begin_date
|
108
|
+
first_index = item_history.bsearch_index do |i|
|
109
|
+
i.timestamp.compare_to(filter.begin_date).positive?
|
110
|
+
end
|
111
|
+
return if first_index.nil?
|
112
|
+
end
|
113
|
+
|
114
|
+
if filter.end_date
|
115
|
+
last_index = item_history.bsearch_index do |i|
|
116
|
+
i.timestamp.compare_to(filter.end_date).positive?
|
117
|
+
end
|
118
|
+
return if last_index.zero?
|
119
|
+
|
120
|
+
last_index ||= item_history.length
|
121
|
+
end
|
122
|
+
|
123
|
+
range = first_index...last_index
|
124
|
+
|
125
|
+
operator = filter.operator.symbol
|
126
|
+
operator = "==" if operator == "="
|
127
|
+
|
128
|
+
block = lambda do |i|
|
129
|
+
next if filter.state && !item_history[i].state.send(operator, filter.state)
|
130
|
+
|
131
|
+
yield(item_history, i)
|
132
|
+
end
|
133
|
+
|
134
|
+
if filter.ordering == filter.class::Ordering::DESCENDING
|
135
|
+
range.reverse_each(&block)
|
136
|
+
else
|
137
|
+
range.each(&block)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Naming have to follow java interface names
|
4
|
+
module RSpec
|
5
|
+
module OpenHAB
|
6
|
+
module Core
|
7
|
+
module Mocks
|
8
|
+
class ThingHandler
|
9
|
+
include org.openhab.core.thing.binding.BridgeHandler
|
10
|
+
|
11
|
+
attr_reader :thing, :callback
|
12
|
+
|
13
|
+
def initialize(thing = nil)
|
14
|
+
# have to handle the interface method
|
15
|
+
if thing.nil?
|
16
|
+
status_info = org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder
|
17
|
+
.create(org.openhab.core.thing.ThingStatus::ONLINE).build
|
18
|
+
@callback.status_updated(self.thing, status_info)
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
# ruby initializer here
|
23
|
+
@thing = thing
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_command(channel, command); end
|
27
|
+
|
28
|
+
def set_callback(callback)
|
29
|
+
@callback = callback
|
30
|
+
end
|
31
|
+
|
32
|
+
def child_handler_initialized(child_handler, child_thing); end
|
33
|
+
end
|
34
|
+
|
35
|
+
class ThingHandlerFactory < org.openhab.core.thing.binding.BaseThingHandlerFactory
|
36
|
+
def supportsThingType(_type)
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def createHandler(thing)
|
41
|
+
ThingHandler.new(thing)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# rubocop:enable Naming
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module OpenHAB
|
5
|
+
module Core
|
6
|
+
module Mocks
|
7
|
+
class ThingTypeProvider
|
8
|
+
include org.openhab.core.thing.binding.ThingTypeProvider
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@types = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(type)
|
16
|
+
@types[type.uid] = type
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_thing_types(_locale)
|
20
|
+
@types.values
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_thing_type(uid, _locale)
|
24
|
+
@types[uid]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -4,7 +4,11 @@ module OpenHAB
|
|
4
4
|
module Core
|
5
5
|
class OSGI
|
6
6
|
class << self
|
7
|
-
def register_service(name, service)
|
7
|
+
def register_service(name, service = nil)
|
8
|
+
if service.nil?
|
9
|
+
service = name
|
10
|
+
name = service.java_class.interfaces.first&.name || service.java_class.name
|
11
|
+
end
|
8
12
|
(@services ||= {})[name] = service
|
9
13
|
end
|
10
14
|
|
@@ -68,6 +68,22 @@ module OpenHAB
|
|
68
68
|
def add_bundle_listener(listener); end
|
69
69
|
end
|
70
70
|
|
71
|
+
class BundleResolver
|
72
|
+
include org.openhab.core.util.BundleResolver
|
73
|
+
|
74
|
+
def initialize
|
75
|
+
@bundles = {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def register(klass, bundle)
|
79
|
+
@bundles[klass] = bundle
|
80
|
+
end
|
81
|
+
|
82
|
+
def resolve_bundle(klass)
|
83
|
+
@bundles[klass]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
71
87
|
# don't depend on org.openhab.core.test
|
72
88
|
class VolatileStorageService
|
73
89
|
include org.openhab.core.storage.StorageService
|
@@ -98,13 +114,15 @@ module OpenHAB
|
|
98
114
|
INSTALLED = 2
|
99
115
|
|
100
116
|
def initialize(*jar_args)
|
117
|
+
return if jar_args.empty?
|
118
|
+
|
101
119
|
file = Jars.find_jar(*jar_args)
|
102
120
|
@jar = java.util.jar.JarFile.new(file)
|
103
121
|
@symbolic_name = jar_args[1]
|
104
122
|
@version = org.osgi.framework.Version.new(jar_args[2].tr("-", "."))
|
105
123
|
end
|
106
124
|
|
107
|
-
|
125
|
+
attr_accessor :symbolic_name, :version
|
108
126
|
|
109
127
|
def state
|
110
128
|
INSTALLED
|
@@ -190,7 +208,7 @@ module OpenHAB
|
|
190
208
|
event_factory.create_event(type, topic, payload, source)
|
191
209
|
rescue Exception => e
|
192
210
|
logger.warn("Creation of event failed, because one of the " \
|
193
|
-
"registered event factories has thrown an exception: #{e}")
|
211
|
+
"registered event factories has thrown an exception: #{e.inspect}")
|
194
212
|
nil
|
195
213
|
end
|
196
214
|
|
@@ -201,7 +219,9 @@ module OpenHAB
|
|
201
219
|
begin
|
202
220
|
event_subscriber.receive(event)
|
203
221
|
rescue Exception => e
|
204
|
-
logger.warn(
|
222
|
+
logger.warn(
|
223
|
+
"Dispatching/filtering event for subscriber '#{event_subscriber.class}' failed: #{e.inspect}"
|
224
|
+
)
|
205
225
|
end
|
206
226
|
else
|
207
227
|
logger.trace("Skip event subscriber (#{event_subscriber.class}) because of its filter.")
|
@@ -217,7 +237,7 @@ module OpenHAB
|
|
217
237
|
include Singleton
|
218
238
|
|
219
239
|
def submit(runnable)
|
220
|
-
runnable.run
|
240
|
+
runnable.respond_to?(:run) ? runnable.run : runnable.call
|
221
241
|
|
222
242
|
java.util.concurrent.CompletableFuture.completed_future(nil)
|
223
243
|
end
|
@@ -233,6 +253,40 @@ module OpenHAB
|
|
233
253
|
end
|
234
254
|
end
|
235
255
|
|
256
|
+
class SafeCaller
|
257
|
+
include org.openhab.core.common.SafeCaller
|
258
|
+
include org.openhab.core.common.SafeCallerBuilder
|
259
|
+
|
260
|
+
def create(target, _interface_type)
|
261
|
+
@target = target
|
262
|
+
self
|
263
|
+
end
|
264
|
+
|
265
|
+
def build
|
266
|
+
@target
|
267
|
+
end
|
268
|
+
|
269
|
+
def with_timeout(_timeout)
|
270
|
+
self
|
271
|
+
end
|
272
|
+
|
273
|
+
def with_identifier(_identifier)
|
274
|
+
self
|
275
|
+
end
|
276
|
+
|
277
|
+
def on_exception(_handler)
|
278
|
+
self
|
279
|
+
end
|
280
|
+
|
281
|
+
def on_timeout(_handler)
|
282
|
+
self
|
283
|
+
end
|
284
|
+
|
285
|
+
def with_async
|
286
|
+
self
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
236
290
|
class CallbacksMap < java.util.HashMap
|
237
291
|
def put(_rule_uid, trigger_handler)
|
238
292
|
trigger_handler.executor.shutdown_now
|
@@ -271,11 +325,12 @@ module OpenHAB
|
|
271
325
|
bc = BundleContext.new(em)
|
272
326
|
cc = ComponentContext.new(bc)
|
273
327
|
cc.properties["measurementSystem"] = api.measurement_system if api
|
328
|
+
resolver = BundleResolver.new
|
274
329
|
|
275
330
|
# the registries!
|
276
331
|
ss = VolatileStorageService.new
|
277
332
|
mr = org.openhab.core.internal.items.MetadataRegistryImpl.new
|
278
|
-
OpenHAB::Core::OSGI.register_service(
|
333
|
+
OpenHAB::Core::OSGI.register_service(mr)
|
279
334
|
mr.managed_provider = mmp = org.openhab.core.internal.items.ManagedMetadataProviderImpl.new(ss)
|
280
335
|
mr.add_provider(mmp)
|
281
336
|
gmp = org.openhab.core.model.item.internal.GenericMetadataProvider.new
|
@@ -286,16 +341,25 @@ module OpenHAB
|
|
286
341
|
ir.event_publisher = ep
|
287
342
|
up = org.openhab.core.internal.i18n.I18nProviderImpl.new(cc)
|
288
343
|
ir.unit_provider = up
|
289
|
-
ir.item_state_converter = org.openhab.core.internal.items.ItemStateConverterImpl.new(up)
|
344
|
+
ir.item_state_converter = isc = org.openhab.core.internal.items.ItemStateConverterImpl.new(up)
|
290
345
|
tr = org.openhab.core.thing.internal.ThingRegistryImpl.new
|
346
|
+
tr.managed_provider = mtp = org.openhab.core.thing.ManagedThingProvider.new(ss)
|
347
|
+
tr.add_provider(mtp)
|
291
348
|
mtr = org.openhab.core.automation.internal.type.ModuleTypeRegistryImpl.new
|
292
349
|
rr = org.openhab.core.automation.internal.RuleRegistryImpl.new
|
293
350
|
rr.module_type_registry = mtr
|
294
351
|
rr.managed_provider = mrp = org.openhab.core.automation.ManagedRuleProvider.new(ss)
|
295
352
|
rr.add_provider(mrp)
|
296
353
|
iclr = org.openhab.core.thing.link.ItemChannelLinkRegistry.new(tr, ir)
|
354
|
+
iclr.add_provider(RSpec::OpenHAB::Core::Mocks::ItemChannelLinkProvider.instance)
|
355
|
+
OpenHAB::Core::OSGI.register_service(iclr)
|
297
356
|
ctr = org.openhab.core.thing.type.ChannelTypeRegistry.new
|
357
|
+
OpenHAB::Core::OSGI.register_service(ctr)
|
358
|
+
ctr.add_channel_type_provider(RSpec::OpenHAB::Core::Mocks::ChannelTypeProvider.instance)
|
298
359
|
ttr = org.openhab.core.thing.type.ThingTypeRegistry.new(ctr)
|
360
|
+
OpenHAB::Core::OSGI.register_service(ttr)
|
361
|
+
ttr.add_thing_type_provider(RSpec::OpenHAB::Core::Mocks::ThingTypeProvider.instance)
|
362
|
+
cgtr = org.openhab.core.thing.type.ChannelGroupTypeRegistry.new
|
299
363
|
|
300
364
|
safe_emf = org.openhab.core.model.core.internal.SafeEMFImpl.new
|
301
365
|
model_repository = org.openhab.core.model.core.internal.ModelRepositoryImpl.new(safe_emf)
|
@@ -360,15 +424,18 @@ module OpenHAB
|
|
360
424
|
|
361
425
|
# link up event bus infrastructure
|
362
426
|
iu = org.openhab.core.internal.items.ItemUpdater.new(ir)
|
363
|
-
ief = org.openhab.core.items.events.ItemEventFactory.new
|
364
427
|
|
365
|
-
sc =
|
366
|
-
aum = org.openhab.core.thing.internal.AutoUpdateManager.new(
|
367
|
-
|
428
|
+
sc = SafeCaller.new
|
429
|
+
aum = org.openhab.core.thing.internal.AutoUpdateManager.new(
|
430
|
+
{ "enabled" => true, "sendOptimisticUpdates" => true }, ctr, ep, iclr, mr, tr
|
431
|
+
)
|
432
|
+
spf = org.openhab.core.thing.internal.profiles.SystemProfileFactory.new(ctr, nil, resolver)
|
433
|
+
cm = org.openhab.core.thing.internal.CommunicationManager.new(aum, ctr, spf, iclr, ir, isc, ep, sc, tr)
|
368
434
|
|
369
435
|
em.add_event_subscriber(iu)
|
370
436
|
em.add_event_subscriber(cm)
|
371
|
-
em.add_event_factory(
|
437
|
+
em.add_event_factory(org.openhab.core.items.events.ItemEventFactory.new)
|
438
|
+
em.add_event_factory(org.openhab.core.thing.events.ThingEventFactory.new)
|
372
439
|
|
373
440
|
# set up the rules engine part 2
|
374
441
|
k = org.openhab.core.automation.internal.module.factory.CoreModuleHandlerFactory
|
@@ -400,6 +467,42 @@ module OpenHAB
|
|
400
467
|
el = org.openhab.core.io.monitor.internal.EventLogger.new(rs)
|
401
468
|
em.add_event_subscriber(el)
|
402
469
|
el.on_ready_marker_added(nil)
|
470
|
+
|
471
|
+
# set up persistence
|
472
|
+
psr = org.openhab.core.persistence.internal.PersistenceServiceRegistryImpl.new
|
473
|
+
org.openhab.core.persistence.extensions.PersistenceExtensions.new(psr)
|
474
|
+
psr.activate("default" => "default")
|
475
|
+
ps = RSpec::OpenHAB::Core::Mocks::PersistenceService.instance
|
476
|
+
psr.add_persistence_service(ps)
|
477
|
+
|
478
|
+
pm = org.openhab.core.persistence.internal.PersistenceManagerImpl.new(nil, ir, sc, rs)
|
479
|
+
pm.add_persistence_service(ps)
|
480
|
+
pm.on_ready_marker_added(nil)
|
481
|
+
|
482
|
+
# set up ThingManager so we can trigger channels
|
483
|
+
localizer = org.openhab.core.thing.i18n.ThingStatusInfoI18nLocalizationService.new
|
484
|
+
tm = org.openhab.core.thing.internal.ThingManagerImpl.new(
|
485
|
+
resolver,
|
486
|
+
cgtr,
|
487
|
+
ctr,
|
488
|
+
cm,
|
489
|
+
nil,
|
490
|
+
nil,
|
491
|
+
ep,
|
492
|
+
iclr,
|
493
|
+
rs,
|
494
|
+
sc,
|
495
|
+
ss,
|
496
|
+
tr,
|
497
|
+
localizer,
|
498
|
+
ttr
|
499
|
+
)
|
500
|
+
thf = RSpec::OpenHAB::Core::Mocks::ThingHandlerFactory.new
|
501
|
+
this_bundle = Bundle.new
|
502
|
+
this_bundle.symbolic_name = "org.openhab.automation.jrubyscripting.rspec"
|
503
|
+
resolver.register(thf.class.java_class, this_bundle)
|
504
|
+
tm.add_thing_handler_factory(thf)
|
505
|
+
tm.on_ready_marker_added(org.openhab.core.service.ReadyMarker.new(nil, this_bundle.symbolic_name))
|
403
506
|
end
|
404
507
|
end
|
405
508
|
end
|
@@ -24,6 +24,13 @@ module RSpec
|
|
24
24
|
@rules.fetch(rule_name).execute(nil, { "event" => event })
|
25
25
|
end
|
26
26
|
|
27
|
+
def trigger_channel(channel, event)
|
28
|
+
channel = org.openhab.core.thing.ChannelUID.new(channel) if channel.is_a?(String)
|
29
|
+
channel = channel.uid if channel.is_a?(org.openhab.core.thing.Channel)
|
30
|
+
thing = channel.thing
|
31
|
+
thing.handler.callback.channel_triggered(nil, channel, event)
|
32
|
+
end
|
33
|
+
|
27
34
|
private
|
28
35
|
|
29
36
|
def restore_autoupdate_items
|
data/lib/rspec/openhab/hooks.rb
CHANGED
data/lib/rspec/openhab/items.rb
CHANGED
@@ -39,6 +39,15 @@ module RSpec
|
|
39
39
|
item.category = item_json["category"] if item_json["category"]
|
40
40
|
|
41
41
|
$ir.add(item)
|
42
|
+
|
43
|
+
next unless item.meta["channel"]&.value
|
44
|
+
|
45
|
+
channel_uid = org.openhab.core.thing.ChannelUID.new(item.meta["channel"].value)
|
46
|
+
channel = $things.get_channel(channel_uid)
|
47
|
+
next unless channel
|
48
|
+
|
49
|
+
link = org.openhab.core.thing.link.ItemChannelLink.new(item.name, channel_uid)
|
50
|
+
Core::Mocks::ItemChannelLinkProvider.instance.add(link)
|
42
51
|
end
|
43
52
|
all_items.each do |item_json| # rubocop:disable Style/CombinableLoops
|
44
53
|
item_json["groupNames"].each do |group_name|
|
@@ -48,6 +57,163 @@ module RSpec
|
|
48
57
|
end
|
49
58
|
end
|
50
59
|
end
|
60
|
+
|
61
|
+
def populate_things_from_api(api)
|
62
|
+
populate_channel_types_from_api(api)
|
63
|
+
populate_thing_types_from_api(api)
|
64
|
+
|
65
|
+
thing_type_registry = ::OpenHAB::Core::OSGI.service("org.openhab.core.thing.type.ThingTypeRegistry")
|
66
|
+
|
67
|
+
api.things.each do |thing_json|
|
68
|
+
uid = org.openhab.core.thing.ThingUID.new(thing_json["UID"])
|
69
|
+
type_uid = org.openhab.core.thing.ThingTypeUID.new(thing_json["thingTypeUID"])
|
70
|
+
bridge_uid = org.openhab.core.thing.ThingUID.new(thing_json["bridgeUID"]) if thing_json["bridgeUID"]
|
71
|
+
|
72
|
+
type = thing_type_registry.get_thing_type(type_uid)
|
73
|
+
klass = if type.is_a?(org.openhab.core.thing.type.BridgeType)
|
74
|
+
org.openhab.core.thing.binding.builder.BridgeBuilder
|
75
|
+
else
|
76
|
+
org.openhab.core.thing.binding.builder.ThingBuilder
|
77
|
+
end
|
78
|
+
builder = klass.create(type_uid, uid)
|
79
|
+
builder.with_bridge(bridge_uid) if bridge_uid
|
80
|
+
|
81
|
+
thing_json.each do |(k, v)|
|
82
|
+
case k
|
83
|
+
when "UID", "thingTypeUID", "bridgeUID", "statusInfo", "editable"
|
84
|
+
nil
|
85
|
+
when "channels"
|
86
|
+
builder.with_channels(v.map { |c| build_channel(c) })
|
87
|
+
when "configuration"
|
88
|
+
builder.with_configuration(org.openhab.core.config.core.Configuration.new(v))
|
89
|
+
else
|
90
|
+
builder.send(:"with_#{k}", v)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
$things.add(builder.build)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def populate_channel_types_from_api(api)
|
101
|
+
api.channel_types.each do |ct_json|
|
102
|
+
uid = org.openhab.core.thing.type.ChannelTypeUID.new(ct_json["UID"])
|
103
|
+
builder = case ct_json["kind"]
|
104
|
+
when "STATE"
|
105
|
+
org.openhab.core.thing.type.ChannelTypeBuilder.state(uid, ct_json["label"], ct_json["itemType"])
|
106
|
+
when "TRIGGER"
|
107
|
+
org.openhab.core.thing.type.ChannelTypeBuilder.trigger(uid, ct_json["label"])
|
108
|
+
else
|
109
|
+
raise ArgumentError, "Unrecognized channel type kind #{ct_json["kind"]} for #{uid}"
|
110
|
+
end
|
111
|
+
|
112
|
+
ct_json.each do |(k, v)|
|
113
|
+
case k
|
114
|
+
when "parameters", "parameterGroups", "label", "kind", "UID", "itemType"
|
115
|
+
nil
|
116
|
+
when "commandDescription"
|
117
|
+
builder.with_command_description(build_command_description(v))
|
118
|
+
when "stateDescription"
|
119
|
+
builder.with_state_description_fragment(build_state_description_fragment(v))
|
120
|
+
when "advanced"
|
121
|
+
builder.is_advanced(v)
|
122
|
+
else
|
123
|
+
builder.send(:"with_#{k}", v)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
ct = builder.build
|
128
|
+
Core::Mocks::ChannelTypeProvider.instance.add(ct)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def build_command_description(json)
|
133
|
+
org.openhab.core.types.CommandDescriptionBuilder.create
|
134
|
+
.with_command_options(json["commandOptions"].map do |o|
|
135
|
+
org.openhab.core.types.CommandOption.new(o["command"], o["label"])
|
136
|
+
end)
|
137
|
+
.build
|
138
|
+
end
|
139
|
+
|
140
|
+
def build_state_description_fragment(json)
|
141
|
+
org.openhab.core.types.StateDescriptionFragmentBuilder.create
|
142
|
+
.with_minimum(json["minimum"]&.to_d)
|
143
|
+
.with_maximum(json["maximum"]&.to_d)
|
144
|
+
.with_step(json["step"&.to_d])
|
145
|
+
.with_pattern(json["pattern"])
|
146
|
+
.with_read_only(json["readOnly"])
|
147
|
+
.with_options(json["options"].map { |o| org.openhab.core.types.StateOption.new(o["value"], o["label"]) })
|
148
|
+
.build
|
149
|
+
end
|
150
|
+
|
151
|
+
def populate_thing_types_from_api(api)
|
152
|
+
api.thing_types.each do |tt_json|
|
153
|
+
uid = org.openhab.core.thing.ThingTypeUID.new(tt_json["UID"])
|
154
|
+
builder = org.openhab.core.thing.type.ThingTypeBuilder.instance(uid, tt_json["label"])
|
155
|
+
tt_json.each do |(k, v)|
|
156
|
+
case k
|
157
|
+
when "UID", "label", "bridge"
|
158
|
+
nil
|
159
|
+
when "listed"
|
160
|
+
builder.is_listed(v)
|
161
|
+
when "channels"
|
162
|
+
builder.with_channels(v.map { |c| build_channel_definition(c) })
|
163
|
+
when "channelGroups"
|
164
|
+
builder.with_channel_groups(v.map { |cg| build_channel_group_definition(cg) })
|
165
|
+
else
|
166
|
+
builder.send(:"with#{k[0].upcase}#{k[1..]}", v)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
tt = tt_json["bridge"] ? builder.build_bridge : builder.build
|
171
|
+
Core::Mocks::ThingTypeProvider.instance.add(tt)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def build_channel_definition(json)
|
176
|
+
org.openhab.core.thing.type.ChannelDefinition.new(
|
177
|
+
json["uid"],
|
178
|
+
org.openhab.core.thing.type.ChannelTypeUID.new(json["typeUID"]),
|
179
|
+
json["description"],
|
180
|
+
json["properties"],
|
181
|
+
nil
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
def build_channel_group_definition(json)
|
186
|
+
org.openhab.core.thing.type.ChannelGroupDefinition.new(
|
187
|
+
json["uid"],
|
188
|
+
org.openhab.core.thing.type.ChannelGroupTypeUID.new(json["typeUID"]),
|
189
|
+
json["label"],
|
190
|
+
json["description"]
|
191
|
+
)
|
192
|
+
end
|
193
|
+
|
194
|
+
def build_channel(json)
|
195
|
+
uid = org.openhab.core.thing.ChannelUID.new(json["uid"])
|
196
|
+
builder = org.openhab.core.thing.binding.builder.ChannelBuilder.create(uid)
|
197
|
+
|
198
|
+
json.each do |(k, v)|
|
199
|
+
case k
|
200
|
+
when "uid", "id", "linkedItems", "itemType"
|
201
|
+
nil
|
202
|
+
when "channelTypeUID"
|
203
|
+
builder.with_type(org.openhab.core.thing.type.ChannelTypeUID.new((v)))
|
204
|
+
when "configuration"
|
205
|
+
builder.with_configuration(org.openhab.core.config.core.Configuration.new(v))
|
206
|
+
when "kind"
|
207
|
+
builder.with_kind(org.openhab.core.thing.type.ChannelKind.const_get(v, false))
|
208
|
+
when "defaultTags"
|
209
|
+
builder.with_default_tags(v.to_set)
|
210
|
+
else
|
211
|
+
builder.send("with_#{k}", v)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
builder.build
|
216
|
+
end
|
51
217
|
end
|
52
218
|
end
|
53
219
|
end
|
@@ -5,7 +5,8 @@
|
|
5
5
|
$LOAD_PATH.unshift(File.expand_path("../vendor/gems/jar-dependencies-1.0.0/lib", __dir__))
|
6
6
|
|
7
7
|
require "rspec/openhab/api"
|
8
|
-
api = OpenHAB::API.new("http://#{ENV.fetch("OPENHAB_HOST", "localhost")}:#{ENV.fetch("OPENHAB_HTTP_PORT", "8080")}/"
|
8
|
+
api = OpenHAB::API.new("http://#{ENV.fetch("OPENHAB_HOST", "localhost")}:#{ENV.fetch("OPENHAB_HTTP_PORT", "8080")}/",
|
9
|
+
ENV.fetch("OPENHAB_TOKEN", nil))
|
9
10
|
|
10
11
|
module OpenHAB
|
11
12
|
module Core
|
@@ -42,9 +43,11 @@ maven_require do
|
|
42
43
|
require "jar org.openhab.core.bundles, org.openhab.core.model.core, #{openhab_version}"
|
43
44
|
require "jar org.openhab.core.bundles, org.openhab.core.model.item, #{openhab_version}"
|
44
45
|
require "jar org.openhab.core.bundles, org.openhab.core.model.script, #{openhab_version}"
|
46
|
+
require "jar org.openhab.core.bundles, org.openhab.core.persistence, #{openhab_version}"
|
45
47
|
require "jar org.openhab.core.bundles, org.openhab.core.semantics, #{openhab_version}"
|
46
48
|
require "jar org.openhab.core.bundles, org.openhab.core.thing, #{openhab_version}"
|
47
49
|
end
|
50
|
+
java_import org.openhab.core.persistence.extensions.PersistenceExtensions
|
48
51
|
|
49
52
|
require "openhab/version"
|
50
53
|
|
@@ -64,6 +67,11 @@ require "rspec/openhab/core/logger"
|
|
64
67
|
# during testing, we don't want "regular" output from rules
|
65
68
|
OpenHAB::Log.logger("org.openhab.automation.jruby.runtime").level = :warn
|
66
69
|
OpenHAB::Log.logger("org.openhab.automation.jruby.logger").level = :warn
|
70
|
+
require "rspec/openhab/core/mocks/channel_type_provider"
|
71
|
+
require "rspec/openhab/core/mocks/item_channel_link_provider"
|
72
|
+
require "rspec/openhab/core/mocks/persistence_service"
|
73
|
+
require "rspec/openhab/core/mocks/thing_handler"
|
74
|
+
require "rspec/openhab/core/mocks/thing_type_provider"
|
67
75
|
require "openhab/dsl/imports"
|
68
76
|
OpenHAB::DSL::Imports.api = api
|
69
77
|
OpenHAB::DSL::Imports.import_presets
|
@@ -90,6 +98,7 @@ RSpec.configure do |config|
|
|
90
98
|
end
|
91
99
|
|
92
100
|
RSpec::OpenHAB::SuspendRules.suspend_rules do
|
101
|
+
RSpec::OpenHAB::Items.populate_things_from_api(api) if api.authenticated?
|
93
102
|
RSpec::OpenHAB::Items.populate_items_from_api(api)
|
94
103
|
end
|
95
104
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-openhab-scripting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.18
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,6 +192,11 @@ files:
|
|
192
192
|
- lib/rspec/openhab/core/item_proxy.rb
|
193
193
|
- lib/rspec/openhab/core/load_path.rb
|
194
194
|
- lib/rspec/openhab/core/logger.rb
|
195
|
+
- lib/rspec/openhab/core/mocks/channel_type_provider.rb
|
196
|
+
- lib/rspec/openhab/core/mocks/item_channel_link_provider.rb
|
197
|
+
- lib/rspec/openhab/core/mocks/persistence_service.rb
|
198
|
+
- lib/rspec/openhab/core/mocks/thing_handler.rb
|
199
|
+
- lib/rspec/openhab/core/mocks/thing_type_provider.rb
|
195
200
|
- lib/rspec/openhab/core/openhab_setup.rb
|
196
201
|
- lib/rspec/openhab/core/osgi.rb
|
197
202
|
- lib/rspec/openhab/core/script_handling.rb
|
@@ -236,7 +241,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
236
241
|
requirements:
|
237
242
|
- - ">="
|
238
243
|
- !ruby/object:Gem::Version
|
239
|
-
version: '2.
|
244
|
+
version: '2.6'
|
240
245
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
241
246
|
requirements:
|
242
247
|
- - ">="
|
@@ -244,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
244
249
|
version: '0'
|
245
250
|
requirements:
|
246
251
|
- jar ch.qos.logback, logback-classic, 1.2.9
|
247
|
-
rubygems_version: 3.
|
252
|
+
rubygems_version: 3.2.29
|
248
253
|
signing_key:
|
249
254
|
specification_version: 4
|
250
255
|
summary: Library testing OpenHAB ruby rules with rspec.
|