tooled 0.0.2

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/.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