rspec-openhab-scripting 0.0.16-java → 0.0.17-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5dd7ea9915aa3edecf86f75d7331bfe77ad3fbbbee4c278fd130895e4bc1e6c
4
- data.tar.gz: 489db2879bf94009c027fcbb87572ae5b3834d31fab17f473cddc2fdecfebdfd
3
+ metadata.gz: a5541ba712d1a3fef9112f736b456309acb491aa0cdf075098abe04712a59940
4
+ data.tar.gz: d75f2b90687529a2bbc63f6d456f639a23360e7636d8ea7c36ed4d2113c7b6d7
5
5
  SHA512:
6
- metadata.gz: 967d33cd26a809179324637df7ebb9243ec901ae6c75aaa97a1615a6f699082bb83050727502c326bcf85732f86521f93ce253877306d8e6cf86b4ed84030708
7
- data.tar.gz: 375c3ebb1c64176b3da00a8489b8b9574e5636d767a2cb981100dc3b6b3128cbf23fc8b7ab9998ed3b7154a9d0754be6f349d3711ef326e7714ec360cac89732
6
+ metadata.gz: f576f81ea3fea76dbb173e8aa7ad3d1439f24e518bcd8574597266fe4bc457e325b6ec2f214e9c15a9c6b4c681d7350f7845fe055962f3b1b68214c0433b6b4d
7
+ data.tar.gz: 394f5a733ed2ddd02bf109f08fb80bbc35f8db5cebb340231a4b9bb17064ba17598ea1dbd90de18e16ff7d6ef52c387db001da6f6a3ae140c44928e71cef48c5
@@ -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,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,12 @@ 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 resolve_bundle(klass); end
75
+ end
76
+
71
77
  # don't depend on org.openhab.core.test
72
78
  class VolatileStorageService
73
79
  include org.openhab.core.storage.StorageService
@@ -190,7 +196,7 @@ module OpenHAB
190
196
  event_factory.create_event(type, topic, payload, source)
191
197
  rescue Exception => e
192
198
  logger.warn("Creation of event failed, because one of the " \
193
- "registered event factories has thrown an exception: #{e}")
199
+ "registered event factories has thrown an exception: #{e.inspect}")
194
200
  nil
195
201
  end
196
202
 
@@ -201,7 +207,9 @@ module OpenHAB
201
207
  begin
202
208
  event_subscriber.receive(event)
203
209
  rescue Exception => e
204
- logger.warn("Dispatching/filtering event for subscriber '#{event_subscriber.class}' failed: #{e}")
210
+ logger.warn(
211
+ "Dispatching/filtering event for subscriber '#{event_subscriber.class}' failed: #{e.inspect}"
212
+ )
205
213
  end
206
214
  else
207
215
  logger.trace("Skip event subscriber (#{event_subscriber.class}) because of its filter.")
@@ -217,7 +225,7 @@ module OpenHAB
217
225
  include Singleton
218
226
 
219
227
  def submit(runnable)
220
- runnable.run
228
+ runnable.respond_to?(:run) ? runnable.run : runnable.call
221
229
 
222
230
  java.util.concurrent.CompletableFuture.completed_future(nil)
223
231
  end
@@ -233,6 +241,40 @@ module OpenHAB
233
241
  end
234
242
  end
235
243
 
244
+ class SafeCaller
245
+ include org.openhab.core.common.SafeCaller
246
+ include org.openhab.core.common.SafeCallerBuilder
247
+
248
+ def create(target, _interface_type)
249
+ @target = target
250
+ self
251
+ end
252
+
253
+ def build
254
+ @target
255
+ end
256
+
257
+ def with_timeout(_timeout)
258
+ self
259
+ end
260
+
261
+ def with_identifier(_identifier)
262
+ self
263
+ end
264
+
265
+ def on_exception(_handler)
266
+ self
267
+ end
268
+
269
+ def on_timeout(_handler)
270
+ self
271
+ end
272
+
273
+ def with_async
274
+ self
275
+ end
276
+ end
277
+
236
278
  class CallbacksMap < java.util.HashMap
237
279
  def put(_rule_uid, trigger_handler)
238
280
  trigger_handler.executor.shutdown_now
@@ -275,7 +317,7 @@ module OpenHAB
275
317
  # the registries!
276
318
  ss = VolatileStorageService.new
277
319
  mr = org.openhab.core.internal.items.MetadataRegistryImpl.new
278
- OpenHAB::Core::OSGI.register_service("org.openhab.core.items.MetadataRegistry", mr)
320
+ OpenHAB::Core::OSGI.register_service(mr)
279
321
  mr.managed_provider = mmp = org.openhab.core.internal.items.ManagedMetadataProviderImpl.new(ss)
