rats 0.1.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.
@@ -0,0 +1,43 @@
1
+ module Rats
2
+ class Meridian < Data
3
+
4
+ VALID_MERIDIANS = (4..6)
5
+
6
+ def self.padding_width; 1; end
7
+ def self.padding_value; " "; end
8
+
9
+ def self.transform(value)
10
+ return unless value
11
+ value = value.to_s.upcase.reverse.chomp('W').reverse
12
+ value.to_i > 0 ? value.to_i : nil
13
+ end
14
+
15
+ def valid?
16
+ VALID_MERIDIANS.include?(self.value.to_i)
17
+ end
18
+
19
+ def to_s; "W" + self.value.to_s; end
20
+
21
+ private
22
+
23
+ # as a meridian, we can only safely traverse within alberta
24
+
25
+ def traverse(direction)
26
+ raise ArgumentError unless self.v
27
+ new_value = case direction.downcase.to_sym
28
+ when :up
29
+ raise IllegalTraverse
30
+ when :right
31
+ self.v.to_i > VALID_MERIDIANS.min ? self.v.to_i - 1 : nil
32
+ when :down
33
+ raise IllegalTraverse
34
+ when :left
35
+ self.v.to_i < VALID_MERIDIANS.max ? self.v.to_i + 1 : nil
36
+ end
37
+ raise Rats::OutOfAlberta if new_value.nil?
38
+ Rats::Meridian.new(new_value)
39
+ end
40
+ alias traverse! traverse
41
+
42
+ end
43
+ end
@@ -0,0 +1,67 @@
1
+ module Rats
2
+ class Quarter < Data
3
+
4
+ VALID_QUARTERS = [:ne, :nw, :se, :sw]
5
+
6
+ # order: up, right, down, left
7
+ UNBOUNDED_QUARTER_MATRIX = {
8
+ :se => [:ne, :sw, :ne, :sw],
9
+ :sw => [:nw, :se, :nw, :se],
10
+ :nw => [:sw, :ne, :sw, :ne],
11
+ :ne => [:se, :nw, :se, :nw]
12
+ }
13
+ BOUNDED_QUARTER_MATRIX = {
14
+ :se => [:ne, nil, nil, :sw],
15
+ :sw => [:nw, :se, nil, nil],
16
+ :nw => [nil, :ne, :sw, nil],
17
+ :ne => [nil, nil, :se, :nw]
18
+ }
19
+
20
+ def self.padding_width; 2; end
21
+ def self.padding_value; " "; end
22
+
23
+ def self.transform(value)
24
+ value.to_s.upcase if value
25
+ end
26
+
27
+ def valid?
28
+ VALID_QUARTERS.include?(self.value.to_s.downcase.to_sym)
29
+ end
30
+
31
+ private
32
+
33
+ # as a quarter, we can only safely traverse within a section
34
+
35
+ def traverse(direction)
36
+ raise ArgumentError unless self.v
37
+ new_value = case direction.downcase.to_sym
38
+ when :up
39
+ BOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][0]
40
+ when :right
41
+ BOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][1]
42
+ when :down
43
+ BOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][2]
44
+ when :left
45
+ BOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][3]
46
+ end
47
+ raise Rats::OutOfSection if new_value.nil?
48
+ Rats::Quarter.new(new_value)
49
+ end
50
+
51
+ def traverse!(direction)
52
+ raise ArgumentError unless self.v
53
+ new_value = case direction.downcase.to_sym
54
+ when :up
55
+ UNBOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][0]
56
+ when :right
57
+ UNBOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][1]
58
+ when :down
59
+ UNBOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][2]
60
+ when :left
61
+ UNBOUNDED_QUARTER_MATRIX[self.v.to_s.downcase.to_sym][3]
62
+ end
63
+ Rats::Quarter.new(new_value)
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,59 @@
1
+ module Rats
2
+ class Range < Data
3
+
4
+ VALID_RANGES = (1..30)
5
+
6
+ def self.padding_width; 2; end
7
+ def self.padding_value; "0"; end
8
+
9
+ def self.transform(value)
10
+ return unless value
11
+ value.to_i > 0 ? value.to_i : nil
12
+ end
13
+
14
+ # NOTE: this does not take into consideration that some ranges do not
15
+ # exist for some meridians and township (y-axis) values ... but we
16
+ # would need to know those values, and that is outside the scope
17
+ # of the Range class. The Base class will handle these cases.
18
+ #
19
+ def valid?
20
+ VALID_RANGES.include?(self.value.to_i)
21
+ end
22
+
23
+ private
24
+
25
+ # as a range, we can only safely traverse within a meridian
26
+
27
+ def traverse(direction)
28
+ raise ArgumentError unless self.v
29
+ new_value = case direction.downcase.to_sym
30
+ when :up
31
+ raise IllegalTraverse
32
+ when :right
33
+ self.v.to_i > VALID_RANGES.min ? self.v.to_i - 1 : nil
34
+ when :down
35
+ raise IllegalTraverse
36
+ when :left
37
+ self.v.to_i < VALID_RANGES.max ? self.v.to_i + 1 : nil
38
+ end
39
+ raise Rats::OutOfMeridian if new_value.nil?
40
+ Rats::Range.new(new_value)
41
+ end
42
+
43
+ def traverse!(direction)
44
+ raise ArgumentError unless self.v
45
+ new_value = case direction.downcase.to_sym
46
+ when :up
47
+ raise IllegalTraverse
48
+ when :right
49
+ self.v.to_i > VALID_RANGES.min ? self.v.to_i - 1 : VALID_RANGES.max
50
+ when :down
51
+ raise IllegalTraverse
52
+ when :left
53
+ self.v.to_i < VALID_RANGES.max ? self.v.to_i + 1 : VALID_RANGES.min
54
+ end
55
+ Rats::Range.new(new_value)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,134 @@
1
+ module Rats
2
+ class Section < Data
3
+
4
+ VALID_SECTIONS = (1..36)
5
+
6
+ UNBOUNDED_SECTION_MATRIX = {
7
+ 1 => [12, 6, nil, 2],
8
+ 2 => [11, 1, nil, 3],
9
+ 3 => [10, 2, nil, 4],
10
+ 4 => [9, 3, nil, 5],
11
+ 5 => [8, 4, nil, 6],
12
+ 6 => [7, 5, nil, 1],
13
+ 7 => [18, 8, 6, 12],
14
+ 8 => [17, 9, 5, 7],
15
+ 9 => [16, 10, 4, 8],
16
+ 10 => [15, 11, 3, 9],
17
+ 11 => [14, 12, 2, 10],
18
+ 12 => [13, 7, 1, 11],
19
+ 13 => [24, 18, 12, 14],
20
+ 14 => [23, 13, 11, 15],
21
+ 15 => [22, 14, 10, 16],
22
+ 16 => [21, 15, 9, 17],
23
+ 17 => [20, 16, 8, 18],
24
+ 18 => [19, 17, 7, 13],
25
+ 19 => [30, 20, 18, 24],
26
+ 20 => [29, 21, 17, 19],
27
+ 21 => [28, 22, 16, 20],
28
+ 22 => [27, 23, 15, 21],
29
+ 23 => [26, 24, 14, 22],
30
+ 24 => [25, 19, 13, 23],
31
+ 25 => [36, 30, 24, 26],
32
+ 26 => [35, 25, 23, 27],
33
+ 27 => [34, 26, 22, 28],
34
+ 28 => [33, 27, 21, 29],
35
+ 29 => [32, 28, 20, 30],
36
+ 30 => [31, 29, 19, 25],
37
+ 31 => [nil, 32, 30, 36],
38
+ 32 => [nil, 33, 29, 31],
39
+ 33 => [nil, 34, 28, 32],
40
+ 34 => [nil, 35, 27, 33],
41
+ 35 => [nil, 36, 26, 34],
42
+ 36 => [nil, 31, 25, 35],
43
+ }
44
+
45
+ BOUNDED_SECTION_MATRIX = {
46
+ 1 => [12, nil, nil, 2],
47
+ 2 => [11, 1, nil, 3],
48
+ 3 => [10, 2, nil, 4],
49
+ 4 => [9, 3, nil, 5],
50
+ 5 => [8, 4, nil, 6],
51
+ 6 => [7, 5, nil, nil],
52
+ 7 => [18, 8, 6, nil],
53
+ 8 => [17, 9, 5, 7],
54
+ 9 => [16, 10, 4, 8],
55
+ 10 => [15, 11, 3, 9],
56
+ 11 => [14, 12, 2, 10],
57
+ 12 => [13, nil, 1, 11],
58
+ 13 => [24, nil, 12, 14],
59
+ 14 => [23, 13, 11, 15],
60
+ 15 => [22, 14, 10, 16],
61
+ 16 => [21, 15, 9, 17],
62
+ 17 => [20, 16, 8, 18],
63
+ 18 => [19, 17, 7, nil],
64
+ 19 => [30, 20, 18, nil],
65
+ 20 => [29, 21, 17, 19],
66
+ 21 => [28, 22, 16, 20],
67
+ 22 => [27, 23, 15, 21],
68
+ 23 => [26, 24, 14, 22],
69
+ 24 => [25, nil, 13, 23],
70
+ 25 => [36, nil, 24, 26],
71
+ 26 => [35, 25, 23, 27],
72
+ 27 => [34, 26, 22, 28],
73
+ 28 => [33, 27, 21, 29],
74
+ 29 => [32, 28, 20, 30],
75
+ 30 => [31, 29, 19, nil],
76
+ 31 => [nil, 32, 30, nil],
77
+ 32 => [nil, 33, 29, 31],
78
+ 33 => [nil, 34, 28, 32],
79
+ 34 => [nil, 35, 27, 33],
80
+ 35 => [nil, 36, 26, 34],
81
+ 36 => [nil, nil, 25, 35],
82
+ }
83
+
84
+ def self.padding_width; 2; end
85
+ def self.padding_value; "0"; end
86
+
87
+ def self.transform(value)
88
+ return unless value
89
+ value.to_i > 0 ? value.to_i : nil
90
+ end
91
+
92
+
93
+ def valid?
94
+ VALID_SECTIONS.include?(self.value.to_i)
95
+ end
96
+
97
+ private
98
+
99
+ # as a section, we can only safely traverse within a township
100
+
101
+ def traverse(direction)
102
+ raise ArgumentError unless self.v
103
+ new_value = case direction.downcase.to_sym
104
+ when :up
105
+ BOUNDED_SECTION_MATRIX[self.v.to_i][0]
106
+ when :right
107
+ BOUNDED_SECTION_MATRIX[self.v.to_i][1]
108
+ when :down
109
+ BOUNDED_SECTION_MATRIX[self.v.to_i][2]
110
+ when :left
111
+ BOUNDED_SECTION_MATRIX[self.v.to_i][3]
112
+ end
113
+ raise Rats::OutOfTownship if new_value.nil?
114
+ Rats::Section.new(new_value)
115
+ end
116
+
117
+ def traverse!(direction)
118
+ raise ArgumentError unless self.v
119
+ new_value = case direction.downcase.to_sym
120
+ when :up
121
+ UNBOUNDED_SECTION_MATRIX[self.v.to_i][0]
122
+ when :right
123
+ UNBOUNDED_SECTION_MATRIX[self.v.to_i][1]
124
+ when :down
125
+ UNBOUNDED_SECTION_MATRIX[self.v.to_i][2]
126
+ when :left
127
+ UNBOUNDED_SECTION_MATRIX[self.v.to_i][3]
128
+ end
129
+ raise Rats::IllegalTraverse if new_value.nil?
130
+ Rats::Section.new(new_value)
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,27 @@
1
+ module Rats
2
+ class Township < Data
3
+
4
+ VALID_TOWNSHIPS = (1..126)
5
+
6
+ def self.padding_width; 3; end
7
+ def self.padding_value; "0"; end
8
+
9
+ def self.transform(value)
10
+ return unless value
11
+ value.to_i > 0 ? value.to_i : nil
12
+ end
13
+
14
+ # NOTE: this does not take into consideration that some townships do not
15
+ # exist for some meridians and ranges (x-axis) values ... but we
16
+ # would need to know those values, and that is outside the scope
17
+ # of the Township class. The Base class will handle these cases.
18
+ #
19
+ def valid?
20
+ VALID_TOWNSHIPS.include?(self.value.to_i)
21
+ end
22
+
23
+ def traverse(direction); raise IllegalTraverse; end
24
+ alias taverse! traverse
25
+
26
+ end
27
+ end
data/lib/rats/data.rb ADDED
@@ -0,0 +1,10 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ # data
4
+ #
5
+ require 'data/base'
6
+ require 'data/quarter'
7
+ require 'data/section'
8
+ require 'data/township'
9
+ require 'data/range'
10
+ require 'data/meridian'
data/lib/rats.rb ADDED
@@ -0,0 +1,23 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'rats/base'
4
+ require 'rats/data'
5
+ require 'rats/boundaries'
6
+
7
+ module Rats
8
+
9
+ def self.new(*args)
10
+ Rats::Base.new(args)
11
+ end
12
+
13
+ # custom errors
14
+ #
15
+ class OutOfBounds < StandardError; end
16
+ class OutOfSection < OutOfBounds; end
17
+ class OutOfTownship < OutOfBounds; end
18
+ class OutOfMeridian < OutOfBounds; end
19
+ class OutOfAlberta < OutOfBounds; end
20
+
21
+ class IllegalTraverse < StandardError; end
22
+
23
+ end
data/rats.gemspec ADDED
@@ -0,0 +1,73 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rats}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Mark G"]
12
+ s.date = %q{2010-03-31}
13
+ s.description = %q{A ruby class to help with using the Alberta Township System}
14
+ s.email = %q{rats@attackcorp.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/rats.rb",
27
+ "lib/rats/base.rb",
28
+ "lib/rats/boundaries.rb",
29
+ "lib/rats/data.rb",
30
+ "lib/rats/data/base.rb",
31
+ "lib/rats/data/meridian.rb",
32
+ "lib/rats/data/quarter.rb",
33
+ "lib/rats/data/range.rb",
34
+ "lib/rats/data/section.rb",
35
+ "lib/rats/data/township.rb",
36
+ "rats.gemspec",
37
+ "spec/data/data_spec.rb",
38
+ "spec/data/meridian_spec.rb",
39
+ "spec/data/quarter_spec.rb",
40
+ "spec/data/range_spec.rb",
41
+ "spec/data/section_spec.rb",
42
+ "spec/data/township_spec.rb",
43
+ "spec/rats_spec.rb",
44
+ "spec/spec.opts",
45
+ "spec/spec_helper.rb"
46
+ ]
47
+ s.homepage = %q{http://github.com/attack/rats}
48
+ s.rdoc_options = ["--charset=UTF-8"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.3.6}
51
+ s.summary = %q{A ruby class to help with using the Alberta Township System}
52
+ s.test_files = [
53
+ "spec/data/data_spec.rb",
54
+ "spec/data/meridian_spec.rb",
55
+ "spec/data/quarter_spec.rb",
56
+ "spec/data/range_spec.rb",
57
+ "spec/data/section_spec.rb",
58
+ "spec/data/township_spec.rb",
59
+ "spec/rats_spec.rb",
60
+ "spec/spec_helper.rb"
61
+ ]
62
+
63
+ if s.respond_to? :specification_version then
64
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
65
+ s.specification_version = 3
66
+
67
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
68
+ else
69
+ end
70
+ else
71
+ end
72
+ end
73
+
@@ -0,0 +1,122 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Rats::Data do
4
+
5
+ it "initializes" do
6
+ data = Rats::Data.new
7
+ data.is_a?(Rats::Data).should be_true
8
+ end
9
+
10
+ describe "attributes" do
11
+
12
+ before(:each) do
13
+ @data = Rats::Data.new
14
+ end
15
+
16
+ describe "writing and reading" do
17
+
18
+ it "writes string" do
19
+ @data.value = "1"
20
+ @data.value.should == "1"
21
+ end
22
+
23
+ it "writes integer" do
24
+ @data.value = 1
25
+ @data.value.should == 1
26
+ end
27
+
28
+ it "writes string using alternate" do
29
+ @data.v = "1"
30
+ @data.v.should == "1"
31
+ @data.value.should == "1"
32
+ end
33
+
34
+ it "writes integer using alternate" do
35
+ @data.v = 1
36
+ @data.v.should == 1
37
+ @data.value.should == 1
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ describe "validation" do
45
+
46
+ it "stubs valid? with true" do
47
+ data = Rats::Data.new
48
+ data.valid?.should be_true
49
+ end
50
+
51
+ end
52
+
53
+ describe "methods" do
54
+
55
+ it "pads the value" do
56
+ data = Rats::Data.new(1)
57
+ data.to_p.should == "1"
58
+
59
+ #Rats::Data.should_receive(:padding_width).twice.and_return(3)
60
+ Rats::Data.expects(:padding_width).twice.returns(3)
61
+ data.to_p.should == " 1"
62
+
63
+ #Rats::Data.should_receive(:padding_value).and_return("0")
64
+ Rats::Data.expects(:padding_value).returns("0")
65
+ data.to_p.should == "001"
66
+ end
67
+
68
+ it "converts to string" do
69
+ data = Rats::Data.new(1)
70
+ data.to_s.should == "1"
71
+ end
72
+
73
+ it "resets a value" do
74
+ data = Rats::Data.new(1)
75
+ data.v.should == 1
76
+ data.nil!
77
+ data.v.should be_nil
78
+ end
79
+
80
+ end
81
+
82
+ describe "traversing" do
83
+
84
+ before(:each) do
85
+ @data = Rats::Data.new
86
+ end
87
+
88
+ it "stubs left" do
89
+ lambda { @data.left }.should raise_error(NotImplementedError)
90
+ end
91
+
92
+ it "stubs west" do
93
+ lambda { @data.west }.should raise_error(NotImplementedError)
94
+ end
95
+
96
+ it "stubs right" do
97
+ lambda { @data.right }.should raise_error(NotImplementedError)
98
+ end
99
+
100
+ it "stubs east" do
101
+ lambda { @data.east }.should raise_error(NotImplementedError)
102
+ end
103
+
104
+ it "stubs up" do
105
+ lambda { @data.up }.should raise_error(NotImplementedError)
106
+ end
107
+
108
+ it "stubs north" do
109
+ lambda { @data.north }.should raise_error(NotImplementedError)
110
+ end
111
+
112
+ it "stubs down" do
113
+ lambda { @data.down }.should raise_error(NotImplementedError)
114
+ end
115
+
116
+ it "stubs south" do
117
+ lambda { @data.south }.should raise_error(NotImplementedError)
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,100 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Rats::Meridian do
4
+
5
+ it "initializes" do
6
+ data = Rats::Meridian.new
7
+ data.is_a?(Rats::Meridian).should be_true
8
+ end
9
+
10
+ describe "boundaries" do
11
+
12
+ it "allows valid data" do
13
+ data = Rats::Meridian.new(6)
14
+ data.valid?.should be_true
15
+ end
16
+
17
+ it "doesn't allow bad data" do
18
+ data = Rats::Meridian.new
19
+ lambda { data.value = 3 }.should raise_error(ArgumentError)
20
+ end
21
+
22
+ end
23
+
24
+ describe "traversing" do
25
+
26
+ describe "correctly" do
27
+
28
+ it "moves up" do
29
+ data = Rats::Meridian.new("5")
30
+ lambda { data.up }.should raise_error(Rats::IllegalTraverse)
31
+ end
32
+
33
+ it "moves right" do
34
+ data = Rats::Meridian.new("5")
35
+ data.right.v.should == 4
36
+ end
37
+
38
+ it "moves down" do
39
+ data = Rats::Meridian.new("5")
40
+ lambda { data.up }.should raise_error(Rats::IllegalTraverse)
41
+ end
42
+
43
+ it "moves left" do
44
+ data = Rats::Meridian.new("5")
45
+ data.left.v.should == 6
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ describe "read/write" do
53
+
54
+ it "returns a padded value" do
55
+ data = Rats::Meridian.new('4')
56
+ data.to_p.should == '4'
57
+ end
58
+
59
+ it "returns the integer" do
60
+ data = Rats::Meridian.new('4')
61
+ data.v.should == 4
62
+ end
63
+
64
+ it "returns a string" do
65
+ data = Rats::Meridian.new('4')
66
+ data.to_s.should == 'W4'
67
+ end
68
+
69
+ it "writes just the integer" do
70
+ data = Rats::Meridian.new('W4')
71
+ data.v.should == 4
72
+ end
73
+
74
+ describe "transforming" do
75
+
76
+ it "accepts integers" do
77
+ Rats::Meridian.transform(4).should == 4
78
+ end
79
+
80
+ it "accepts strings" do
81
+ Rats::Meridian.transform('4').should == 4
82
+ end
83
+
84
+ it "accepts string prepended W" do
85
+ Rats::Meridian.transform('W4').should == 4
86
+ end
87
+
88
+ it "accepts string prepended w" do
89
+ Rats::Meridian.transform('w4').should == 4
90
+ end
91
+
92
+ it "doesn't accept other data" do
93
+ Rats::Meridian.transform('E4').should be_nil
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end