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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d267863174213b2996edf9c92a8704499fb6e4c5136289fb2d2b2aae1a810bf
4
- data.tar.gz: 0cd9ff249e7a045265337bbb8603c0ab7e87d2c7e24145454e08917869202d98
3
+ metadata.gz: 6ea44768dd3bccdfc7276944f329030e21182d161126e433126970f096543f46
4
+ data.tar.gz: 81be4550cd3ab271f43e15616959709bb9e5d1cf14a999dd8565e0b148d3a8d7
5
5
  SHA512:
6
- metadata.gz: 4881e2d5e6cd7149dc15fa518fa6198d189db5177889571db981c204b299b674ac7a8e773fe1b3d14c0c4afeab244ef4653e3c1075a8585188dce465f9acbf5b
7
- data.tar.gz: 7d4f79653bf22e61ea06e19f42efc08544cbf4ad3a3ce3226c28dbd9f54df41f4cfdccec2df8dd6bbdbf4bc42d3d05076fb4217e416ea8f0492ce19b2062c92d
6
+ metadata.gz: 4d70a68375f21fab304d05b620125cf79b5767f3522d5e22a0608301b56e4ed3b2f6baba7942bdfcdb9ffed742378452720b79b7bfc5d7523544087a0bcb15bc
7
+ data.tar.gz: d2ce66901858dc37eb7c76b5f37f82da6147f1b471b8fc70097037099d677eb01c6e4e25d77e12105847e28156a919e059d5420271f9ce5cfcb0c9af933b4383
@@ -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
- attr_reader :symbolic_name, :version
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("Dispatching/filtering event for subscriber '#{event_subscriber.class}' failed: #{e}")
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("org.openhab.core.items.MetadataRegistry", mr)
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 = org.openhab.core.internal.common.SafeCallerImpl.new({})
366
- aum = org.openhab.core.thing.internal.AutoUpdateManager.new({ "enabled" => "true" }, nil, ep, iclr, mr, tr)
367
- cm = org.openhab.core.thing.internal.CommunicationManager.new(aum, nil, nil, iclr, ir, nil, ep, sc, tr)
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(ief)
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
@@ -10,9 +10,11 @@ RSpec.configure do |config|
10
10
  end
11
11
  end
12
12
  end
13
+
13
14
  config.after do
14
15
  OpenHAB::DSL::Timers.timer_manager.cancel_all
15
16
  Timecop.return
16
17
  restore_autoupdate_items
18
+ RSpec::OpenHAB::Core::Mocks::PersistenceService.instance.reset
17
19
  end
18
20
  end
@@ -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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module OpenHAB
5
- VERSION = "0.0.15"
5
+ VERSION = "0.0.18"
6
6
  end
7
7
  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.15
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-05 00:00:00.000000000 Z
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.5'
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.3.17
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.