280
322
  mr.add_provider(mmp)
281
323
  gmp = org.openhab.core.model.item.internal.GenericMetadataProvider.new
@@ -286,16 +328,24 @@ module OpenHAB
286
328
  ir.event_publisher = ep
287
329
  up = org.openhab.core.internal.i18n.I18nProviderImpl.new(cc)
288
330
  ir.unit_provider = up
289
- ir.item_state_converter = org.openhab.core.internal.items.ItemStateConverterImpl.new(up)
331
+ ir.item_state_converter = isc = org.openhab.core.internal.items.ItemStateConverterImpl.new(up)
290
332
  tr = org.openhab.core.thing.internal.ThingRegistryImpl.new
333
+ tr.managed_provider = mtp = org.openhab.core.thing.ManagedThingProvider.new(ss)
334
+ tr.add_provider(mtp)
291
335
  mtr = org.openhab.core.automation.internal.type.ModuleTypeRegistryImpl.new
292
336
  rr = org.openhab.core.automation.internal.RuleRegistryImpl.new
293
337
  rr.module_type_registry = mtr
294
338
  rr.managed_provider = mrp = org.openhab.core.automation.ManagedRuleProvider.new(ss)
295
339
  rr.add_provider(mrp)
296
340
  iclr = org.openhab.core.thing.link.ItemChannelLinkRegistry.new(tr, ir)
341
+ iclr.add_provider(RSpec::OpenHAB::Core::Mocks::ItemChannelLinkProvider.instance)
342
+ OpenHAB::Core::OSGI.register_service(iclr)
297
343
  ctr = org.openhab.core.thing.type.ChannelTypeRegistry.new
344
+ OpenHAB::Core::OSGI.register_service(ctr)
345
+ ctr.add_channel_type_provider(RSpec::OpenHAB::Core::Mocks::ChannelTypeProvider.instance)
298
346
  ttr = org.openhab.core.thing.type.ThingTypeRegistry.new(ctr)
347
+ OpenHAB::Core::OSGI.register_service(ttr)
348
+ ttr.add_thing_type_provider(RSpec::OpenHAB::Core::Mocks::ThingTypeProvider.instance)
299
349
 
300
350
  safe_emf = org.openhab.core.model.core.internal.SafeEMFImpl.new
301
351
  model_repository = org.openhab.core.model.core.internal.ModelRepositoryImpl.new(safe_emf)
@@ -362,9 +412,12 @@ module OpenHAB
362
412
  iu = org.openhab.core.internal.items.ItemUpdater.new(ir)
363
413
  ief = org.openhab.core.items.events.ItemEventFactory.new
364
414
 
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)
415
+ sc = SafeCaller.new
416
+ aum = org.openhab.core.thing.internal.AutoUpdateManager.new(
417
+ { "enabled" => true, "sendOptimisticUpdates" => true }, ctr, ep, iclr, mr, tr
418
+ )
419
+ spf = org.openhab.core.thing.internal.profiles.SystemProfileFactory.new(ctr, nil, BundleResolver.new)
420
+ cm = org.openhab.core.thing.internal.CommunicationManager.new(aum, ctr, spf, iclr, ir, isc, ep, sc, tr)
368
421
 
369
422
  em.add_event_subscriber(iu)
370
423
  em.add_event_subscriber(cm)
@@ -3,6 +3,18 @@
3
3
  module RSpec
4
4
  module OpenHAB
5
5
  module Items
6
+ class ThingHandler
7
+ include org.openhab.core.thing.binding.ThingHandler
8
+
9
+ attr_reader :thing
10
+
11
+ def initialize(thing)
12
+ @thing = thing
13
+ end
14
+
15
+ def handle_command(channel, command); end
16
+ end
17
+
6
18
  class << self
7
19
  def populate_items_from_api(api)
8
20
  all_items = api.items
@@ -39,6 +51,15 @@ module RSpec
39
51
  item.category = item_json["category"] if item_json["category"]
40
52
 
41
53
  $ir.add(item)
54
+
55
+ next unless item.meta["channel"]&.value
56
+
57
+ channel_uid = org.openhab.core.thing.ChannelUID.new(item.meta["channel"].value)
58
+ channel = $things.get_channel(channel_uid)
59
+ next unless channel
60
+
61
+ link = org.openhab.core.thing.link.ItemChannelLink.new(item.name, channel_uid)
62
+ Core::Mocks::ItemChannelLinkProvider.instance.add(link)
42
63
  end
43
64
  all_items.each do |item_json| # rubocop:disable Style/CombinableLoops
