traffic_light_controller 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ bundler_args: --without development
4
+ rvm:
5
+ - 1.9.2
6
+ - 1.9.3
data/Gemfile CHANGED
@@ -2,9 +2,20 @@ source :rubygems
2
2
 
3
3
  gemspec
4
4
 
5
+ group :development do
6
+ gem "guard"
7
+ gem "guard-bundler"
8
+ gem "guard-rspec"
9
+ gem "rb-fchange", :require => false
10
+ gem "rb-fsevent", :require => false
11
+ gem "rb-inotify", :require => false
12
+ gem "terminal-notifier-guard"
13
+ end
14
+
5
15
  group :test do
6
- gem "rspec"
7
16
  gem "ci_reporter"
17
+ gem "rake"
18
+ gem "rspec"
8
19
  gem "simplecov", :require => false
9
20
  gem "simplecov-rcov"
10
21
  end
data/Gemfile.lock CHANGED
@@ -12,11 +12,11 @@ GEM
12
12
  specs:
13
13
  arduino (0.4)
14
14
  serialport (>= 1.0.4)
15
- binding_of_caller (0.6.7)
16
- builder (3.1.2)
17
- ci_reporter (1.7.1)
15
+ binding_of_caller (0.6.8)
16
+ builder (3.1.4)
17
+ ci_reporter (1.7.3)
18
18
  builder (>= 2.1.2)
19
- coderay (1.0.7)
19
+ coderay (1.0.8)
20
20
  columnize (0.3.6)
21
21
  debugger (1.1.4)
22
22
  columnize (>= 0.3.1)
@@ -24,12 +24,26 @@ GEM
24
24
  debugger-ruby_core_source (~> 1.1.3)
25
25
  debugger-linecache (1.1.2)
26
26
  debugger-ruby_core_source (>= 1.1.1)
27
- debugger-ruby_core_source (1.1.3)
27
+ debugger-ruby_core_source (1.1.4)
28
28
  diff-lcs (1.1.3)
29
+ ffi (1.1.5)
30
+ guard (1.5.4)
31
+ listen (>= 0.4.2)
32
+ lumberjack (>= 1.0.2)
33
+ pry (>= 0.9.10)
34
+ thor (>= 0.14.6)
35
+ guard-bundler (1.0.0)
36
+ bundler (~> 1.0)
37
+ guard (~> 1.1)
38
+ guard-rspec (2.1.1)
39
+ guard (>= 1.1)
40
+ rspec (~> 2.11)
29
41
  hashie (1.2.0)
30
42
  json (1.7.5)
31
- method_source (0.8)
32
- multi_json (1.3.6)
43
+ listen (0.5.3)
44
+ lumberjack (1.0.2)
45
+ method_source (0.8.1)
46
+ multi_json (1.3.7)
33
47
  pry (0.9.10)
34
48
  coderay (~> 1.0.5)
35
49
  method_source (~> 0.8)
@@ -37,12 +51,17 @@ GEM
37
51
  pry-debugger (0.2.0)
38
52
  debugger (~> 1.1.3)
39
53
  pry (~> 0.9.9)
40
- pry-stack_explorer (0.4.5)
41
- binding_of_caller (~> 0.6.2)
54
+ pry-stack_explorer (0.4.7)
55
+ binding_of_caller (~> 0.6.8)
42
56
  rack (1.4.1)
43
57
  rack-protection (1.2.0)
44
58
  rack
45
- rake (0.9.2.2)
59
+ rake (10.0.0)
60
+ rb-fchange (0.0.6)
61
+ ffi
62
+ rb-fsevent (0.9.2)
63
+ rb-inotify (0.8.8)
64
+ ffi (>= 0.5.0)
46
65
  rspec (2.11.0)
47
66
  rspec-core (~> 2.11.0)
48
67
  rspec-expectations (~> 2.11.0)
@@ -50,12 +69,12 @@ GEM
50
69
  rspec-core (2.11.1)
51
70
  rspec-expectations (2.11.3)
52
71
  diff-lcs (~> 1.1.3)
53
- rspec-mocks (2.11.2)
72
+ rspec-mocks (2.11.3)
54
73
  serialport (1.1.0)
55
- simplecov (0.6.4)
74
+ simplecov (0.7.1)
56
75
  multi_json (~> 1.0)
57
- simplecov-html (~> 0.5.3)
58
- simplecov-html (0.5.3)
76
+ simplecov-html (~> 0.7.1)
77
+ simplecov-html (0.7.1)
59
78
  simplecov-rcov (0.2.3)
60
79
  simplecov (>= 0.4.1)
61
80
  sinatra (1.3.3)
@@ -63,6 +82,8 @@ GEM
63
82
  rack-protection (~> 1.2)
64
83
  tilt (~> 1.3, >= 1.3.3)
65
84
  slop (3.3.3)
85
+ terminal-notifier-guard (1.5.3)
86
+ thor (0.16.0)
66
87
  tilt (1.3.3)
67
88
 
68
89
  PLATFORMS
