rats 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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