44
65
  item_json["groupNames"].each do |group_name|
@@ -48,6 +69,170 @@ module RSpec
48
69
  end
49
70
  end
50
71
  end
72
+
73
+ def populate_things_from_api(api)
74
+ populate_channel_types_from_api(api)
75
+ populate_thing_types_from_api(api)
76
+
77
+ thing_type_registry = ::OpenHAB::Core::OSGI.service("org.openhab.core.thing.type.ThingTypeRegistry")
78
+
79
+ api.things.each do |thing_json|
80
+ uid = org.openhab.core.thing.ThingUID.new(thing_json["UID"])
81
+ type_uid = org.openhab.core.thing.ThingTypeUID.new(thing_json["thingTypeUID"])
82
+ bridge_uid = org.openhab.core.thing.ThingUID.new(thing_json["bridgeUID"]) if thing_json["bridgeUID"]
83
+
84
+ type = thing_type_registry.get_thing_type(type_uid)
85
+ klass = if type.is_a?(org.openhab.core.thing.type.BridgeType)
86
+ org.openhab.core.thing.binding.builder.BridgeBuilder
87
+ else
88
+ org.openhab.core.thing.binding.builder.ThingBuilder
89
+ end
90
+ builder = klass.create(type_uid, uid)
91
+ builder.with_bridge(bridge_uid) if bridge_uid
92
+
93
+ thing_json.each do |(k, v)|
94
+ case k
95
+ when "UID", "thingTypeUID", "bridgeUID", "statusInfo", "editable"
96
+ nil
97
+ when "channels"
98
+ builder.with_channels(v.map { |c| build_channel(c) })
99
+ when "configuration"
100
+ builder.with_configuration(org.openhab.core.config.core.Configuration.new(v))
101
+ else
102
+ builder.send(:"with_#{k}", v)
103
+ end
104
+ end
105
+
106
+ thing = builder.build
107
+ # pretend everything is online so that AutoUpdateManager won't reject updates
108
+ # to items linked to offline channels
109
+ thing.status_info = org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder
110
+ .create(org.openhab.core.thing.ThingStatus::ONLINE).build
111
+ handler = ThingHandler.new(thing)
112
+ thing.handler = handler
113
+ $things.add(thing)
114
+ end
115
+ end
116
+
117
+ private
118
+
119
+ def populate_channel_types_from_api(api)
120
+ api.channel_types.each do |ct_json|
121
+ uid = org.openhab.core.thing.type.ChannelTypeUID.new(ct_json["UID"])
122
+ builder = case ct_json["kind"]
123
+ when "STATE"
124
+ org.openhab.core.thing.type.ChannelTypeBuilder.state(uid, ct_json["label"], ct_json["itemType"])
125
+ when "TRIGGER"
126
+ org.openhab.core.thing.type.ChannelTypeBuilder.trigger(uid, ct_json["label"])
127
+ else
128
+ raise ArgumentError, "Unrecognized channel type kind #{ct_json["kind"]} for #{uid}"
129
+ end
130
+
131
+ ct_json.each do |(k, v)|
132
+ case k
133
+ when "parameters", "parameterGroups", "label", "kind", "UID", "itemType"
134
+ nil
135
+ when "commandDescription"
136
+ builder.with_command_description(build_command_description(v))
137
+ when "stateDescription"
138
+ builder.with_state_description_fragment(build_state_description_fragment(v))
139
+ when "advanced"
140
+ builder.is_advanced(v)
141
+ else
142
+ builder.send(:"with_#{k}", v)
143
+ end
144
+ end
145
+
146
+ ct = builder.build
147
+ Core::Mocks::ChannelTypeProvider.instance.add(ct)
148
+ end
149
+ end
150
+
151
+ def build_command_description(json)
152
+ org.openhab.core.types.CommandDescriptionBuilder.create
153
+ .with_command_options(json["commandOptions"].map do |o|
154
+ org.openhab.core.types.CommandOption.new(o["command"], o["label"])
155
+ end)
156
+ .build
157
+ end
158
+
159
+ def build_state_description_fragment(json)
160
+ org.openhab.core.types.StateDescriptionFragmentBuilder.create
161
+ .with_minimum(json["minimum"]&.to_d)
162
+ .with_maximum(json["maximum"]&.to_d)
163
+ .with_step(json["step"&.to_d])
164
+ .with_pattern(json["pattern"])
165
+ .with_read_only(json["readOnly"])
166
+ .with_options(json["options"].map { |o| org.openhab.core.types.StateOption.new(o["value"], o["label"]) })
167
+ .build
168
+ end
169
+
170
+ def populate_thing_types_from_api(api)
171
+ api.thing_types.each do |tt_json|
172
+ uid = org.openhab.core.thing.ThingTypeUID.new(tt_json["UID"])
173
+ builder = org.openhab.core.thing.type.ThingTypeBuilder.instance(uid, tt_json["label"])
174
+ tt_json.each do |(k, v)|
175
+ case k
176
+ when "UID", "label", "bridge"
177
+ nil
178
+ when "listed"
179
+ builder.is_listed(v)
180
+ when "channels"
181
+ builder.with_channels(v.map { |c| build_channel_definition(c) })
182
+ when "channelGroups"
183
+ builder.with_channel_groups(v.map { |cg| build_channel_group_definition(cg) })
184
+ else
185
+ builder.send(:"with#{k[0].upcase}#{k[1..]}", v)
186
+ end
187
+ end
188
+
189
+ tt = tt_json["bridge"] ? builder.build_bridge : builder.build
190
+ Core::Mocks::ThingTypeProvider.instance.add(tt)
191
+ end
192
+ end
193
+
194
+ def build_channel_definition(json)
195
+ org.openhab.core.thing.type.ChannelDefinition.new(
196
+ json["uid"],
197
+ org.openhab.core.thing.type.ChannelTypeUID.new(json["typeUID"]),
198
+ json["description"],
199
+ json["properties"],
200
+ nil
201
+ )
202
+ end
203
+
204
+ def build_channel_group_definition(json)
205
+ org.openhab.core.thing.type.ChannelGroupDefinition.new(
206
+ json["uid"],
207
+ org.openhab.core.thing.type.ChannelGroupTypeUID.new(json["typeUID"]),
208
+ json["label"],
209
+ json["description"]
210
+ )
211
+ end
212
+
213
+ def build_channel(json)
214
+ uid = org.openhab.core.thing.ChannelUID.new(json["uid"])
215
+ builder = org.openhab.core.thing.binding.builder.ChannelBuilder.create(uid)
216
+
217
+ json.each do |(k, v)|
218
+ case k
219
+ when "uid", "id", "linkedItems", "itemType"
220
+ nil
221
+ when "channelTypeUID"
222
+ builder.with_type(org.openhab.core.thing.type.ChannelTypeUID.new((v)))
223
+ when "configuration"
224
+ builder.with_configuration(org.openhab.core.config.core.Configuration.new(v))
225
+ when "kind"
226
+ builder.with_kind(org.openhab.core.thing.type.ChannelKind.const_get(v, false))
227
+ when "defaultTags"
228
+ builder.with_default_tags(v.to_set)
229
+ else
230
+ builder.send("with_#{k}", v)
231
+ end
232
+ end
233
+
234
+ builder.build
235
+ end
51
236
  end
