traffic_light_controller 0.0.3 → 0.0.4
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.
- 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
|
+
[](http://travis-ci.org/jcmuller/traffic_light_controller)
|
3
|
+
[](https://gemnasium.com/jcmuller/traffic_light_controller)
|
4
|
+
[](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
|