@@ -70,11 +91,18 @@ PLATFORMS
70
91
 
71
92
  DEPENDENCIES
72
93
  ci_reporter
94
+ guard
95
+ guard-bundler
96
+ guard-rspec
73
97
  pry
74
98
  pry-debugger
75
99
  pry-stack_explorer
76
100
  rake
101
+ rb-fchange
102
+ rb-fsevent
103
+ rb-inotify
77
104
  rspec
78
105
  simplecov
79
106
  simplecov-rcov
107
+ terminal-notifier-guard
80
108
  traffic_light_controller!
data/Guardfile ADDED
@@ -0,0 +1,14 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'bundler' do
5
+ watch('Gemfile')
6
+ watch(/^.+\.gemspec/)
7
+ end
8
+
9
+ guard 'rspec' do
10
+ watch(%r{^spec/.+_spec\.rb$})
11
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
12
+ watch('spec/spec_helper.rb') { "spec" }
13
+ end
14
+
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # Traffic Light Controller (ruby)
2
+ [![Build Status](https://secure.travis-ci.org/jcmuller/traffic_light_controller.png?branch=master)](http://travis-ci.org/jcmuller/traffic_light_controller)
3
+ [![Dependency Status](https://gemnasium.com/jcmuller/traffic_light_controller.png "Dependency Status")](https://gemnasium.com/jcmuller/traffic_light_controller)
4
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/jcmuller/traffic_light_controller)
5
+
6
+ This piece of work goes along with [Build Status Server](http://github.com/jcmuller/build_status_server)
@@ -6,53 +6,97 @@ module TrafficLightController
6
6
  @config = Config.new
7
7
  @server = TCPServer.new(config.server.address, config.server.port)
8
8
  rescue Errno::EADDRINUSE
9
- puts "Address in use"
9
+ address_in_use_error(config.server)
10
10
  rescue Errno::EADDRNOTAVAIL, SocketError
11
- puts "Address not available"
12
- end
13
-
14
- def work(run_forever = true)
15
- while(run_forever)
16
- Thread.start(server.accept) do |client|
17
- begin
18
- path = nil
19
-
20
- while(line = client.readline) do
21
- break if line == "\r\n"
22
- if match = line.match(%r{GET /+(?<path>\w*) HTTP/1\.})
23
- path = match[:path]
24
- end
25
- end
26
-
27
- if config.arduino.lights.has_key?(path)
28
- process(path)
29
- client.print "HTTP/1.1 200 OK\r\nContent-type:text/plain\r\n\r\n"
30
- client.puts path
31
- else
32
- client.print "HTTP/1.1 404 Not Found\r\nContent-type:text/plain\r\n\r\n"
33
- client.puts "The requested path doesn't exist"
34
- end
35
- rescue => e
36
- puts "Got #{e}!"
37
- ensure
38
- client.close
39
- end
11
+ address_not_available_error(config.server.address)
12
+ end
13
+
14
+ def work
15
+ while(true)
16
+ start_thread_and_do_work
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :server, :config, :board
23
+
24
+ def start_thread_and_do_work
25
+ Thread.start(server.accept) do |client|
26
+ work_with_client(client)
27
+ end
28
+ end
29
+
30
+ def work_with_client(client)
31
+ puts "work_with_client"
32
+ process_path(process_request(client))
33
+ rescue => e
34
+ puts "Got #{e.class}: #{e}!"
35
+ ensure
36
+ client.close
37
+ end
38
+
39
+ def process_request(client)
40
+ puts "process_request"
41
+ path = nil
42
+
43
+ while(line = client.readline) do
44
+ break if line == "\r\n"
45
+ if match = line.match(%r{GET /+(?<path>\w*) HTTP/1\.})
46
+ path = match[:path]
40
47
  end
41
48
  end
49
+
50
+ path
51
+ end
52
+
53
+ def process_path(path)
54
+ puts "process_path"
55
+ if config.arduino.lights.has_key?(path)
56
+ change_pins(path)
57
+ client.print "HTTP/1.1 200 OK\r\nContent-type:text/plain\r\n\r\n"
58
+ client.puts path
59
+ else
60
+ client.print "HTTP/1.1 404 Not Found\r\nContent-type:text/plain\r\n\r\n"
61
+ client.puts "The requested path doesn't exist"
62
+ end
42
63
  end
43
64
 
44
- def process(path)
65
+ def change_pins(path)
66
+ puts "change_pins"
67
+ init_board
45
68
  board.turnOff
46
69
  board.setHigh(config.arduino.lights[path]) unless path == "off"
47
70
  board.close
48
71
  end
49
72
 
50
- private
73
+ def init_board
74
+ puts "board"
75
+ @board = Arduino.new(config.arduino.port)
76
+ rescue Errno::ENOENT
77
+ STDERR.puts "The port #{config.arduino.port} doesn't exist"
78
+ exit
79
+ rescue ArgumentError
80
+ STDERR.puts "#{config.arduino.port} is not a serial port"
81
+ exit
82
+ end
51
83
 
52
- attr_reader :server, :config
84
+ # ERRORS
85
+ def address_in_use_error(server)
86
+ STDERR.puts <<-EOT
87
+ There appears that another instance is running, or another process
88
+ is listening on the same port (#{server.address}:#{server.port})
53
89
 
54
- def board
55
- @board = Arduino.new(config.arduino.port)
90
+ EOT
91
+ exit
92
+ end
93
+
94
+ def address_not_available_error(address)
95
+ STDERR.puts <<-EOT
96
+ The address configured is not available (#{address})
97
+
98
+ EOT
99
+ exit
56
100
  end
57
101
  end
58
102
  end
@@ -1,3 +1,3 @@
1
1
  module TrafficLightController
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -1,4 +1,96 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe TrafficLightController::Server do
4
+ let(:board) { mock }
5
+ let(:config) { mock }
6
+ let(:server) { mock(accept: client) }
7
+ let(:client) { mock }
8
+
9
+ before do
10
+ config.stub_chain(:server, :address).and_return("127.0.0.1")
11
+ config.stub_chain(:server, :port).and_return(10000 + rand(1000))
12
+ config.stub_chain(:arduino, :port).and_return("port")
13
+
14
+ TrafficLightController::Config.stub(:new).and_return(config)
15
+ TCPServer.stub(:new).and_return(server)
16
+ STDOUT.stub(:puts)
17
+ end
18
+
19
+ context "public methods" do
20
+ before do
21
+ subject.stub(:board).and_return(board)
22
+ end
23
+
24
+ describe "#initialize" do
25
+ it "should call address_in_use_error if address is in use" do
26
+ TCPServer.should_receive(:new).and_raise(Errno::EADDRINUSE)
27
+ described_class.any_instance.should_receive(:address_in_use_error)
28
+ described_class.new
29
+ end
30
+
31
+ it "should call address_in_use_error if address is not available" do
32
+ TCPServer.should_receive(:new).and_raise(Errno::EADDRNOTAVAIL)
33
+ described_class.any_instance.should_receive(:address_not_available_error)
34
+ described_class.new
35
+ end
36
+ end
37
+
38
+ describe "#change_pins" do
39
+ before { subject.stub(:init_board) }
40
+
41
+ it "set high the pin pointed to by path" do
42
+ config.stub_chain(:arduino, :lights).and_return({"blah" => 4})
43
+ board.should_receive(:turnOff)
44
+ board.should_receive(:setHigh).with(4)
45
+ board.should_receive(:close)
46
+
47
+ subject.send(:change_pins, "blah")
48
+ end
49
+
50
+ it "should not set high any pins" do
51
+ board.should_receive(:turnOff)
52
+ board.should_not_receive(:setHigh)
53
+ board.should_receive(:close)
54
+
55
+ subject.send(:change_pins, "off")
56
+ end
57
+ end
58
+ end
59
+
60
+ context "private methods" do
61
+ describe "#board" do
62
+ it "should instantiate a new arduino object" do
63
+ Arduino.should_receive(:new).with("port")
64
+ subject.send(:init_board)
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#start_thread_and_do_work" do
70
+ it "should start a thread" do
71
+ Thread.should_receive(:start).and_yield(client)
72
+ subject.should_receive(:work_with_client).with(client)
73
+ subject.send(:start_thread_and_do_work)
74
+ end
75
+ end
76
+
77
+ describe "#work_with_client" do
78
+ it "should call process path" do
79
+ subject.should_receive(:process_request).with(client).and_return(:processed)
80
+ subject.should_receive(:process_path).with(:processed)
81
+ client.should_receive(:close)
82
+
83
+ subject.send(:work_with_client, client)
84
+ end
85
+
86
+ it "should rescue from all exceptions and log them to STDOUT" do
87
+ subject.should_receive(:process_request).and_raise RuntimeError
88
+
89
+ STDOUT.should_receive(:puts).with("Got RuntimeError: RuntimeError!")
90
+
91
+ client.should_receive(:close)
92
+
93
+ subject.send(:work_with_client, client)
94
+ end
95
+ end
4
96
  end
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,14 @@
5
5
  #
6
6
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
7
 
8
+ require "simplecov"
9
+ require 'simplecov-rcov'
10
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
11
+ SimpleCov.start do
12
+ add_filter "vendor/bundler_gems" # Ignore gems
13
+ add_filter "spec"
14
+ end
15
+
8
16
  require "rspec/core"
9
17
  require "rspec/mocks"
10
18
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: traffic_light_controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
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: 2012-10-24 00:00:00.000000000 Z
12
+ date: 2012-11-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -147,9 +147,12 @@ extensions: []
147
147
  extra_rdoc_files: []
148
148
  files:
149
149
  - .gitignore
150
+ - .travis.yml
150
151
  - Gemfile
151
152
  - Gemfile.lock
153
+ - Guardfile
152
154
  - LICENSE
155
+ - README.md
153
156
  - Rakefile
154
157
  - bin/traffic_light_controller
155
158
  - config/.gitignore