whipped-cream 0.1.0 → 0.1.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.
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1
4
+
5
+ * Validate GPIO pin numbers (@rringer)
6
+
3
7
  ## 0.1.0
4
8
 
5
9
  * Support deploying to a Pi with RVM installed (@shobhitic)
data/README.md CHANGED
@@ -160,3 +160,7 @@ end
160
160
  Web UI designed by [Ashton Harris](http://ashtonharris.me).
161
161
 
162
162
  Logo designed by [Jeff Bloch](http://www.redbubble.com/people/jabbtees).
163
+
164
+
165
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/justincampbell/whipped-cream/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
166
+
data/Rakefile CHANGED
@@ -9,7 +9,9 @@ task default: :ci
9
9
  desc "Run all test suites"
10
10
  task ci: [:spec, :cane]
11
11
 
12
- RSpec::Core::RakeTask.new
12
+ RSpec::Core::RakeTask.new do |rspec|
13
+ rspec.rspec_opts = '--tag ~acceptance'
14
+ end
13
15
 
14
16
  Cane::RakeTask.new do |cane|
15
17
  cane.add_threshold 'coverage/.last_run.json', :>=, 90
@@ -17,7 +19,33 @@ end
17
19
 
18
20
  desc "Test deploying the demo plugin to a Vagrant box"
19
21
  task :vagrant do
20
- system 'vagrant destroy -f'
21
- system 'vagrant up'
22
- system 'bin/whipped-cream deploy demo.rb 127.0.0.1:2222'
22
+ [
23
+ ['vagrant up',
24
+ 'Bringing up Debian Wheezy Vagrant box'],
25
+ ['bin/whipped-cream deploy demo.rb 127.0.0.1:2222',
26
+ 'Performing initial deploy'],
27
+ ['bin/whipped-cream deploy demo.rb 127.0.0.1:2222',
28
+ 'Performing subsequent deploy'],
29
+ ['REMOTE_URL="http://127.0.0.1:8080" rspec --tag acceptance',
30
+ 'Running acceptance tests against Vagrant box']
31
+ ].each do |command, description|
32
+ puts yellow(description)
33
+ puts cyan(?` + command + ?`)
34
+
35
+ unless system(command)
36
+ raise "Command failed: '#{command}'"
37
+ end
38
+ end
39
+ end
40
+
41
+ def yellow(text)
42
+ color(3, text)
43
+ end
44
+
45
+ def cyan(text)
46
+ color(6, text)
47
+ end
48
+
49
+ def color(number, text)
50
+ `tput setaf #{number}` + text + `tput sgr0`
23
51
  end
@@ -2,8 +2,10 @@ Vagrant.configure('2') do |config|
2
2
  config.vm.box = 'debian-wheezy'
3
3
  config.vm.box_url = 'https://dl.dropboxusercontent.com/u/86066173/debian-wheezy.box'
4
4
 
5
- [80].each do |port|
6
- config.vm.network "forwarded_port", guest: port, host: port
5
+ {
6
+ 80 => 8080
7
+ }.each do |guest, host|
8
+ config.vm.network :forwarded_port, guest: guest, host: host
7
9
  end
8
10
 
9
11
  config.vm.provision :shell, inline: <<-SCRIPT
data/demo.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  name "Demo"
2
2
 
3
- button "Open/Close", pin: 1
3
+ button "Open/Close", pin: 4
4
4
 
5
- sensor "Door", pin: 2, high: "Open", low: "Closed"
5
+ sensor "Door", pin: 17, high: "Open", low: "Closed"
6
6
 
7
- switch "Light", pin: 3
7
+ switch "Light", pin: 18
8
8
 
9
9
  sensor "Ruby Version" do
10
10
  RUBY_VERSION
@@ -7,6 +7,10 @@ module WhippedCream
7
7
  attr_reader :name, :pin, :block
8
8
 
9
9
  def initialize(name, options = {})
10
+ raise "Invalid pin. The pin must be one of "\
11
+ "the Raspberry Pi's valid GPIO pins: "\
12
+ "#{VALID_GPIO_PINS}" unless VALID_GPIO_PINS.include?(options[:pin])
13
+
10
14
  @name = name
11
15
  @pin = options[:pin]
12
16
  @block = options[:block]
@@ -1,6 +1,8 @@
1
1
  module WhippedCream
2
2
  # An abstract class for controls to inherit from
3
3
  class Control
4
+ VALID_GPIO_PINS = [4, 17, 18, 22, 23, 24, 25, 27]
5
+
4
6
  def id
5
7
  name.downcase.gsub(/[^\w]+/, '_').gsub(/^_|_$/, '').to_sym
6
8
  end
@@ -8,6 +8,13 @@ module WhippedCream
8
8
  attr_reader :name, :pin, :low, :high, :on_low, :on_high, :block
9
9
 
10
10
  def initialize(name, options = {}, &block)
11
+ # Pushing nil onto VALID_GPIO_PINS to allow a pinless sensor
12
+ raise "Invalid pin. The pin must be one of "\
13
+ "the Raspberry Pi's valid GPIO pins: "\
14
+ "#{VALID_GPIO_PINS}" unless VALID_GPIO_PINS.dup
15
+ .push(nil)
16
+ .include?(options[:pin])
17
+
11
18
  @name = name
12
19
  @pin = options[:pin]
13
20
  @low = options[:low]
@@ -4,6 +4,10 @@ module WhippedCream
4
4
  attr_reader :name, :pin
5
5
 
6
6
  def initialize(name, options = {})
7
+ raise "Invalid pin. The pin must be one of "\
8
+ "the Raspberry Pi's valid GPIO pins: "\
9
+ "#{VALID_GPIO_PINS}" unless VALID_GPIO_PINS.include?(options[:pin])
10
+
7
11
  @name = name
8
12
  @pin = options[:pin]
9
13
  end
@@ -1,3 +1,3 @@
1
1
  module WhippedCream
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'faraday'
3
+ require 'timeout'
4
+
5
+ describe 'Whipped Cream', :acceptance do
6
+ let(:http) { Faraday.new(url: url) }
7
+ let(:request_method) { :get }
8
+ let(:response) { http.send(request_method, path) }
9
+
10
+ let(:remote_url) { ENV['REMOTE_URL'] }
11
+ let(:url) { remote_url || 'http://127.0.0.1:8080' }
12
+ let(:path) { '' }
13
+
14
+ around do |example|
15
+ start_server unless remote_url
16
+ wait_for_server(1)
17
+ example.yield
18
+ kill_server unless remote_url
19
+ end
20
+
21
+ describe 'GET /' do
22
+ let(:path) { '/' }
23
+
24
+ it "succeeds" do
25
+ expect(response).to be_success
26
+ end
27
+ end
28
+ end
29
+
30
+ def start_server
31
+ `bin/whipped-cream start demo.rb --daemonize`
32
+ end
33
+
34
+ def kill_server
35
+ `pkill -9 -f whipped-cream`
36
+ end
37
+
38
+ def wait_for_server(duration)
39
+ Timeout.timeout(duration) do
40
+ begin
41
+ http.get
42
+ rescue Faraday::Error::ConnectionFailed
43
+ sleep 0.01
44
+ retry
45
+ end
46
+ end
47
+ end
@@ -13,7 +13,7 @@ describe WhippedCream::Builder do
13
13
  <<-PLUGIN
14
14
  name "Garage"
15
15
 
16
- button "Open/Close", pin: 1
16
+ button "Open/Close", pin: 4
17
17
  PLUGIN
18
18
  }
19
19
 
@@ -89,7 +89,7 @@ describe WhippedCream::Builder do
89
89
  context "with a button" do
90
90
  let(:plugin) {
91
91
  described_class.build do
92
- button "Open/Close", pin: 1 do
92
+ button "Open/Close", pin: 4 do
93
93
  :tap
94
94
  end
95
95
  end
@@ -101,7 +101,7 @@ describe WhippedCream::Builder do
101
101
  button = plugin.buttons.first
102
102
 
103
103
  expect(button.name).to eq("Open/Close")
104
- expect(button.pin).to eq(1)
104
+ expect(button.pin).to eq(4)
105
105
  end
106
106
  end
107
107
  end
@@ -115,7 +115,7 @@ describe WhippedCream::Builder do
115
115
  let(:plugin) {
116
116
  described_class.build do
117
117
  sensor "Door",
118
- pin: 2,
118
+ pin: 17,
119
119
  low: "Closed",
120
120
  high: "Open",
121
121
  on_high: :door_opened
@@ -128,7 +128,7 @@ describe WhippedCream::Builder do
128
128
  sensor = plugin.sensors.first
129
129
 
130
130
  expect(sensor.name).to eq("Door")
131
- expect(sensor.pin).to eq(2)
131
+ expect(sensor.pin).to eq(17)
132
132
  expect(sensor.low).to eq("Closed")
133
133
  expect(sensor.high).to eq("Open")
134
134
  expect(sensor.on_high).to eq(:door_opened)
@@ -145,7 +145,7 @@ describe WhippedCream::Builder do
145
145
  context "with a switch" do
146
146
  let(:plugin) {
147
147
  described_class.build do
148
- switch "Light", pin: 3
148
+ switch "Light", pin: 18
149
149
  end
150
150
  }
151
151
 
@@ -155,7 +155,7 @@ describe WhippedCream::Builder do
155
155
  switch = plugin.switches.first
156
156
 
157
157
  expect(switch.name).to eq("Light")
158
- expect(switch.pin).to eq(3)
158
+ expect(switch.pin).to eq(18)
159
159
  end
160
160
  end
161
161
  end
@@ -1,13 +1,23 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe WhippedCream::Button do
4
- subject(:button) { described_class.new(name, pin: pin, block: block) }
4
+ context 'valid button' do
5
+ subject(:button) { described_class.new(name, pin: valid_pin, block: block) }
5
6
 
6
- let(:name) { "Open/Close" }
7
- let(:pin) { nil }
8
- let(:block) { nil }
7
+ let(:name) { "Open/Close" }
8
+ let(:valid_pin) { 4 }
9
+ let(:block) { nil }
9
10
 
10
- its(:name) { should eq(name) }
11
- its(:id) { should eq(:open_close) }
12
- its(:type) { should eq(:button) }
11
+ its(:name) { should eq(name) }
12
+ its(:id) { should eq(:open_close) }
13
+ its(:type) { should eq(:button) }
14
+ end
15
+
16
+ context 'invalid button' do
17
+ let(:invalid_pin) { 3 }
18
+
19
+ it 'should raise an error on initialization' do
20
+ expect { described_class.new(name, pin: invalid_pin) }.to raise_error
21
+ end
22
+ end
13
23
  end
@@ -12,7 +12,7 @@ describe WhippedCream::CLI do
12
12
  <<-PLUGIN
13
13
  name "Garage"
14
14
 
15
- button "Open/Close", pin: 1
15
+ button "Open/Close", pin: 4
16
16
  PLUGIN
17
17
  }
18
18
  let(:pi_address) { "192.168.0.123" }
@@ -39,7 +39,7 @@ describe WhippedCream::Plugin do
39
39
 
40
40
  context "with a button" do
41
41
  before do
42
- plugin.controls << WhippedCream::Button.new("Open/Close")
42
+ plugin.controls << WhippedCream::Button.new("Open/Close", pin: 4)
43
43
  end
44
44
 
45
45
  its(:controls) { should_not be_empty }
@@ -14,7 +14,7 @@ describe WhippedCream::Runner do
14
14
  context "with a button" do
15
15
  let(:plugin) {
16
16
  WhippedCream::Plugin.build do
17
- button "Open/Close", pin: 1
17
+ button "Open/Close", pin: 4
18
18
  end
19
19
  }
20
20
 
@@ -22,7 +22,7 @@ describe WhippedCream::Runner do
22
22
  pin = runner.pins[:open_close]
23
23
 
24
24
  expect(pin).to be_a(PiPiper::Pin)
25
- expect(pin.pin).to eq(1)
25
+ expect(pin.pin).to eq(4)
26
26
  expect(pin.direction).to eq(:out)
27
27
  end
28
28
 
@@ -40,7 +40,7 @@ describe WhippedCream::Runner do
40
40
  context "with a sensor" do
41
41
  let(:plugin) {
42
42
  WhippedCream::Plugin.build do
43
- sensor "Door", pin: 2, low: "Open", high: "Closed"
43
+ sensor "Door", pin: 17, low: "Open", high: "Closed"
44
44
  end
45
45
  }
46
46
 
@@ -48,7 +48,7 @@ describe WhippedCream::Runner do
48
48
  pin = runner.pins[:door]
49
49
 
50
50
  expect(pin).to be_a(PiPiper::Pin)
51
- expect(pin.pin).to eq(2)
51
+ expect(pin.pin).to eq(17)
52
52
  expect(pin.direction).to eq(:in)
53
53
  end
54
54
 
@@ -81,7 +81,7 @@ describe WhippedCream::Runner do
81
81
  context "with a switch" do
82
82
  let(:plugin) {
83
83
  WhippedCream::Plugin.build do
84
- switch "Light", pin: 3
84
+ switch "Light", pin: 18
85
85
  end
86
86
  }
87
87
 
@@ -89,7 +89,7 @@ describe WhippedCream::Runner do
89
89
  pin = runner.pins[:light]
90
90
 
91
91
  expect(pin).to be_a(PiPiper::Pin)
92
- expect(pin.pin).to eq(3)
92
+ expect(pin.pin).to eq(18)
93
93
  expect(pin.direction).to eq(:out)
94
94
  end
95
95
 
@@ -1,27 +1,48 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe WhippedCream::Sensor do
4
- subject(:sensor) { described_class.new(name, options, &block) }
5
-
6
- let(:name) { "Door" }
7
- let(:options) {
8
- {
9
- pin: 2,
10
- high: "Open",
11
- low: "Closed",
12
- on_high: :door_opened
4
+ context 'valid sensor' do
5
+ subject(:sensor) { described_class.new(name, valid_options, &block) }
6
+
7
+ let(:name) { "Door" }
8
+ let(:valid_options) {
9
+ {
10
+ pin: 17,
11
+ high: "Open",
12
+ low: "Closed",
13
+ on_high: :door_opened
14
+ }
13
15
  }
14
- }
15
- let(:block) { nil }
16
+ let(:block) { nil }
17
+
18
+ its(:name) { should eq(name) }
19
+ its(:id) { should eq(:door) }
16
20
 
17
- its(:name) { should eq(name) }
18
- its(:id) { should eq(:door) }
21
+ its(:pin) { should eq(17) }
19
22
 
20
- its(:pin) { should eq(2) }
23
+ its(:high) { should eq("Open") }
24
+ its(:low) { should eq("Closed") }
21
25
 
22
- its(:high) { should eq("Open") }
23
- its(:low) { should eq("Closed") }
26
+ its(:on_high) { should eq(:door_opened) }
27
+ its(:on_low) { should be_nil }
28
+ end
29
+
30
+ context 'invalid sensor' do
31
+ let(:name) { "Door" }
32
+ let(:invalid_options) {
33
+ {
34
+ pin: 3,
35
+ high: "Open",
36
+ low: "Closed",
37
+ on_high: :door_opened
38
+ }
39
+ }
40
+ let(:block) { nil }
24
41
 
25
- its(:on_high) { should eq(:door_opened) }
26
- its(:on_low) { should be_nil }
42
+ it 'should raise an error on initialization' do
43
+ expect {
44
+ described_class.new(name, invalid_options, &block)
45
+ }.to raise_error
46
+ end
47
+ end
27
48
  end
@@ -5,7 +5,7 @@ describe WhippedCream::Server do
5
5
 
6
6
  let(:plugin) {
7
7
  WhippedCream::Plugin.build do
8
- button "Open/Close", pin: 1
8
+ button "Open/Close", pin: 4
9
9
  end
10
10
  }
11
11
 
@@ -28,7 +28,7 @@ describe WhippedCream::Server do
28
28
  context "with a button" do
29
29
  let(:plugin) {
30
30
  WhippedCream::Plugin.build do
31
- button "Open/Close", pin: 1
31
+ button "Open/Close", pin: 4
32
32
  end
33
33
  }
34
34
 
@@ -44,7 +44,7 @@ describe WhippedCream::Server do
44
44
  context "with a switch" do
45
45
  let(:plugin) {
46
46
  WhippedCream::Plugin.build do
47
- switch "Light", pin: 1
47
+ switch "Light", pin: 18
48
48
  end
49
49
  }
50
50
 
@@ -1,13 +1,23 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe WhippedCream::Switch do
4
- subject(:switch) { described_class.new(name, pin: pin) }
4
+ context 'valid switch' do
5
+ subject(:switch) { described_class.new(name, pin: valid_pin) }
5
6
 
6
- let(:name) { "Light" }
7
- let(:pin) { 3 }
7
+ let(:name) { "Light" }
8
+ let(:valid_pin) { 18 }
8
9
 
9
- its(:name) { should eq(name) }
10
- its(:id) { should eq(:light) }
11
- its(:type) { should eq(:switch) }
12
- its(:pin) { should eq(3) }
10
+ its(:name) { should eq(name) }
11
+ its(:id) { should eq(:light) }
12
+ its(:type) { should eq(:switch) }
13
+ its(:pin) { should eq(18) }
14
+ end
15
+
16
+ context 'invalid switch' do
17
+ let(:invalid_pin) { 3 }
18
+
19
+ it 'should raise an error upon initialization' do
20
+ expect { described_class.new(name, pin: invalid_pin) }.to raise_error
21
+ end
22
+ end
13
23
  end
@@ -20,4 +20,5 @@ RSpec.configure do |config|
20
20
  end
21
21
 
22
22
  config.order = :random
23
+ config.treat_symbols_as_metadata_keys_with_true_values = true
23
24
  end
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_development_dependency 'bundler', '~> 1.3'
32
32
  spec.add_development_dependency 'cane'
33
+ spec.add_development_dependency 'faraday'
33
34
  spec.add_development_dependency 'rake'
34
35
  spec.add_development_dependency 'rspec'
35
36
  spec.add_development_dependency 'simplecov'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: whipped-cream
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-11 00:00:00.000000000 Z
12
+ date: 2014-01-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-scp
@@ -123,6 +123,22 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: faraday
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
126
142
  - !ruby/object:Gem::Dependency
127
143
  name: rake
128
144
  requirement: !ruby/object:Gem::Requirement
@@ -221,6 +237,7 @@ files:
221
237
  - lib/whipped-cream/views/switch.erb
222
238
  - lib/whipped-cream/web.rb
223
239
  - logo.png
240
+ - spec/acceptance_spec.rb
224
241
  - spec/lib/whipped-cream/builder_spec.rb
225
242
  - spec/lib/whipped-cream/button_spec.rb
226
243
  - spec/lib/whipped-cream/cli_spec.rb
@@ -262,6 +279,7 @@ signing_key:
262
279
  specification_version: 3
263
280
  summary: HTTP topping for Raspberry Pi
264
281
  test_files:
282
+ - spec/acceptance_spec.rb
265
283
  - spec/lib/whipped-cream/builder_spec.rb
266
284
  - spec/lib/whipped-cream/button_spec.rb
267
285
  - spec/lib/whipped-cream/cli_spec.rb
@@ -273,3 +291,4 @@ test_files:
273
291
  - spec/lib/whipped-cream/switch_spec.rb
274
292
  - spec/lib/whipped-cream_spec.rb
275
293
  - spec/spec_helper.rb
294
+ has_rdoc: