tooled 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.irbrc ADDED
@@ -0,0 +1,9 @@
1
+ $:.unshift Dir.pwd
2
+
3
+ require 'rubygems'
4
+
5
+ require 'bundler'
6
+ Bundler.require
7
+
8
+ $:.unshift File.join(Dir.pwd, 'lib')
9
+ require 'tooled'
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tooled.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Darren Coxall
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Tooled
2
+
3
+ Small, tested, independant classes that can be used to help keep ruby code clean and simple by avoiding the over-use of `Hash` and making use of commonly ignored features such as implementing the arithmetic methods (`+`, `-`, `/`, `*`).
4
+
5
+ I started this gem as I enjoy writting underlying classes and implementing many of the libraries I have enjoyed from other languages and tools.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'tooled'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install tooled
20
+
21
+ ## Usage
22
+
23
+ Usage is as simple as installing the gem and then using the classes in your own code.
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,120 @@
1
+ ##
2
+ # Publisher provides a barebones implementation to a pub-sub system.
3
+ #
4
+ # By including the Publisher into any class you can then regsiter events
5
+ # and wrap blocks in `with_event` which will then broadcast the event to
6
+ # any registered subscribers.
7
+
8
+ module Tooled
9
+ module Publisher
10
+
11
+ ##
12
+ # Used to distinguish exceptions relating to the lack of a particular
13
+ # event.
14
+
15
+ class EventMissingException < Exception ; end
16
+
17
+ def self.included(base)
18
+ base.extend(ClassMethods)
19
+ end
20
+
21
+ ##
22
+ # Returns a complete hash of subscribers including those registered at
23
+ # class level.
24
+
25
+ def subscribers
26
+ (@subscribers ||= self.class.subscribers).dup
27
+ end
28
+
29
+ ##
30
+ # Registers a subscriber to an instance.
31
+ #
32
+ # This will raise an EventMissing exception if any of the provided event
33
+ # names aren't registered.
34
+
35
+ def register_subscriber(subscriber, *event_names)
36
+ @subscribers ||= self.class.subscribers
37
+ events = event_names.collect(&:to_sym).uniq
38
+ invalid_events = events - self.class.publishable_events_list
39
+ raise EventMissingException.new("`#{invalid_events.collect(&:to_s).join('`, `')}` are not registered events") unless invalid_events.empty?
40
+ @subscribers[subscriber] = events
41
+ end
42
+
43
+ ##
44
+ # Executes a provided block but calls all the events on relevant subscribers
45
+ # as well.
46
+ #
47
+ # `before_event_name` -> `around_event_name` -> `around_event_name` -> `after_event_name`
48
+
49
+ def with_event(event_name, &block)
50
+ raise EventMissingException.new("`#{event_name.to_s}` is not a registered event") unless self.class.publishable_events_list.include?(event_name.to_sym)
51
+ subs = _subscribers_for(event_name)
52
+ _broadcast(subs, ["before_#{event_name.to_s}", "around_#{event_name.to_s}"])
53
+ result = block.call if block_given?
54
+ _broadcast(subs, ["around_#{event_name.to_s}", "after_#{event_name.to_s}"])
55
+ result
56
+ end
57
+
58
+ private
59
+
60
+ def _subscribers_for(event_name)
61
+ subscribers.select { |subscriber, events| events.include?(event_name.to_sym) }.keys
62
+ end
63
+
64
+ def _broadcast(subs, method)
65
+ subs.each do |subscriber|
66
+ if method.is_a?(Array)
67
+ method.each { |m| subscriber.send(m) if subscriber.respond_to?(m) }
68
+ else
69
+ subscriber.send(method.to_s) if subscriber.respond_to?(method.to_s)
70
+ end
71
+ end
72
+ end
73
+
74
+ module ClassMethods
75
+
76
+ ##
77
+ # Sets the list of publishable events. If an event is not registered
78
+ # as a publishable event then it will not fire.
79
+
80
+ def publishable_events(*event_names)
81
+ @publishable_events = event_names.collect(&:to_sym).uniq
82
+ end
83
+
84
+ ##
85
+ # Registers an individual event without removing previously added events.
86
+
87
+ def register_event(event_name)
88
+ event_name = event_name.to_sym
89
+ @publishable_events ||= Array.new
90
+ @publishable_events << event_name unless @publishable_events.include?(event_name)
91
+ end
92
+
93
+ ##
94
+ # Provides an array with all publishable event names.
95
+
96
+ def publishable_events_list
97
+ (@publishable_events ||= Array.new).dup
98
+ end
99
+
100
+ ##
101
+ # Provides a hash with all subscribers and their associated events.
102
+
103
+ def subscribers
104
+ (@subscribers ||= Hash.new).dup
105
+ end
106
+
107
+ ##
108
+ # Registers an individual subscriber to any number of events from a class
109
+ # level.
110
+
111
+ def register_subscriber(subscriber, *event_names)
112
+ @subscribers ||= Hash.new
113
+ events = event_names.collect(&:to_sym).uniq
114
+ invalid_events = events - publishable_events_list
115
+ raise EventMissingException.new("`#{invalid_events.collect(&:to_s).join('`, `')}` are not registered events") unless invalid_events.empty?
116
+ @subscribers[subscriber] = events
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,46 @@
1
+ ##
2
+ # Queue provides a first on, first off array
3
+
4
+ module Tooled
5
+ class Queue
6
+ include Enumerable
7
+
8
+ def initialize
9
+ @queue_values = []
10
+ end
11
+
12
+ def count
13
+ @queue_values.count
14
+ end
15
+ alias_method :length, :count
16
+
17
+ def <<(value)
18
+ @queue_values << value
19
+ end
20
+ alias_method :push, :<<
21
+
22
+ def peek
23
+ @queue_values.first
24
+ end
25
+
26
+ def pop
27
+ @queue_values.delete_at(0)
28
+ end
29
+
30
+ def [](index)
31
+ @queue_values[index.to_i]
32
+ end
33
+
34
+ def to_a
35
+ @queue_values.reverse.dup
36
+ end
37
+
38
+ def empty?
39
+ @queue_values.empty?
40
+ end
41
+
42
+ def each(&block)
43
+ yield block.call(pop) until empty?
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ ##
2
+ # Stack provides a first on, last off array
3
+
4
+ module Tooled
5
+ class Stack
6
+ include Enumerable
7
+
8
+ def initialize
9
+ @stack_values = []
10
+ end
11
+
12
+ def count
13
+ @stack_values.count
14
+ end
15
+ alias_method :length, :count
16
+
17
+ def <<(value)
18
+ @stack_values << value
19
+ end
20
+ alias_method :push, :<<
21
+
22
+ def peek
23
+ @stack_values.last
24
+ end
25
+
26
+ def pop
27
+ @stack_values.delete_at(@stack_values.count - 1)
28
+ end
29
+
30
+ def [](index)
31
+ @stack_values[@stack_values.count - (index.to_i + 1)]
32
+ end
33
+
34
+ def to_a
35
+ @stack_values.dup
36
+ end
37
+
38
+ def empty?
39
+ @stack_values.empty?
40
+ end
41
+
42
+ def each(&block)
43
+ yield block.call(pop) until empty?
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ ##
2
+ # Vector2D is a basic data structure developed to store 2 dimensional
3
+ # co-ordinates and allow them to be manipulated using addition, subtraction,
4
+ # mulitplication and division.
5
+
6
+ module Tooled
7
+ class Vector2D
8
+ def initialize(x, y)
9
+ @axis_values = [nil, nil]
10
+ self.x, self.y = x.to_f, y.to_f
11
+ end
12
+
13
+ %w( x y ).each_with_index do |axis, i|
14
+ define_method(axis) { @axis_values[i] }
15
+ define_method("#{axis}=") { |val| @axis_values[i] = val.to_f }
16
+ end
17
+
18
+ %w( * / + - ).each do |sym|
19
+ define_method(sym) { |val| _perform_message(val, sym) }
20
+ end
21
+
22
+ private
23
+
24
+ def _perform_message(val, msg)
25
+ if val.is_a?(Vector2D)
26
+ Vector2D.new(x.send(msg, val.x), y.send(msg, val.y))
27
+ else
28
+ Vector2D.new(x.send(msg, val.to_f), y.send(msg, val.to_f))
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ ##
2
+ # Vector3D is a basic data structure developed to store 3 dimensional
3
+ # co-ordinates and allow them to be manipulated using addition, subtraction,
4
+ # mulitplication and division.
5
+
6
+ module Tooled
7
+ class Vector3D
8
+ def initialize(x, y, z)
9
+ @axis_values = [nil, nil, nil]
10
+ self.x, self.y, self.z = x.to_f, y.to_f, z.to_f
11
+ end
12
+
13
+ %w( x y z ).each_with_index do |axis, i|
14
+ define_method(axis) { @axis_values[i] }
15
+ define_method("#{axis}=") { |val| @axis_values[i] = val.to_f }
16
+ end
17
+
18
+ %w( * / + - ).each do |sym|
19
+ define_method(sym) { |val| _perform_message(val, sym) }
20
+ end
21
+
22
+ private
23
+
24
+ def _perform_message(val, msg)
25
+ if val.is_a?(Vector3D)
26
+ Vector3D.new(x.send(msg, val.x), y.send(msg, val.y), z.send(msg, val.z))
27
+ else
28
+ Vector3D.new(x.send(msg, val.to_f), y.send(msg, val.to_f), z.send(msg, val.to_f))
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Tooled
2
+ VERSION = "0.0.2"
3
+ end
data/lib/tooled.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "tooled/version"
2
+ require "tooled/vector2d"
3
+ require "tooled/vector3d"
4
+ require "tooled/stack"
5
+ require "tooled/queue"
6
+ require "tooled/publisher"
7
+
8
+ module Tooled
9
+ # Your code goes here...
10
+ end
@@ -0,0 +1,105 @@
1
+ require "tooled/publisher"
2
+
3
+ describe Tooled::Publisher do
4
+ let(:klass) do
5
+ Class.new do
6
+ include Tooled::Publisher
7
+ publishable_events :foo, :bar
8
+ end
9
+ end
10
+ subject { klass }
11
+
12
+ describe "allows a class to register events" do
13
+ its(:publishable_events_list) { should include(:foo, :bar) }
14
+
15
+ describe "remains unique" do
16
+ subject { klass.publishable_events_list }
17
+ specify { expect { klass.register_event(:blegga) }.to change { klass.publishable_events_list.count }.by(1) }
18
+ specify { expect { klass.register_event(:foo) }.to_not change { klass.publishable_events_list.count } }
19
+ end
20
+ end
21
+
22
+ describe "registering subscribers" do
23
+ let(:subscriber) { double(:subscriber) }
24
+
25
+ context "at class level" do
26
+ specify { expect { subject.register_subscriber(subscriber, :foo, :bar) }.to change { subject.subscribers.count }.by(1) }
27
+
28
+ context "when already subscribed" do
29
+ before { subject.register_subscriber(subscriber, :foo) }
30
+ specify { expect { subject.register_subscriber(subscriber, :foo) }.to_not change { subject.subscribers.count } }
31
+
32
+ it "lists the correct event for the subscriber" do
33
+ subject.subscribers[subscriber].include?(:foo)
34
+ end
35
+ end
36
+
37
+ context "with invalid event" do
38
+ specify { expect { subject.register_subscriber(subscriber, :invalid) }.to raise_error(Tooled::Publisher::EventMissingException) }
39
+ end
40
+ end
41
+
42
+ context "at object level" do
43
+ let(:object) { klass.new }
44
+ subject { object }
45
+
46
+ specify { expect { subject.register_subscriber(subscriber, :foo, :bar) }.to change { subject.subscribers.count }.by(1) }
47
+
48
+ context "when already subscribed" do
49
+ before { subject.register_subscriber(subscriber, :foo) }
50
+ specify { expect { subject.register_subscriber(subscriber, :foo) }.to_not change { subject.subscribers.count } }
51
+
52
+ it "lists the correct event for the subscriber" do
53
+ subject.subscribers[subscriber].include?(:foo)
54
+ end
55
+ end
56
+
57
+ context "with invalid event" do
58
+ specify { expect { subject.register_subscriber(subscriber, :invalid) }.to raise_error(Tooled::Publisher::EventMissingException) }
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "using events" do
64
+ let(:subscriber) { double(:subscriber, before_foo: true, after_foo: true, around_foo: true) }
65
+ let(:klass) do
66
+ Class.new do
67
+ include Tooled::Publisher
68
+ publishable_events :foo, :bar
69
+
70
+ def using_foo
71
+ with_event(:foo) { 1 }
72
+ end
73
+
74
+ def using_bar
75
+ with_event(:bar) { 2 }
76
+ end
77
+
78
+ def using_blegga
79
+ with_event(:blegga) { 3 }
80
+ end
81
+ end
82
+ end
83
+
84
+ subject { klass.new }
85
+
86
+ context "having a subscriber" do
87
+ before do
88
+ subscriber.should_receive(:before_foo)
89
+ subscriber.should_receive(:after_foo)
90
+ subscriber.should_receive(:around_foo).twice
91
+ subject.register_subscriber(subscriber, :foo)
92
+ end
93
+
94
+ its(:using_foo) { should eql(1) }
95
+ end
96
+
97
+ context "having no subscriber" do
98
+ its(:using_bar) { should eql(2) }
99
+ end
100
+
101
+ context "having no event" do
102
+ specify { expect { subject.using_blegga }.to raise_error(Tooled::Publisher::EventMissingException) }
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,57 @@
1
+ require "tooled/queue"
2
+
3
+ describe Tooled::Queue do
4
+ let(:object) { Tooled::Queue.new }
5
+ subject { object }
6
+
7
+ describe "adding elements" do
8
+ specify { expect { subject << 1 }.to change { subject.count }.by(1) }
9
+ specify { expect { subject.push(1) }.to change { subject.count }.by(1) }
10
+ end
11
+
12
+ describe "with no elements" do
13
+ it { should be_empty }
14
+ end
15
+
16
+ describe "converting to array" do
17
+ before { object << 1; object << 2; object << 3 }
18
+ its(:to_a) { should eql([3, 2, 1]) }
19
+ end
20
+
21
+ describe "retrieving elements" do
22
+ before { object << 'bottom' ; object << 'top' }
23
+
24
+ context "using peek" do
25
+ its(:peek) { should eql('bottom') }
26
+ specify { expect { subject.peek }.to_not change { subject.count } }
27
+ end
28
+
29
+ context "using pop" do
30
+ its(:pop) { should eql('bottom') }
31
+ specify { expect { subject.pop }.to change { subject.count }.by(-1) }
32
+ end
33
+
34
+ context "using an index" do
35
+ context "of 0" do
36
+ subject { object[0] }
37
+ it { should eql('bottom') }
38
+ end
39
+
40
+ context "of 1" do
41
+ subject { object[1] }
42
+ it { should eql('top') }
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "is iterable" do
48
+ before { object << 1; object << 2; object << 3 }
49
+ specify do
50
+ expect do
51
+ values = []
52
+ object.each { |v| values << v }
53
+ values.should include(3, 2, 1)
54
+ end.to change { object.count }.by(-3)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ require "tooled/stack"
2
+
3
+ describe Tooled::Stack do
4
+ let(:object) { Tooled::Stack.new }
5
+ subject { object }
6
+
7
+ describe "adding elements" do
8
+ specify { expect { subject << 1 }.to change { subject.count }.by(1) }
9
+ specify { expect { subject.push(1) }.to change { subject.count }.by(1) }
10
+ end
11
+
12
+ describe "with no elements" do
13
+ it { should be_empty }
14
+ end
15
+
16
+ describe "converting to array" do
17
+ before { object << 1; object << 2; object << 3 }
18
+ its(:to_a) { should eql([1, 2, 3]) }
19
+ end
20
+
21
+ describe "retrieving elements" do
22
+ before { object << 'bottom' ; object << 'top' }
23
+
24
+ context "using peek" do
25
+ its(:peek) { should eql('top') }
26
+ specify { expect { subject.peek }.to_not change { subject.count } }
27
+ end
28
+
29
+ context "using pop" do
30
+ its(:pop) { should eql('top') }
31
+ specify { expect { subject.pop }.to change { subject.count }.by(-1) }
32
+ end
33
+
34
+ context "using an index" do
35
+ context "of 0" do
36
+ subject { object[0] }
37
+ it { should eql('top') }
38
+ end
39
+
40
+ context "of 1" do
41
+ subject { object[1] }
42
+ it { should eql('bottom') }
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "is iterable" do
48
+ before { object << 1; object << 2; object << 3 }
49
+ specify do
50
+ expect do
51
+ values = []
52
+ object.each { |v| values << v }
53
+ values.should include(1, 2, 3)
54
+ end.to change { object.count }.by(-3)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,84 @@
1
+ require "tooled/vector2d"
2
+
3
+ describe Tooled::Vector2D do
4
+ let(:object) { Tooled::Vector2D.new(1, 2) }
5
+ subject { object }
6
+
7
+ context "when initialized with values" do
8
+ its(:x) { should eql(1.to_f) }
9
+ its(:y) { should eql(2.to_f) }
10
+ end
11
+
12
+ describe "when multiplied" do
13
+ context "with an integer" do
14
+ subject { object * 2 }
15
+ its(:x) { should eql(2.to_f) }
16
+ its(:y) { should eql(4.to_f) }
17
+ end
18
+
19
+ context "with a float" do
20
+ subject { object * 1.5 }
21
+ its(:x) { should eql(1.5.to_f) }
22
+ its(:y) { should eql(3.to_f) }
23
+ end
24
+
25
+ context "with a vector2d" do
26
+ context "using integer values" do
27
+ subject { object * Tooled::Vector2D.new(2, 5) }
28
+ its(:x) { should eql(2.to_f) }
29
+ its(:y) { should eql(10.to_f) }
30
+ end
31
+
32
+ context "using float values" do
33
+ subject { object * Tooled::Vector2D.new(1.5, 2.5) }
34
+ its(:x) { should eql(1.5.to_f) }
35
+ its(:y) { should eql(5.to_f) }
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "when divided" do
41
+ let(:object) { Tooled::Vector2D.new(5, 10) }
42
+ context "with an integer" do
43
+ subject { object / 5 }
44
+ its(:x) { should eql(1.to_f) }
45
+ its(:y) { should eql(2.to_f) }
46
+ end
47
+
48
+ context "with a float" do
49
+ subject { object / 2.5 }
50
+ its(:x) { should eql(2.to_f) }
51
+ its(:y) { should eql(4.to_f) }
52
+ end
53
+
54
+ context "with a vector2d" do
55
+ context "using integer values" do
56
+ subject { object / Tooled::Vector2D.new(5, 10) }
57
+ its(:x) { should eql(1.to_f) }
58
+ its(:y) { should eql(1.to_f) }
59
+ end
60
+
61
+ context "using float values" do
62
+ subject { object / Tooled::Vector2D.new(2.5, 1.25) }
63
+ its(:x) { should eql(2.to_f) }
64
+ its(:y) { should eql(8.to_f) }
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "when added" do
70
+ context "with a vector2d" do
71
+ subject { object + Tooled::Vector2D.new(1, 5) }
72
+ its(:x) { should eql(2.to_f) }
73
+ its(:y) { should eql(7.to_f) }
74
+ end
75
+ end
76
+
77
+ describe "when subtracted" do
78
+ context "with a vector2d" do
79
+ subject { object - Tooled::Vector2D.new(1, 5) }
80
+ its(:x) { should eql(0.to_f) }
81
+ its(:y) { should eql(-3.to_f) }
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,95 @@
1
+ require "tooled/vector3d"
2
+
3
+ describe Tooled::Vector3D do
4
+ let(:object) { Tooled::Vector3D.new(1, 2, 3) }
5
+ subject { object }
6
+
7
+ context "when initialized with values" do
8
+ its(:x) { should eql(1.to_f) }
9
+ its(:y) { should eql(2.to_f) }
10
+ its(:z) { should eql(3.to_f) }
11
+ end
12
+
13
+ describe "when multiplied" do
14
+ context "with an integer" do
15
+ subject { object * 2 }
16
+ its(:x) { should eql(2.to_f) }
17
+ its(:y) { should eql(4.to_f) }
18
+ its(:z) { should eql(6.to_f) }
19
+ end
20
+
21
+ context "with a float" do
22
+ subject { object * 1.5 }
23
+ its(:x) { should eql(1.5.to_f) }
24
+ its(:y) { should eql(3.to_f) }
25
+ its(:z) { should eql(4.5.to_f) }
26
+ end
27
+
28
+ context "with a vector3d" do
29
+ context "using integer values" do
30
+ subject { object * Tooled::Vector3D.new(2, 5, 10) }
31
+ its(:x) { should eql(2.to_f) }
32
+ its(:y) { should eql(10.to_f) }
33
+ its(:z) { should eql(30.to_f) }
34
+ end
35
+
36
+ context "using float values" do
37
+ subject { object * Tooled::Vector3D.new(1.5, 2.5, 3.5) }
38
+ its(:x) { should eql(1.5.to_f) }
39
+ its(:y) { should eql(5.to_f) }
40
+ its(:z) { should eql(10.5.to_f) }
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "when divided" do
46
+ let(:object) { Tooled::Vector3D.new(5, 10, 15) }
47
+ context "with an integer" do
48
+ subject { object / 5 }
49
+ its(:x) { should eql(1.to_f) }
50
+ its(:y) { should eql(2.to_f) }
51
+ its(:z) { should eql(3.to_f) }
52
+ end
53
+
54
+ context "with a float" do
55
+ subject { object / 2.5 }
56
+ its(:x) { should eql(2.to_f) }
57
+ its(:y) { should eql(4.to_f) }
58
+ its(:z) { should eql(6.to_f) }
59
+ end
60
+
61
+ context "with a vector3d" do
62
+ context "using integer values" do
63
+ subject { object / Tooled::Vector3D.new(5, 10, 15) }
64
+ its(:x) { should eql(1.to_f) }
65
+ its(:y) { should eql(1.to_f) }
66
+ its(:z) { should eql(1.to_f) }
67
+ end
68
+
69
+ context "using float values" do
70
+ subject { object / Tooled::Vector3D.new(2.5, 1.25, 2.5) }
71
+ its(:x) { should eql(2.to_f) }
72
+ its(:y) { should eql(8.to_f) }
73
+ its(:z) { should eql(6.to_f) }
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "when added" do
79
+ context "with a vector3d" do
80
+ subject { object + Tooled::Vector3D.new(1, 5, 10) }
81
+ its(:x) { should eql(2.to_f) }
82
+ its(:y) { should eql(7.to_f) }
83
+ its(:z) { should eql(13.to_f) }
84
+ end
85
+ end
86
+
87
+ describe "when subtracted" do
88
+ context "with a vector3d" do
89
+ subject { object - Tooled::Vector3D.new(1, 5, 10) }
90
+ its(:x) { should eql(0.to_f) }
91
+ its(:y) { should eql(-3.to_f) }
92
+ its(:z) { should eql(-7.to_f) }
93
+ end
94
+ end
95
+ end
data/tooled.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tooled/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tooled"
8
+ spec.version = Tooled::VERSION
9
+ spec.authors = ["Darren Coxall"]
10
+ spec.email = ["darren@darrencoxall.com"]
11
+ spec.description = %q{A simple collection of classes to help avoid over-using Hash}
12
+ spec.summary = %q{A simple collection of classes to help avoid over-using Hash}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tooled
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Darren Coxall
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: A simple collection of classes to help avoid over-using Hash
63
+ email:
64
+ - darren@darrencoxall.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .irbrc
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - lib/tooled.rb
76
+ - lib/tooled/publisher.rb
77
+ - lib/tooled/queue.rb
78
+ - lib/tooled/stack.rb
79
+ - lib/tooled/vector2d.rb
80
+ - lib/tooled/vector3d.rb
81
+ - lib/tooled/version.rb
82
+ - spec/publisher_spec.rb
83
+ - spec/queue_spec.rb
84
+ - spec/stack_spec.rb
85
+ - spec/vector2d_spec.rb
86
+ - spec/vector3d_spec.rb
87
+ - tooled.gemspec
88
+ homepage: ''
89
+ licenses:
90
+ - MIT
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.23
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: A simple collection of classes to help avoid over-using Hash
113
+ test_files:
114
+ - spec/publisher_spec.rb
115
+ - spec/queue_spec.rb
116
+ - spec/stack_spec.rb
117
+ - spec/vector2d_spec.rb
118
+ - spec/vector3d_spec.rb