artoo 1.6.7 → 1.8.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +6 -20
- data/artoo.gemspec +7 -7
- data/bin/artoo +0 -8
- data/examples/ardrone_nav_video_wii.rb +1 -1
- data/examples/ardrone_nav_wiiclassic.rb +1 -1
- data/examples/ardrone_wiiclassic.rb +1 -1
- data/examples/firmata.rb +1 -1
- data/examples/firmata_button.rb +1 -1
- data/examples/hello_api_multiple.rb +1 -1
- data/examples/roomba_wiichuck.rb +1 -1
- data/examples/sphero.rb +2 -2
- data/examples/sphero_color.rb +1 -1
- data/examples/sphero_color_wiichuck.rb +2 -2
- data/examples/sphero_cycle.rb +1 -1
- data/examples/sphero_messages.rb +1 -1
- data/examples/sphero_pebble.rb +42 -0
- data/examples/sphero_wiichuck.rb +3 -3
- data/examples/test_bot.rb +23 -0
- data/examples/wiichuck.rb +1 -1
- data/examples/wiiclassic.rb +1 -1
- data/lib/artoo/api/api.rb +93 -30
- data/lib/artoo/api/device_event_client.rb +15 -10
- data/lib/artoo/api/route_helpers.rb +14 -3
- data/lib/artoo/connection.rb +8 -5
- data/lib/artoo/device.rb +29 -11
- data/lib/artoo/drivers/driver.rb +4 -0
- data/lib/artoo/drivers/{pinger.rb → ping.rb} +6 -6
- data/lib/artoo/interfaces/interface.rb +37 -0
- data/lib/artoo/interfaces/ping.rb +17 -0
- data/lib/artoo/interfaces/rover.rb +35 -0
- data/lib/artoo/master.rb +45 -3
- data/lib/artoo/robot.rb +33 -8
- data/lib/artoo/utility.rb +10 -0
- data/lib/artoo/version.rb +1 -1
- data/test/api/api_routes_test.rb +46 -0
- data/test/connection_test.rb +2 -2
- data/test/device_test.rb +8 -1
- data/test/interfaces/interface_test.rb +29 -0
- data/test/master_test.rb +13 -7
- metadata +32 -28
- data/Gemfile.lock +0 -88
- data/lib/artoo/commands/bluetooth.rb +0 -74
- data/lib/artoo/commands/scan.rb +0 -42
- data/lib/artoo/ext/actor.rb +0 -18
- data/lib/artoo/ext/timers.rb +0 -41
data/lib/artoo/connection.rb
CHANGED
@@ -9,7 +9,7 @@ module Artoo
|
|
9
9
|
include Artoo::Utility
|
10
10
|
include Comparable
|
11
11
|
|
12
|
-
attr_reader :parent, :name, :port, :adaptor, :connection_id
|
12
|
+
attr_reader :parent, :name, :port, :adaptor, :connection_id, :details
|
13
13
|
|
14
14
|
# Create new connection
|
15
15
|
# @param [Hash] params
|
@@ -23,6 +23,7 @@ module Artoo
|
|
23
23
|
@name = params[:name].to_s
|
24
24
|
@port = Port.new(params[:port])
|
25
25
|
@parent = params[:parent]
|
26
|
+
@details = remove_keys(params, :name, :parent, :id, :loopback)
|
26
27
|
|
27
28
|
require_adaptor(params[:adaptor] || :loopback, params)
|
28
29
|
end
|
@@ -58,10 +59,8 @@ module Artoo
|
|
58
59
|
def to_hash
|
59
60
|
{
|
60
61
|
:name => name,
|
61
|
-
:connection_id => connection_id,
|
62
|
-
:port => port.to_s,
|
63
62
|
:adaptor => adaptor_name.to_s.gsub(/^.*::/, ''),
|
64
|
-
:
|
63
|
+
:details => @details
|
65
64
|
}
|
66
65
|
end
|
67
66
|
|
@@ -90,11 +89,15 @@ module Artoo
|
|
90
89
|
return nil
|
91
90
|
end
|
92
91
|
|
92
|
+
def respond_to_missing?(method_name, include_private = false)
|
93
|
+
# TODO: verify that the adaptor supprts the method we're calling
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
93
97
|
private
|
94
98
|
|
95
99
|
def require_adaptor(type, params)
|
96
100
|
if Artoo::Robot.test?
|
97
|
-
original_type = type
|
98
101
|
type = :test
|
99
102
|
end
|
100
103
|
|
data/lib/artoo/device.rb
CHANGED
@@ -6,7 +6,7 @@ module Artoo
|
|
6
6
|
include Celluloid
|
7
7
|
include Artoo::Utility
|
8
8
|
|
9
|
-
attr_reader :parent, :name, :driver, :pin, :connection, :interval
|
9
|
+
attr_reader :parent, :name, :driver, :pin, :connection, :interval, :interface, :details
|
10
10
|
|
11
11
|
# Create new device
|
12
12
|
# @param [Hash] params
|
@@ -17,11 +17,15 @@ module Artoo
|
|
17
17
|
# @option params :interval [String]
|
18
18
|
# @option params :driver [String]
|
19
19
|
def initialize(params={})
|
20
|
-
@name
|
21
|
-
@pin
|
22
|
-
@parent
|
23
|
-
@connection = determine_connection(params[:connection]) ||
|
24
|
-
|
20
|
+
@name = params[:name].to_s
|
21
|
+
@pin = params[:pin]
|
22
|
+
@parent = params[:parent]
|
23
|
+
@connection = determine_connection(params[:connection]) ||
|
24
|
+
default_connection
|
25
|
+
@interval = params[:interval] || 0.5
|
26
|
+
|
27
|
+
@details = remove_keys(params, :name, :parent, :connection,
|
28
|
+
:passthru, :driver)
|
25
29
|
|
26
30
|
require_driver(params[:driver] || :passthru, params)
|
27
31
|
end
|
@@ -60,10 +64,9 @@ module Artoo
|
|
60
64
|
{
|
61
65
|
:name => name,
|
62
66
|
:driver => driver.class.name.to_s.gsub(/^.*::/, ''),
|
63
|
-
:
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:commands => driver.commands
|
67
|
+
:connection => connection.name,
|
68
|
+
:commands => driver.commands,
|
69
|
+
:details => @details
|
67
70
|
}
|
68
71
|
end
|
69
72
|
|
@@ -87,9 +90,24 @@ module Artoo
|
|
87
90
|
command(method_name, *arguments, &block)
|
88
91
|
end
|
89
92
|
|
93
|
+
def respond_to_missing?(method_name, include_private = false)
|
94
|
+
commands.include?(method_name) || super
|
95
|
+
end
|
96
|
+
|
90
97
|
# @return [String] pretty inspect
|
91
98
|
def inspect
|
92
|
-
"#<Device @id=#{object_id}, @name='name', @driver='driver'>"
|
99
|
+
"#<Device @id=#{object_id}, @name='name', @driver='#{driver.class.name}'>"
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_interface(i)
|
103
|
+
@parent.add_interface(i)
|
104
|
+
end
|
105
|
+
|
106
|
+
def require_interface(i)
|
107
|
+
Logger.info "Require interface #{i}"
|
108
|
+
require "artoo/interfaces/#{i.to_s}"
|
109
|
+
@interface = constantize("Artoo::Interfaces::#{classify(i.to_s)}").new(:name => i.to_s, :robot => parent, :device => current_instance)
|
110
|
+
add_interface(@interface)
|
93
111
|
end
|
94
112
|
|
95
113
|
private
|
data/lib/artoo/drivers/driver.rb
CHANGED
@@ -77,6 +77,10 @@ module Artoo
|
|
77
77
|
return false
|
78
78
|
end
|
79
79
|
|
80
|
+
def require_interface(i)
|
81
|
+
parent.require_interface(i)
|
82
|
+
end
|
83
|
+
|
80
84
|
# Sends missing methods to connection
|
81
85
|
def method_missing(method_name, *arguments, &block)
|
82
86
|
connection.send(method_name, *arguments, &block)
|
@@ -3,22 +3,22 @@ require 'artoo/drivers/driver'
|
|
3
3
|
module Artoo
|
4
4
|
module Drivers
|
5
5
|
# Test driver that can be pinged itself
|
6
|
-
class
|
6
|
+
class Ping < Driver
|
7
7
|
|
8
8
|
COMMANDS = [:ping].freeze
|
9
9
|
|
10
10
|
def start_driver
|
11
|
-
@count = 0
|
12
11
|
super
|
13
12
|
end
|
14
13
|
|
15
14
|
# Publishes events to update event topic
|
16
15
|
# when pinged
|
17
16
|
def ping
|
18
|
-
|
19
|
-
publish(event_topic_name("update"), "ping",
|
20
|
-
publish(event_topic_name("ping"),
|
21
|
-
|
17
|
+
data = 'pong'
|
18
|
+
publish(event_topic_name("update"), "ping", data)
|
19
|
+
publish(event_topic_name("ping"), data)
|
20
|
+
|
21
|
+
data
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Artoo
|
2
|
+
module Interfaces
|
3
|
+
# The Interface class is the base class used to
|
4
|
+
# implement behavior for a specific category of robot. Examples
|
5
|
+
# would be a Rover or Copter.
|
6
|
+
#
|
7
|
+
# Derive a class from this class, in order to implement higher-order
|
8
|
+
# behavior for a new category of robot.
|
9
|
+
class Interface
|
10
|
+
include Celluloid
|
11
|
+
include Celluloid::Notifications
|
12
|
+
|
13
|
+
attr_accessor :name, :robot, :device
|
14
|
+
|
15
|
+
def interface_type
|
16
|
+
:raw
|
17
|
+
end
|
18
|
+
|
19
|
+
COMMANDS = [].freeze
|
20
|
+
|
21
|
+
# Create new interface
|
22
|
+
# @param [Hash] params
|
23
|
+
# @option params [Object] :robot
|
24
|
+
# @option params [Object] :device
|
25
|
+
def initialize(params={})
|
26
|
+
@name = params[:name]
|
27
|
+
@robot = params[:robot]
|
28
|
+
@device = params[:device]
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Collection] commands
|
32
|
+
def commands
|
33
|
+
self.class.const_get('COMMANDS')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'artoo/interfaces/interface'
|
2
|
+
|
3
|
+
module Artoo
|
4
|
+
module Interfaces
|
5
|
+
# The Rover interface.
|
6
|
+
class Rover < Interface
|
7
|
+
def interface_type
|
8
|
+
:rover
|
9
|
+
end
|
10
|
+
|
11
|
+
COMMANDS = [:forward, :backward, :left, :right, :turn_left, :turn_right, :stop]
|
12
|
+
|
13
|
+
def forward(speed)
|
14
|
+
end
|
15
|
+
|
16
|
+
def backward(speed)
|
17
|
+
end
|
18
|
+
|
19
|
+
def left(speed)
|
20
|
+
end
|
21
|
+
|
22
|
+
def right(speed)
|
23
|
+
end
|
24
|
+
|
25
|
+
def turn_left(degrees)
|
26
|
+
end
|
27
|
+
|
28
|
+
def turn_right(degrees)
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/artoo/master.rb
CHANGED
@@ -22,6 +22,10 @@ module Artoo
|
|
22
22
|
current.robot(name)
|
23
23
|
end
|
24
24
|
|
25
|
+
def robot?(name)
|
26
|
+
current.robot?(name)
|
27
|
+
end
|
28
|
+
|
25
29
|
def start_work
|
26
30
|
current.start_work
|
27
31
|
end
|
@@ -37,12 +41,26 @@ module Artoo
|
|
37
41
|
def continue_work
|
38
42
|
current.continue_work
|
39
43
|
end
|
44
|
+
|
45
|
+
def command(name, params)
|
46
|
+
current.command(name, params)
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_command(name, behaviour)
|
50
|
+
current.add_command(name, behaviour)
|
51
|
+
end
|
52
|
+
|
53
|
+
def commands
|
54
|
+
current.commands
|
55
|
+
end
|
56
|
+
|
40
57
|
end
|
41
58
|
|
42
59
|
# Create new master
|
43
60
|
# @param [Collection] robots
|
44
61
|
def initialize(bots=[])
|
45
62
|
@robots = []
|
63
|
+
@commands = []
|
46
64
|
assign(bots)
|
47
65
|
end
|
48
66
|
|
@@ -56,9 +74,11 @@ module Artoo
|
|
56
74
|
# @param [String] name
|
57
75
|
# @return [Robot] robot
|
58
76
|
def robot(name)
|
59
|
-
|
60
|
-
|
61
|
-
|
77
|
+
robots.find {|r| r.name == name}
|
78
|
+
end
|
79
|
+
|
80
|
+
def robot?(name)
|
81
|
+
robots.find {|r| r.name == name}
|
62
82
|
end
|
63
83
|
|
64
84
|
# @param [String] name
|
@@ -111,5 +131,27 @@ module Artoo
|
|
111
131
|
robots.each {|r| r.terminate} unless !Artoo::Robot.is_running?
|
112
132
|
Artoo::Robot.stopped!
|
113
133
|
end
|
134
|
+
|
135
|
+
# return list of master command names
|
136
|
+
def commands
|
137
|
+
@commands.map{ |c| c[:name] }
|
138
|
+
end
|
139
|
+
|
140
|
+
# execute master command
|
141
|
+
def command(name, params)
|
142
|
+
command = @commands.find{ |c| c[:name] == name.to_sym }
|
143
|
+
if command
|
144
|
+
if params.nil?
|
145
|
+
command[:behaviour].call
|
146
|
+
else
|
147
|
+
command[:behaviour].call(params)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# add command to master
|
153
|
+
def add_command(name, behaviour)
|
154
|
+
@commands << { name: name.to_sym, behaviour: behaviour }
|
155
|
+
end
|
114
156
|
end
|
115
157
|
end
|
data/lib/artoo/robot.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'celluloid/autostart'
|
2
2
|
require 'celluloid/io'
|
3
3
|
require 'multi_json'
|
4
|
-
require 'artoo/ext/timers'
|
5
|
-
require 'artoo/ext/actor'
|
6
4
|
|
7
5
|
require 'artoo/robot_class_methods'
|
8
6
|
require 'artoo/basic'
|
@@ -16,6 +14,9 @@ require 'artoo/api/api'
|
|
16
14
|
require 'artoo/master'
|
17
15
|
require 'artoo/port'
|
18
16
|
require 'artoo/utility'
|
17
|
+
require 'artoo/interfaces/interface'
|
18
|
+
require 'artoo/interfaces/ping'
|
19
|
+
require 'artoo/interfaces/rover'
|
19
20
|
|
20
21
|
module Artoo
|
21
22
|
# The most important class used by Artoo is Robot. This represents the primary
|
@@ -30,7 +31,7 @@ module Artoo
|
|
30
31
|
include Artoo::Utility
|
31
32
|
include Artoo::Events
|
32
33
|
|
33
|
-
attr_reader :connections, :devices, :name, :commands
|
34
|
+
attr_reader :connections, :devices, :name, :commands, :interfaces
|
34
35
|
|
35
36
|
exclusive :execute_startup
|
36
37
|
|
@@ -42,6 +43,7 @@ module Artoo
|
|
42
43
|
def initialize(params={})
|
43
44
|
@name = params[:name] || current_class.name || "Robot #{random_string}"
|
44
45
|
@commands = params[:commands] || []
|
46
|
+
@interfaces = {}
|
45
47
|
initialize_connections(params[:connections] || {})
|
46
48
|
initialize_devices(params[:devices] || {})
|
47
49
|
end
|
@@ -134,12 +136,14 @@ module Artoo
|
|
134
136
|
"#<Robot #{object_id}>"
|
135
137
|
end
|
136
138
|
|
137
|
-
|
138
|
-
|
139
|
+
# @return [Object] whatever result is passed back from the wrapped robot
|
140
|
+
def command(method_name, *arguments, &block)
|
141
|
+
t = interface_for_command(method_name)
|
142
|
+
if t
|
139
143
|
if arguments.first
|
140
|
-
|
144
|
+
t.send(method_name, *arguments)
|
141
145
|
else
|
142
|
-
|
146
|
+
t.send(method_name)
|
143
147
|
end
|
144
148
|
else
|
145
149
|
"Unknown Command"
|
@@ -151,10 +155,31 @@ module Artoo
|
|
151
155
|
end
|
152
156
|
|
153
157
|
# @return [Boolean] True if command exists
|
154
|
-
def
|
158
|
+
def own_command?(method_name)
|
155
159
|
return commands.include?(method_name.intern)
|
156
160
|
end
|
157
161
|
|
162
|
+
def add_interface(i)
|
163
|
+
@interfaces[i.interface_type.intern] = i
|
164
|
+
end
|
165
|
+
|
166
|
+
# @return [Boolean] True if command exists in any of the robot's interfaces
|
167
|
+
def interface_for_command(method_name)
|
168
|
+
return self if own_command?(method_name)
|
169
|
+
@interfaces.each_value {|i|
|
170
|
+
return i if i.commands.include?(method_name.intern)
|
171
|
+
}
|
172
|
+
return nil
|
173
|
+
end
|
174
|
+
|
175
|
+
# Sends missing methods to command
|
176
|
+
def method_missing(method_name, *arguments, &block)
|
177
|
+
command(method_name, *arguments, &block)
|
178
|
+
end
|
179
|
+
|
180
|
+
def respond_to_missing?(method_name, include_private = false)
|
181
|
+
own_command?(method_name)|| interface_for_command(method_name)
|
182
|
+
end
|
158
183
|
|
159
184
|
private
|
160
185
|
|
data/lib/artoo/utility.rb
CHANGED
@@ -85,5 +85,15 @@ module Artoo
|
|
85
85
|
end
|
86
86
|
)
|
87
87
|
end
|
88
|
+
|
89
|
+
# Removes selected keys from hash
|
90
|
+
# @example {one: 'one', two: 'two'} => {two: 'two'}
|
91
|
+
# @return [Hash] new object without selected keys
|
92
|
+
def remove_keys(h, *keys)
|
93
|
+
hash = h.dup
|
94
|
+
keys.each { |key| hash.delete(key) }
|
95
|
+
hash
|
96
|
+
end
|
97
|
+
|
88
98
|
end
|
89
99
|
end
|
data/lib/artoo/version.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
|
3
|
+
describe "API routes" do
|
4
|
+
|
5
|
+
let(:base) { 'http://localhost:8080' }
|
6
|
+
|
7
|
+
def validate_route(relative_path, status=200)
|
8
|
+
res = HTTP.get(base + relative_path)
|
9
|
+
res.status.must_equal status
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_form(relative_path, params)
|
13
|
+
res = HTTP.post base + '/api/commands/echo', :body => JSON.dump(params)
|
14
|
+
|
15
|
+
res.status.must_equal 200
|
16
|
+
end
|
17
|
+
|
18
|
+
before :all do
|
19
|
+
@pid = fork { require_relative '../../examples/test_bot' }
|
20
|
+
sleep 1
|
21
|
+
end
|
22
|
+
|
23
|
+
after (:all) { system("kill -9 #{@pid}") }
|
24
|
+
|
25
|
+
it 'must respond to expected routes' do
|
26
|
+
validate_route('/api')
|
27
|
+
validate_route('/api/commands')
|
28
|
+
validate_route('/api/robots')
|
29
|
+
validate_route('/api/robots/TestBot')
|
30
|
+
validate_route('/api/robots/NonExistentBot', 404)
|
31
|
+
validate_route('/api/robots/TestBot/commands')
|
32
|
+
validate_route('/api/robots/TestBot/commands/hello')
|
33
|
+
validate_route('/api/robots/TestBot/devices')
|
34
|
+
validate_route('/api/robots/TestBot/devices/ping')
|
35
|
+
validate_route('/api/robots/TestBot/devices/ping/commands')
|
36
|
+
validate_route('/api/robots/TestBot/connections')
|
37
|
+
validate_route('/api/robots/TestBot/connections/loopback')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'must respond to command calls' do
|
41
|
+
validate_form('/api/commands/echo', { param: 'pong' })
|
42
|
+
validate_form('/api/robots/TestBot/devices/ping/commands/ping',
|
43
|
+
{ name: 'bot' })
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/test/connection_test.rb
CHANGED
@@ -23,10 +23,10 @@ describe Artoo::Connection do
|
|
23
23
|
|
24
24
|
it 'Artoo::Connection#as_json' do
|
25
25
|
MultiJson.load(@connection.as_json, :symbolize_keys => true)[:name].must_equal "my_test_connection"
|
26
|
-
MultiJson.load(@connection.as_json, :symbolize_keys => true)[:
|
26
|
+
MultiJson.load(@connection.as_json, :symbolize_keys => true)[:adaptor].must_equal "Loopback"
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'Artoo::Connection#additional_params' do
|
30
30
|
@robot.default_connection.adaptor.additional_params[:awesomeness].must_equal :high
|
31
31
|
end
|
32
|
-
end
|
32
|
+
end
|
data/test/device_test.rb
CHANGED
@@ -43,4 +43,11 @@ describe Artoo::Device do
|
|
43
43
|
@device = @robot.devices[:test_device_2]
|
44
44
|
@device.driver.additional_params[:cool_factor].must_equal 11
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
|
+
it 'Artoo::Device#require_interface' do
|
48
|
+
@device = @robot.devices[:test_device_1]
|
49
|
+
@device.require_interface(:ping)
|
50
|
+
@device.interface.name.must_equal 'ping'
|
51
|
+
@robot.interfaces[:ping].name.must_equal 'ping'
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
|
2
|
+
|
3
|
+
class Awesomeness < Artoo::Interfaces::Interface
|
4
|
+
COMMANDS = [:awesome].freeze
|
5
|
+
|
6
|
+
def interface_type
|
7
|
+
:awesomeness
|
8
|
+
end
|
9
|
+
|
10
|
+
def awesome
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Artoo::Interfaces::Interface do
|
16
|
+
before do
|
17
|
+
@robot = mock('robot')
|
18
|
+
@device = mock('device')
|
19
|
+
@interface = Awesomeness.new(:robot => @robot, :device => @device)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'Interface#interface_type' do
|
23
|
+
@interface.interface_type.must_equal :awesomeness
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'Interface#commands' do
|
27
|
+
@interface.commands.first.must_equal :awesome
|
28
|
+
end
|
29
|
+
end
|
data/test/master_test.rb
CHANGED
@@ -23,7 +23,7 @@ describe Artoo::Master do
|
|
23
23
|
@robot1 = MockRobot.new("robot1")
|
24
24
|
@robot2 = MockRobot.new("robot2")
|
25
25
|
@robot3 = MockRobot.new("robot3")
|
26
|
-
|
26
|
+
|
27
27
|
@robots << @robot1
|
28
28
|
@robots << @robot2
|
29
29
|
@robots << @robot3
|
@@ -36,14 +36,20 @@ describe Artoo::Master do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'Artoo::Master#robot with invalid robot name' do
|
39
|
-
|
39
|
+
@master.robot("robotno").must_equal(nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'Artoo::Master::#commands' do
|
43
|
+
@master.commands.must_equal []
|
40
44
|
end
|
41
45
|
|
42
|
-
it 'Artoo::Master
|
43
|
-
@master.
|
46
|
+
it 'Artoo::Master::#add_command' do
|
47
|
+
@master.add_command :test, lambda{}
|
48
|
+
@master.commands.must_equal [:test]
|
44
49
|
end
|
45
50
|
|
46
|
-
it 'Artoo::Master
|
47
|
-
@master.
|
51
|
+
it 'Artoo::Master::#command' do
|
52
|
+
@master.add_command :test, lambda{'test'}
|
53
|
+
@master.command(:test, nil).must_equal 'test'
|
48
54
|
end
|
49
|
-
end
|
55
|
+
end
|