52
237
  end
53
238
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module OpenHAB
5
- VERSION = "0.0.16"
5
+ VERSION = "0.0.17"
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
@@ -66,7 +67,10 @@ require "rspec/openhab/core/logger"
66
67
  # during testing, we don't want "regular" output from rules
67
68
  OpenHAB::Log.logger("org.openhab.automation.jruby.runtime").level = :warn
68
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"
69
72
  require "rspec/openhab/core/mocks/persistence_service"
73
+ require "rspec/openhab/core/mocks/thing_type_provider"
70
74
  require "openhab/dsl/imports"
71
75
  OpenHAB::DSL::Imports.api = api
72
76
  OpenHAB::DSL::Imports.import_presets
@@ -93,6 +97,7 @@ RSpec.configure do |config|
93
97
  end
94
98
 
95
99
  RSpec::OpenHAB::SuspendRules.suspend_rules do
100
+ RSpec::OpenHAB::Items.populate_things_from_api(api) if api.authenticated?
96
101
  RSpec::OpenHAB::Items.populate_items_from_api(api)
97
102
  end
98
103
 
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.16
4
+ version: 0.0.17
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-18 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,7 +192,10 @@ 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
195
197
  - lib/rspec/openhab/core/mocks/persistence_service.rb
198
+ - lib/rspec/openhab/core/mocks/thing_type_provider.rb
196
199
  - lib/rspec/openhab/core/openhab_setup.rb
197
200
  - lib/rspec/openhab/core/osgi.rb
198
201
  - lib/rspec/openhab/core/script_handling.rb
@@ -237,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
240
  requirements:
238
241
  - - ">="
239
242
  - !ruby/object:Gem::Version
240
- version: '2.5'
243
+ version: '2.6'
241
244
  required_rubygems_version: !ruby/object:Gem::Requirement
242
245
  requirements:
243
246
  - - ">="