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 +6 -0
- data/Gemfile +12 -1
- data/Gemfile.lock +42 -14
- data/Guardfile +14 -0
- data/README.md +6 -0
- data/lib/traffic_light_controller/server.rb +79 -35
- data/lib/traffic_light_controller/version.rb +1 -1
- data/spec/lib/traffic_light_controller/server_spec.rb +92 -0
- data/spec/spec_helper.rb +8 -0
- metadata +5 -2
data/.travis.yml
ADDED
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.
|
16
|
-
builder (3.1.
|
17
|
-
ci_reporter (1.7.
|
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.
|
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.
|
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
|
-
|
32
|
-
|
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.
|
41
|
-
binding_of_caller (~> 0.6.
|
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.
|
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.
|
72
|
+
rspec-mocks (2.11.3)
|
54
73
|
serialport (1.1.0)
|
55
|
-
simplecov (0.
|
74
|
+
simplecov (0.7.1)
|
56
75
|
multi_json (~> 1.0)
|
57
|
-
simplecov-html (~> 0.
|
58
|
-
simplecov-html (0.
|
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
|
-
|
9
|
+
address_in_use_error(config.server)
|
10
10
|
rescue Errno::EADDRNOTAVAIL, SocketError
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
def work
|
15
|
-
while(
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
55
|
-
|
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,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.
|
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-
|
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
|