awtrix_control 0.0.1

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.
@@ -0,0 +1,246 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe AwtrixControl::Device do
6
+ before do
7
+ @device = AwtrixControl::Device.new(DEFAULT_HOST)
8
+ end
9
+
10
+ describe '#initialize' do
11
+ it 'initializes instance variables' do
12
+ expect(@device.host).to eq(DEFAULT_HOST)
13
+ expect(@device.apps).to eq({})
14
+ end
15
+ end
16
+
17
+ describe '#<<' do
18
+ it 'adds an app instance to the device' do
19
+ app = AwtrixControl::App.new(:test_app)
20
+ @device << app
21
+ actual = @device.apps[:test_app]
22
+ expect(actual).to eq(app)
23
+ expect(app.device).to eq(@device)
24
+ end
25
+ end
26
+
27
+ describe '#[]' do
28
+ it 'returns an app instance' do
29
+ @device.new_app(:test_app)
30
+ app = @device[:test_app]
31
+ expect(app.name).to eq(:test_app)
32
+ end
33
+
34
+ it 'returns nil if the app does not exist' do
35
+ app = @device[:test_app]
36
+ expect(app).to be_nil
37
+ end
38
+ end
39
+
40
+ describe '#effects' do
41
+ it 'makes a call to the effects endpoint of the device' do
42
+ actual = JSON.parse(@device.effects)
43
+ expect(actual.first).to eq('Fade')
44
+ expect_request(method: :get, path: 'effects')
45
+ end
46
+ end
47
+
48
+ describe '#indicator' do
49
+ it 'renders a white indicator by default' do
50
+ @device.indicator(:top)
51
+ expect_request(method: :post, path: 'indicator1', body: { color: '#ffffff' })
52
+ end
53
+
54
+ it 'tells the device to show a given indicator in a given color' do
55
+ @device.indicator(:bottom, '#00FF00')
56
+ expect_request(method: :post, path: 'indicator3', body: { color: '#00FF00' })
57
+ end
58
+
59
+ it 'works with shorthand color symbols' do
60
+ @device.indicator(:top, :red)
61
+ expect_request(method: :post, path: 'indicator1', body: { color: '#ff0000' })
62
+ end
63
+ end
64
+
65
+ context 'with effects' do
66
+ it 'renders a blinking indicator' do
67
+ @device.indicator(:center, :red, effect: :blink)
68
+ expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', blink: 500 })
69
+ end
70
+
71
+ it 'renders a pulsing indicator' do
72
+ @device.indicator(:center, :red, effect: :pulse)
73
+ expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', fade: 2000 })
74
+ end
75
+
76
+ it 'renders a blinking indicator with a custom frequency' do
77
+ @device.indicator(:center, :red, effect: :blink, frequency: 1000)
78
+ expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', blink: 1000 })
79
+ end
80
+
81
+ it 'renders a pulsing indicator with a custom frequency' do
82
+ @device.indicator(:center, :red, effect: :pulse, frequency: 5000)
83
+ expect_request(method: :post, path: 'indicator2', body: { color: '#ff0000', fade: 5000 })
84
+ end
85
+ end
86
+
87
+ describe '#loop' do
88
+ it 'makes a call to the loop endpoint of the device' do
89
+ actual = @device.loop
90
+ expect(actual).to eq({ "Hello" => 1, "Time" => 0, "World" => 2 })
91
+ expect_request(method: :get, path: 'loop')
92
+ end
93
+ end
94
+
95
+ describe '#new_app' do
96
+ it 'instantiates a new app and adds it to the device' do
97
+ @device.new_app('test_app')
98
+ actual = @device.apps['test_app']
99
+ expect(actual.name).to eq('test_app')
100
+ expect(actual.payload).to eq(AwtrixControl::App.new('test_app').default_payload)
101
+ end
102
+
103
+ it 'overwrites an existing app' do
104
+ @device.new_app('test_app')
105
+ second_app = @device.new_app('test_app')
106
+ actual = @device.apps['test_app']
107
+ expect(actual).to eq(second_app)
108
+ end
109
+ end
110
+
111
+ describe '#notify' do
112
+ it 'makes a call to the notify endpoint of the device' do
113
+ @device.notify('test_notification', color: :red)
114
+ expect_request(method: :post, path: 'notify', body: { text: 'test_notification', color: "#ff0000" })
115
+ end
116
+ end
117
+
118
+ describe '#power' do
119
+ it 'makes a call to the power endpoint of the device' do
120
+ @device.power(true)
121
+ expect_request(method: :post, path: 'power', body: { power: true })
122
+ end
123
+ end
124
+
125
+ describe '#remove_indicator' do
126
+ it 'removes an indicator from the device' do
127
+ @device.remove_indicator(:top)
128
+ expect_request(method: :post, path: 'indicator1', body: { color: '#000000' })
129
+ end
130
+ end
131
+
132
+ describe '#remove_indicators' do
133
+ it 'removes all indicators from the device' do
134
+ @device.remove_indicators
135
+ expect_request(method: :post, path: 'indicator1', body: { color: '#000000' })
136
+ expect_request(method: :post, path: 'indicator2', body: { color: '#000000' })
137
+ expect_request(method: :post, path: 'indicator3', body: { color: '#000000' })
138
+ end
139
+ end
140
+
141
+ describe '#reset' do
142
+ it 'makes the device sleep for 1 second' do
143
+ @device.reset
144
+ expect_request(method: :post, path: 'sleep', body: { sleep: 1 })
145
+ end
146
+ end
147
+
148
+ describe '#rtttl' do
149
+ it 'makes a call to the rtttl endpoint of the device' do
150
+ @device.rtttl('test_rtttl')
151
+ expect_request(method: :post, path: 'rtttl', body: '"test_rtttl"')
152
+ end
153
+ end
154
+
155
+ describe '#screen' do
156
+ it 'makes a call to the screen endpoint of the device' do
157
+ actual = JSON.parse(@device.screen)
158
+ expect(actual).to start_with(0, 0, 0, 0, 0)
159
+ expect_request(method: :get, path: 'screen')
160
+ end
161
+ end
162
+
163
+ describe '#sleep' do
164
+ it 'makes the device sleep for a number of seconds' do
165
+ @device.sleep(5)
166
+ expect_request(method: :post, path: 'sleep', body: { sleep: 5 })
167
+ end
168
+
169
+ it 'makes the device sleep indefinitely when no seconds are provided' do
170
+ @device.sleep
171
+ expect_request(method: :post, path: 'sleep', body: {})
172
+ end
173
+ end
174
+
175
+ describe '#sound' do
176
+ it 'makes a call to the sound endpoint of the device' do
177
+ @device.sound('test_sound')
178
+ expect_request(method: :post, path: 'sound', body: { sound: 'test_sound' })
179
+ end
180
+ end
181
+
182
+ describe '#stats' do
183
+ it 'makes a call to the status endpoint of the device' do
184
+ actual = JSON.parse(@device.stats)["version"]
185
+ expect(actual).to eq('0.96')
186
+ expect_request(method: :get, path: 'stats')
187
+ end
188
+ end
189
+
190
+ describe '#transitions' do
191
+ it 'makes a call to the transitions endpoint of the device' do
192
+ actual = JSON.parse(@device.transitions).first
193
+ expect(actual).to eq('Random')
194
+ expect_request(method: :get, path: 'transitions')
195
+ end
196
+ end
197
+
198
+ describe '#delete_app' do
199
+ it 'deletes an app by name' do
200
+ app = AwtrixControl::App.new('test_app')
201
+ @device << app
202
+ @device.delete_app('test_app')
203
+ expect(@device.apps).to eq({})
204
+ expect_request(method: :post, path: 'custom?name=test_app', body: {})
205
+ end
206
+ end
207
+
208
+ describe '#delete_all_apps' do
209
+ it 'deletes all apps from the device and device, even if they do not match' do
210
+ app1 = AwtrixControl::App.new('test_app1')
211
+ @device << app1
212
+ @device.delete_all_apps
213
+ expect_request(method: :get, path: 'loop')
214
+ # The loop endpoint is mocked with the following apps:
215
+ expect_request(method: :post, path: 'custom?name=Time')
216
+ expect_request(method: :post, path: 'custom?name=Hello')
217
+ expect_request(method: :post, path: 'custom?name=World')
218
+ expect(@device.apps).to eq({})
219
+ end
220
+ end
221
+
222
+ def expect_request(method:, path:, host: DEFAULT_HOST, body: {})
223
+ expect(WebMock)
224
+ .to have_requested(method, "http://#{host}/api/#{path}")
225
+ .with(body: body)
226
+ end
227
+
228
+ describe '#push_app' do
229
+ it 'pushes an app to the device by name' do
230
+ app = @device.new_app(:test_app)
231
+ @device.push_app(:test_app)
232
+ expect_request(method: :post,
233
+ path: 'custom?name=test_app',
234
+ body: { "name": "test_app" }.merge(app.default_payload))
235
+
236
+ end
237
+
238
+ it 'does not push apps from other devices' do
239
+ other_device = AwtrixControl::Device.new('192.168.0.2')
240
+ app = other_device.new_app(:test_app)
241
+ @device.push_app(:test_app)
242
+
243
+ expect(WebMock).not_to have_requested(:post, "http://#{DEFAULT_HOST}/api/custom")
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'AwtrixControl' do
6
+ end
@@ -0,0 +1,33 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'awtrix_control'
5
+ require 'webmock/rspec'
6
+
7
+ # Disable external requests
8
+ WebMock.disable_net_connect!(allow_localhost: true)
9
+
10
+ DEFAULT_HOST = '1.1.1.1'
11
+
12
+ # Global stubs
13
+ RSpec.configure do |config|
14
+ config.before(:each) do
15
+ stub_request(:get, %r{http://#{DEFAULT_HOST}/api/.*})
16
+ .to_return do |request|
17
+ path = request.uri.path.split('/').last
18
+ file_path = File.join('spec', 'fixtures', "get_#{path}.json")
19
+ {
20
+ status: 200,
21
+ body: File.read(file_path),
22
+ headers: { 'Content-Type' => 'application/json' }
23
+ }
24
+ end
25
+
26
+ stub_request(:post, %r{http://#{DEFAULT_HOST}/api/.*})
27
+ .to_return(
28
+ status: 200,
29
+ body: "OK",
30
+ headers: { 'Content-Type' => 'application/json' }
31
+ )
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awtrix_control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Francois Gaspard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-09-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ description: A gem to control AWTRIX 3 devices from Ruby
28
+ email:
29
+ - fr@ncois.email
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/awtrix_control.rb
35
+ - lib/awtrix_control/app.rb
36
+ - lib/awtrix_control/device.rb
37
+ - lib/awtrix_control/request.rb
38
+ - lib/spec/awtrix_control/app_spec.rb
39
+ - lib/spec/awtrix_control/device_spec.rb
40
+ - lib/spec/awtrix_control_spec.rb
41
+ - lib/spec/spec_helper.rb
42
+ homepage: https://github.com/Francois-gaspard/awtrix
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.5.17
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Control AWTRIX 3 devices
65
+ test_files: []