lego-nxt 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ class Module
2
+ # Creates an invariant accessor that allows getting and setting from the same
3
+ # endpoint. It will operate in getter mode if you don't pass any arguments
4
+ # when calling it, otherwise it will work in setter mode. Useful when needing
5
+ # to chain methods (you can't chain standard attr_writer methods because
6
+ # of the `= something` part).
7
+ def attr_combined_accessor(sym, default = nil)
8
+ define_method(sym) do |*args|
9
+ if args.empty?
10
+ instance_var = :"@#{sym}"
11
+ if (value = self.instance_variable_get(instance_var))
12
+ value
13
+ else
14
+ self.instance_variable_set(instance_var, default)
15
+ default
16
+ end
17
+ else
18
+ send(:"#{sym}=", *args)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ class String
2
+ # Convert the given string to a hexadecimal representation of the same data.
3
+ # This method is non-destructive, it will return a new copy of the string
4
+ # convered to hex.
5
+ def to_hex_str
6
+ str = ''
7
+ self.each_byte {|b| str << '0x%02x ' % b}
8
+ str
9
+ end
10
+
11
+ #
12
+ def from_hex_str_two
13
+ data = self.split(' ')
14
+ str = ''
15
+ data.each {|h| eval "str += '%c' % #{h}"}
16
+ str
17
+ end
18
+
19
+ def from_hex_str
20
+ data = self.split(' ')
21
+ str = ''
22
+
23
+ data.each do |h|
24
+ str += '%c' % h
25
+ end
26
+
27
+ str
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ module NXT
2
+ module Utils
3
+ module Accessors
4
+ def attr_setter(name, options)
5
+ define_method("#{name}=") do |value|
6
+ if options.include?(:is)
7
+ raise TypeError.new('Expected value to be a number') unless duration.is_a?(options[:is])
8
+ end
9
+
10
+ if options.include?(:is_key_in) && !options[:is_key_in].include?(value)
11
+ raise TypeError.new("Expected value to be one of: :#{options[:is_key_in].keys.join(', :')}")
12
+ end
13
+
14
+ instance_variable_set("@#{name}", value)
15
+ self
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ require 'rspec/expectations'
2
+
3
+ RSpec::Matchers.define :have_constant do |expected|
4
+ match do |actual|
5
+ actual.class.constants.include?(expected)
6
+ end
7
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe NXT::Interface::SerialPort do
4
+ before do
5
+ @device = '/dev/zero'
6
+ @bad_device = 'hello world'
7
+ end
8
+
9
+ subject do
10
+ NXT::Interface::SerialPort.new(@device)
11
+ end
12
+
13
+ describe 'constants' do
14
+ it 'should have a BAUD_RATE constant' do
15
+ should have_constant(:BAUD_RATE)
16
+ should have_constant(:DATA_BITS)
17
+ should have_constant(:STOP_BITS)
18
+ should have_constant(:PARITY)
19
+ should have_constant(:READ_TIMEOUT)
20
+ end
21
+ end
22
+
23
+ describe 'accessors' do
24
+ it 'should have read/write accessor for @dev' do
25
+ should respond_to(:dev)
26
+ should respond_to(:dev=)
27
+ end
28
+ end
29
+
30
+ describe '#initialize' do
31
+ it 'should set the device to the incomming argument' do
32
+ subject.dev.should equal(@device)
33
+ end
34
+
35
+ it 'should raise an exception when trying to connect to invalid dev files' do
36
+ expect do
37
+ serial_port = subject.class.new(@bad_device)
38
+ end.to raise_exception(InvalidDeviceError)
39
+ end
40
+ end
41
+
42
+ describe '#connect' do
43
+ it 'should raise an exception when the SerialPort connection failed' do
44
+ expect do
45
+ subject.connect
46
+ end.to raise_exception(SerialPortConnectionError, 'The #{@device} device is not a valid SerialPort')
47
+ end
48
+
49
+ it 'should raise an exception when the SerialPort connection is nil' do
50
+ ::SerialPort.should_receive(:new).and_return(nil)
51
+ expect do
52
+ subject.connect
53
+ end.to raise_exception(SerialPortConnectionError, "Could not establish a SerialPort connection to #{@device}")
54
+ end
55
+
56
+ it 'should set the flow control and read timeout when the connection is established' do
57
+ serial_port_stub = stub()
58
+ serial_port_stub.should_receive(:flow_control=).with(::SerialPort::HARD).once
59
+ serial_port_stub.should_receive(:read_timeout=).with(subject.class::READ_TIMEOUT).once
60
+ ::SerialPort.should_receive(:new).and_return(serial_port_stub)
61
+
62
+ subject.connect
63
+ end
64
+ end
65
+
66
+ describe '#send' do
67
+
68
+ end
69
+
70
+ describe '#receive' do
71
+
72
+ end
73
+ end
@@ -0,0 +1,205 @@
1
+ require 'spec_helper'
2
+
3
+ describe NXTBrick do
4
+ before do
5
+ @interface = stub(
6
+ is_a?: true
7
+ )
8
+ end
9
+
10
+ subject do
11
+ NXTBrick.new(@interface)
12
+ end
13
+
14
+ describe 'accessors' do
15
+ it 'should have read/write accessors for @interface' do
16
+ should respond_to(:interface)
17
+ should respond_to(:interface=)
18
+ end
19
+
20
+ it 'should have read/write accessors for @options' do
21
+ should respond_to(:options)
22
+ should respond_to(:options=)
23
+ end
24
+
25
+ it 'should have a read accessor for @a' do
26
+ should respond_to(:a)
27
+ should_not respond_to(:a=)
28
+ end
29
+
30
+ it 'should have a read accessor for @b' do
31
+ should respond_to(:b)
32
+ should_not respond_to(:b=)
33
+ end
34
+
35
+ it 'should have a read accessor for @c' do
36
+ should respond_to(:c)
37
+ should_not respond_to(:c=)
38
+ end
39
+
40
+ it 'should have a read accessor for @one' do
41
+ should respond_to(:one)
42
+ should_not respond_to(:one=)
43
+ end
44
+
45
+ it 'should have a read accessor for @two' do
46
+ should respond_to(:two)
47
+ should_not respond_to(:two=)
48
+ end
49
+
50
+ it 'should have a read accessor for @three' do
51
+ should respond_to(:three)
52
+ should_not respond_to(:three=)
53
+ end
54
+
55
+ it 'should have a read accessor for @four' do
56
+ should respond_to(:four)
57
+ should_not respond_to(:four=)
58
+ end
59
+
60
+ it 'should have a read accessor for @port_identifiers' do
61
+ should respond_to(:port_identifiers)
62
+ should_not respond_to(:port_identifiers=)
63
+ end
64
+ end
65
+
66
+ describe '#initialize' do
67
+ it 'should raise an exception if an invalid type of interface is given' do
68
+ interface_stub = stub()
69
+ interface_stub.should_receive(:is_a?).with(NXT::Interface::Base).once.and_return(false)
70
+ expect do
71
+ NXTBrick.new(interface_stub)
72
+ end.to raise_exception(InvalidInterfaceError)
73
+ end
74
+
75
+ it 'should set the interface to the incomming argument' do
76
+ subject.interface.should equal(@interface)
77
+ end
78
+
79
+ it 'should set the options to the incomming argument' do
80
+ options_stub = stub()
81
+ nxt = NXTBrick.new(@interface, options_stub)
82
+ nxt.options.should equal(options_stub)
83
+ end
84
+
85
+ it 'should call yield if given a block, passing self' do
86
+ block_called = false
87
+
88
+ NXTBrick.new(@interface) do |nxt|
89
+ block_called = true
90
+ nxt.should be_an_instance_of(NXTBrick)
91
+ end
92
+
93
+ block_called.should be_true
94
+ end
95
+ end
96
+
97
+ describe '#add' do
98
+ it 'should raise an exception if an invalid type of port is given' do
99
+ expect do
100
+ subject.add('not a symbol', :symbol, Class)
101
+ end.to raise_exception(TypeError, 'Expected port to be a Symbol')
102
+ end
103
+
104
+ it 'should raise an exception if an invalid type of identifier is given' do
105
+ expect do
106
+ subject.add(:symbol, 'not a symbol', Class)
107
+ end.to raise_exception(TypeError, 'Expected identifier to be a Symbol')
108
+ end
109
+
110
+ it 'should raise an exception if an invalid type of klass is given' do
111
+ expect do
112
+ subject.add(:symbol, :symbol, 'not a class')
113
+ end.to raise_exception(TypeError, 'Expected klass to be a Class')
114
+ end
115
+
116
+ it 'should raise an exception if an invalid port number or letter is given' do
117
+ expect do
118
+ subject.add(:invalid_port, :symbol, Class)
119
+ end.to raise_exception(TypeError, 'Expected port to be one of: :a, :b, :c, :one, :two, :three, :four')
120
+ end
121
+
122
+ it 'should create a new instance of the passed klass and store it in the attribute for the given port' do
123
+ port = :a
124
+ class_stub = Class.new
125
+ class_return_stub = stub()
126
+
127
+ class_stub.should_receive(:new) do
128
+ class_return_stub
129
+ end.with(port).once()
130
+
131
+ subject.add(port, :hello, class_stub)
132
+
133
+ subject.send(port).should equal(class_return_stub)
134
+ end
135
+
136
+ it 'should raise an exception if the port given is already set' do
137
+ port = :a
138
+
139
+ class_stub = Class.new
140
+ class_stub.stub(:new)
141
+ subject.stub(:hello)
142
+ subject.instance_variable_set(:"@#{port}", 'some value already there')
143
+
144
+ expect do
145
+ subject.add(port, :hello, class_stub)
146
+ end.to raise_error(PortTakenError, "Port #{port} is already set, call remove first")
147
+ end
148
+
149
+ it 'should raise an exception if trying to use an identifier that is the name of a defined methodz' do
150
+ port = :a
151
+ identifier = :hello
152
+
153
+ class_stub = Class.new
154
+ class_stub.stub(:new)
155
+ subject.stub(identifier)
156
+
157
+ expect do
158
+ subject.add(port, :hello, class_stub)
159
+ end.to raise_error(InvalidIdentifierError, "Cannot use identifier #{identifier}, a method on NXTBrick is already using it.")
160
+ end
161
+
162
+ it 'should set up the port identifiers correctly' do
163
+ port = :a
164
+ identifier = :hello_world
165
+ class_stub = Class.new
166
+ class_stub.stub(:new)
167
+
168
+ subject.add(port, identifier, class_stub)
169
+
170
+ subject.port_identifiers[identifier].should equal(port)
171
+ end
172
+ end
173
+
174
+ describe '#remove' do
175
+ it 'should raise an exception if an invalid type of identifier is given' do
176
+ expect do
177
+ subject.remove('not a symbol')
178
+ end.to raise_exception(TypeError, 'Expected identifier to be a Symbol')
179
+ end
180
+
181
+ it 'should remove any matching identifiers' do
182
+ identifier = :hello_world
183
+ port_identifiers = {}
184
+ subject.instance_variable_set(:@port_identifiers, port_identifiers)
185
+
186
+ port_identifiers.should_receive(:delete).with(identifier).once()
187
+ subject.remove(identifier)
188
+ end
189
+
190
+ it 'should return a boolean indicating whether it removed anything' do
191
+ identifier = :hello_world
192
+ port_identifiers = {}
193
+ port_identifiers[identifier] = true
194
+ subject.instance_variable_set(:@port_identifiers, port_identifiers)
195
+
196
+ return_value = subject.remove(identifier)
197
+ return_value.should be_true
198
+
199
+ port_identifiers.should_not include(identifier)
200
+
201
+ return_value = subject.remove(identifier)
202
+ return_value.should be_false
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,4 @@
1
+ require 'matchers'
2
+ require 'nxt'
3
+
4
+ include NXT::Exceptions
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lego-nxt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Nathan Kleyn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: serialport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 3.2.13
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 3.2.13
41
+ - !ruby/object:Gem::Dependency
42
+ name: libusb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.13.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 2.13.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.12.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.12.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.6.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 0.8.6.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: redcarpet
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 2.3.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 2.3.0
111
+ description: Ruby LEGO Mindstorms NXT 2.0 control via Bluetooth and USB. See http://github.com/nathankleyn/lego-nxt
112
+ for more information.
113
+ email: nathan@nathankleyn.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files:
117
+ - README.md
118
+ files:
119
+ - README.md
120
+ - Rakefile
121
+ - lib/nxt.rb
122
+ - lib/nxt/connectors/output/motor.rb
123
+ - lib/nxt/connectors/input/color.rb
124
+ - lib/nxt/connectors/input/ultrasonic.rb
125
+ - lib/nxt/connectors/input/touch.rb
126
+ - lib/nxt/exceptions.rb
127
+ - lib/nxt/nxt_brick.rb
128
+ - lib/nxt/commands/program.rb
129
+ - lib/nxt/commands/sound.rb
130
+ - lib/nxt/commands/tone.rb
131
+ - lib/nxt/commands/output.rb
132
+ - lib/nxt/commands/base.rb
133
+ - lib/nxt/commands/input.rb
134
+ - lib/nxt/utils/accessors.rb
135
+ - lib/nxt/patches/string.rb
136
+ - lib/nxt/patches/module.rb
137
+ - lib/nxt/interfaces/usb.rb
138
+ - lib/nxt/interfaces/base.rb
139
+ - lib/nxt/interfaces/serial_port.rb
140
+ - spec/spec_helper.rb
141
+ - spec/matchers.rb
142
+ - spec/nxt/nxt_brick_spec.rb
143
+ - spec/nxt/interfaces/serial_port_spec.rb
144
+ homepage: http://github.com/nathankleyn/lego-nxt
145
+ licenses:
146
+ - MIT
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - '>='
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.0.2
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: Ruby LEGO Mindstorms NXT 2.0 control via Bluetooth and USB.
168
+ test_files: []
169
+ has_rdoc: