whipped-cream 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: