maintain 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,67 @@
1
+ # Some specs to check against ActiveRecord conflicts. Rails tends to blow
2
+ # shit up when you build it outside of Rails. We'll see how this goes...
3
+
4
+ proceed = false
5
+ begin
6
+ require 'rubygems'
7
+ require 'active_record'
8
+ proceed = true
9
+ rescue LoadError
10
+ puts 'Not testing ActiveRecord (unavailable)'
11
+ end
12
+
13
+ if proceed
14
+ # Use load to have it evaluate the ActiveRecord::Base extension logic again, in the event
15
+ # that we've already done that with a previous test.
16
+ load 'lib/maintain.rb'
17
+ describe Maintain, "ActiveRecord::Base" do
18
+ it "should automatically be extended" do
19
+ ActiveRecord::Base.should respond_to(:maintain)
20
+ end
21
+ describe "accessors" do
22
+ before :each do
23
+ ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:', :pool => 5, :timeout => 5000})
24
+ class ActiveMaintainTest < ActiveRecord::Base; end
25
+ silence_stream(STDOUT) do
26
+ ActiveRecord::Schema.define do
27
+ create_table :active_maintain_tests, :force => true do |t|
28
+ t.string :status
29
+ end
30
+ end
31
+ end
32
+
33
+ ActiveMaintainTest.maintain :status do
34
+ state :new, :default => true
35
+ state :old
36
+ aggregate :everything, :as => [:new, :old]
37
+ end
38
+ end
39
+
40
+ it "should default to 'new'" do
41
+ ActiveMaintainTest.new.status.should == 'new'
42
+ ActiveMaintainTest.new.status.should == :new
43
+ end
44
+
45
+ it "should allow us to update its status to 'old'" do
46
+ active_maintain_test = ActiveMaintainTest.new(:status => 'old')
47
+ active_maintain_test.status.should == 'old'
48
+ lambda {
49
+ active_maintain_test.save!
50
+ }.should_not raise_error
51
+ ActiveMaintainTest.first.status.should == 'old'
52
+ end
53
+ end
54
+
55
+ describe "named_scopes" do
56
+ it "should create named_scopes for all states" do
57
+ ActiveMaintainTest.should respond_to(:old)
58
+ ActiveMaintainTest.old.should be_instance_of(Array)
59
+ end
60
+
61
+ it "should create named_scopes for all aggregates" do
62
+ ActiveMaintainTest.should respond_to(:everything)
63
+ ActiveMaintainTest.everything.should be_instance_of(Array)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,35 @@
1
+ # Configuration point number one: setting and configuring states
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain, "aggregates" do
6
+ before :each do
7
+ class MaintainTest
8
+ extend Maintain
9
+ end
10
+ end
11
+
12
+ it "should allow me to define an aggregate" do
13
+ lambda {
14
+ MaintainTest.maintains :state do
15
+ state :old
16
+ state :new
17
+ state :borrowed
18
+ state :blue
19
+ aggregate :b_words, [:borrowed, :blue]
20
+ end
21
+ }.should_not raise_error
22
+ end
23
+
24
+ it "should create boolean methods" do
25
+ MaintainTest.new.should respond_to(:b_words?)
26
+ end
27
+
28
+ it "should return true if one of the states is met in the boolean" do
29
+ maintain = MaintainTest.new
30
+ maintain.state = :new
31
+ maintain.b_words?.should be_false
32
+ maintain.state = :blue
33
+ maintain.b_words?.should be_true
34
+ end
35
+ end
@@ -0,0 +1,83 @@
1
+ # Basic class method specs
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain do
6
+ before :each do
7
+ class MaintainTest
8
+ extend Maintain
9
+ end
10
+ end
11
+
12
+ describe "bitmask" do
13
+ before :each do
14
+ MaintainTest.maintain :permissions, :bitmask => true do
15
+ state :edit, 1
16
+ state :delete, 2
17
+ state :update, 3
18
+ end
19
+ @maintainer = MaintainTest.new
20
+ end
21
+
22
+ describe "accessor methods" do
23
+ it "should default to zero" do
24
+ maintainer = MaintainTest.new
25
+ maintainer.permissions.should == 0
26
+ end
27
+
28
+ it "should be able to test values" do
29
+ maintainer = MaintainTest.new
30
+ maintainer.permissions = :edit
31
+ maintainer.permissions.edit?.should be_true
32
+ maintainer.permissions.delete?.should_not be_true
33
+ maintainer.permissions = [:update, :delete]
34
+ maintainer.permissions.edit?.should_not be_true
35
+ maintainer.permissions.delete?.should be_true
36
+ maintainer.permissions.update?.should be_true
37
+ end
38
+
39
+ it "should be able to test values directly on the class" do
40
+ maintainer = MaintainTest.new
41
+ maintainer.permissions = :edit
42
+ maintainer.edit?.should be_true
43
+ maintainer.delete?.should_not be_true
44
+ end
45
+
46
+ it "should not trap every method" do
47
+ maintainer = MaintainTest.new
48
+ lambda {
49
+ maintainer.permissions.foobar?
50
+ }.should raise_error(NoMethodError)
51
+ end
52
+ end
53
+
54
+ describe "setter methods" do
55
+ it "should be able to set values on the whole field" do
56
+ @maintainer.permissions = :edit
57
+ @maintainer.permissions.should == [:edit]
58
+ @maintainer.permissions.should == 2
59
+ end
60
+
61
+ it "should be able to set values as an array" do
62
+ @maintainer.permissions = [:edit, :delete]
63
+ @maintainer.permissions.should == 6
64
+ @maintainer.permissions.should_not == 7
65
+ @maintainer.permissions.should == [:edit, :delete]
66
+ end
67
+
68
+ it "should be able to set individual bitmask values" do
69
+ @maintainer.permissions = nil
70
+ @maintainer.permissions = []
71
+ @maintainer.permissions.should == 0
72
+ @maintainer.permissions.edit!
73
+ @maintainer.permissions.edit?.should be_true
74
+ @maintainer.permissions.delete?.should_not be_true
75
+ @maintainer.permissions.update!
76
+ @maintainer.permissions.edit?.should be_true
77
+ @maintainer.permissions.edit?.should be_true
78
+ @maintainer.permissions.delete?.should_not be_true
79
+ @maintainer.permissions.update?.should be_true
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,194 @@
1
+ # Comparing state values
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain do
6
+ before :each do
7
+ class MaintainTest
8
+ attr_accessor :existant_attribute
9
+ extend Maintain
10
+ end
11
+ end
12
+
13
+ describe "testing" do
14
+ describe "string states" do
15
+ before :each do
16
+ MaintainTest.maintain :state, :default => :new do
17
+ state :new
18
+ state :overdue
19
+ state :closed
20
+ end
21
+ @maintainer = MaintainTest.new
22
+ @other_maintainer = MaintainTest.new
23
+ end
24
+
25
+ it "equality methods" do
26
+ @maintainer.state.should == :new
27
+ @maintainer.state.should == 'new'
28
+ @maintainer.state.should == 0
29
+ @maintainer.state.should == MaintainTest.new.state
30
+ @maintainer.state.should == @other_maintainer.state
31
+ end
32
+
33
+ describe "boolean methods" do
34
+ describe "on the accessor" do
35
+ it "should work" do
36
+ MaintainTest.maintain :state, :default => :new do
37
+ state :new
38
+ state :overdue
39
+ state :closed
40
+ end
41
+ maintainer = MaintainTest.new
42
+ maintainer.state.new?.should be_true
43
+ maintainer.state.overdue?.should be_false
44
+ maintainer.state.closed?.should be_false
45
+ end
46
+
47
+ it "should not trap every method" do
48
+ maintainer = MaintainTest.new
49
+ lambda {
50
+ maintainer.permissions.foobar?
51
+ }.should raise_error(NoMethodError)
52
+ end
53
+ end
54
+
55
+ describe "on the class itself" do
56
+ it "should work, too" do
57
+ MaintainTest.maintain :state, :default => :new do
58
+ state :new
59
+ state :overdue
60
+ state :closed
61
+ end
62
+ maintainer = MaintainTest.new
63
+ maintainer.state.new?.should be_true
64
+ maintainer.state.overdue?.should be_false
65
+ maintainer.state.closed?.should be_false
66
+ end
67
+
68
+ it "should not override pre-existing methods" do
69
+ class MaintainTestTwo
70
+ def new?
71
+ :i_existed_before_you_came_along
72
+ end
73
+ extend Maintain
74
+ maintains :state, :default => :new do
75
+ state :new
76
+ state :overdue
77
+ state :closed
78
+ end
79
+ end
80
+ MaintainTestTwo.new.new?.should == :i_existed_before_you_came_along
81
+ end
82
+ end
83
+ end
84
+
85
+ it "greater than method" do
86
+ MaintainTest.maintain :state, :default => :closed do
87
+ state :new
88
+ state :overdue
89
+ state :closed
90
+ end
91
+ @maintainer.state.should be > :overdue
92
+ @maintainer.state.should be > 'overdue'
93
+ @maintainer.state.should be > 1
94
+ end
95
+
96
+ it "less than method" do
97
+ @maintainer.state.should be < :overdue
98
+ @maintainer.state.should be < 'overdue'
99
+ @maintainer.state.should be < 1
100
+ end
101
+
102
+ it "greater-than-or-equal-to method" do
103
+ MaintainTest.maintain :state, :default => :closed do
104
+ state :new
105
+ state :overdue
106
+ state :closed
107
+ end
108
+ @maintainer.state.should be >= :overdue
109
+ @maintainer.state.should be >= 'overdue'
110
+ @maintainer.state.should be >= 1
111
+ @maintainer.state.should be >= :closed
112
+ @maintainer.state.should be >= 'closed'
113
+ @maintainer.state.should be >= 2
114
+ end
115
+
116
+ it "less-than-or-equal-to method" do
117
+ MaintainTest.maintain :state, :default => :new do
118
+ state :new
119
+ state :overdue
120
+ state :closed
121
+ end
122
+ @maintainer.state.should be <= :overdue
123
+ @maintainer.state.should be <= 'overdue'
124
+ @maintainer.state.should be <= 1
125
+ @maintainer.state.should be <= :new
126
+ @maintainer.state.should be <= 'new'
127
+ @maintainer.state.should be <= 0
128
+ end
129
+ end
130
+
131
+ describe "integer states" do
132
+ before :each do
133
+ MaintainTest.maintain :state, :default => :new do
134
+ state :new, 1
135
+ state :overdue, 2
136
+ state :closed, 3
137
+ end
138
+ @maintainer = MaintainTest.new
139
+ end
140
+
141
+ it "equality methods" do
142
+ @maintainer.state.should == :new
143
+ @maintainer.state.should == 'new'
144
+ @maintainer.state.should == 1
145
+ @maintainer.state.should == MaintainTest.new.state
146
+ end
147
+
148
+ it "greater than method" do
149
+ MaintainTest.maintain :state, :default => :closed do
150
+ state :new, 1
151
+ state :overdue, 2
152
+ state :closed, 3
153
+ end
154
+ @maintainer.state.should be > :overdue
155
+ @maintainer.state.should be > 'overdue'
156
+ @maintainer.state.should be > 1
157
+ end
158
+
159
+ it "less than method" do
160
+ @maintainer.state.should be < :overdue
161
+ @maintainer.state.should be < 'overdue'
162
+ @maintainer.state.should be < 2
163
+ end
164
+
165
+ it "greater-than-or-equal-to method" do
166
+ MaintainTest.maintain :state, :default => :closed do
167
+ state :new, 1
168
+ state :overdue, 2
169
+ state :closed, 3
170
+ end
171
+ @maintainer.state.should be >= :overdue
172
+ @maintainer.state.should be >= 'overdue'
173
+ @maintainer.state.should be >= 2
174
+ @maintainer.state.should be >= :closed
175
+ @maintainer.state.should be >= 'closed'
176
+ @maintainer.state.should be >= 3
177
+ end
178
+
179
+ it "less-than-or-equal-to method" do
180
+ MaintainTest.maintain :state, :default => :new do
181
+ state :new, 1
182
+ state :overdue, 2
183
+ state :closed, 3
184
+ end
185
+ @maintainer.state.should be <= :overdue
186
+ @maintainer.state.should be <= 'overdue'
187
+ @maintainer.state.should be <= 2
188
+ @maintainer.state.should be <= :new
189
+ @maintainer.state.should be <= 'new'
190
+ @maintainer.state.should be <= 1
191
+ end
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,79 @@
1
+ # Configuration point number one: setting and configuring states
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain do
6
+ before :each do
7
+ class MaintainTest
8
+ attr_accessor :existant_attribute
9
+ extend Maintain
10
+ end
11
+ end
12
+
13
+ describe "defining states" do
14
+ it "should be possible" do
15
+ lambda {
16
+ MaintainTest.maintain :existant_attribute do
17
+ state :new
18
+ end
19
+ }.should_not raise_error
20
+ MaintainTest.new.existant_attribute.should be_nil
21
+ end
22
+
23
+ it "should support default values" do
24
+ MaintainTest.maintain :existant_attribute do
25
+ state :new, :default => true
26
+ end
27
+ MaintainTest.new.existant_attribute.should == :new
28
+ end
29
+
30
+ it "should support integer values" do
31
+ MaintainTest.maintain :existant_attribute do
32
+ state :new, 1, :default => true
33
+ end
34
+ MaintainTest.new.existant_attribute.should == 1
35
+ end
36
+
37
+ it "should provide accessor methods on the Maintain::Maintainer class for state values" do
38
+ maintainer = MaintainTest.maintain :permissions, :bitmask => true do
39
+ state :edit, 1
40
+ state :delete, 2
41
+ state :update, 3
42
+ end
43
+ maintainer.update.should == 8
44
+ end
45
+
46
+ it "should not trap all methods when providing accessor methods for state values" do
47
+ maintainer = MaintainTest.maintain :permissions, :bitmask => true do
48
+ state :edit, 1
49
+ state :delete, 2
50
+ state :update, 3
51
+ end
52
+ lambda {
53
+ maintainer.i_probably_dont_exist
54
+ }.should raise_error(NoMethodError)
55
+ end
56
+
57
+ describe "as bitmask" do
58
+ it "should calculate a base-2 compatible integer" do
59
+ maintainer = MaintainTest.maintain :permissions, :bitmask => true do
60
+ state :edit, 1
61
+ state :delete, 2
62
+ state :update, 3
63
+ end
64
+ maintainer.update.should == 8
65
+ end
66
+
67
+ it "should auto-increment bitmask column values (but dangerously!)" do
68
+ maintainer = MaintainTest.maintain :permissions, :bitmask => true do
69
+ state :edit
70
+ state :delete
71
+ state :update
72
+ end
73
+ maintainer.edit.should == 1
74
+ maintainer.delete.should == 2
75
+ maintainer.update.should == 4
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,44 @@
1
+ # Comparing state values
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain, "hooks" do
6
+ before :each do
7
+ class MaintainTest
8
+ extend Maintain
9
+ end
10
+ end
11
+
12
+ it "should allow me to hook into entry and exit" do
13
+ lambda {
14
+ MaintainTest.maintain :state do
15
+ state :new, :enter => :new_entered
16
+ state :old, :enter => :old_entered
17
+ on :enter, :new, :new_entered
18
+ on :exit, :old do
19
+ self.old_entered
20
+ end
21
+ end
22
+ }.should_not raise_error
23
+ end
24
+
25
+ it "should execute hooks when states are entered and exited" do
26
+ MaintainTest.maintain :state do
27
+ state :new
28
+ state :old
29
+ on :enter, :new, :new_entered
30
+ on :exit, :old do
31
+ self.old_entered
32
+ end
33
+ end
34
+
35
+ maintain = MaintainTest.new
36
+ maintain.should_receive(:new_entered)
37
+ maintain.state = :new
38
+ maintain.should_receive(:old_entered)
39
+ maintain.state = :old
40
+ maintain.should_not_receive(:old_entered)
41
+ maintain.state = :old
42
+ end
43
+
44
+ end
@@ -0,0 +1,22 @@
1
+ # Basic class method specs
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain do
6
+ before :each do
7
+ class MaintainTest
8
+ extend Maintain
9
+ end
10
+ end
11
+
12
+ describe "integer" do
13
+ before :each do
14
+ MaintainTest.maintain :kind, :integer => true do
15
+ state :man, 1
16
+ state :woman, 2
17
+ state :none, 3
18
+ end
19
+ @maintainer = MaintainTest.new
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,45 @@
1
+ # Basic class method specs
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain do
6
+ before :each do
7
+ class MaintainTest
8
+ attr_accessor :existant_attribute
9
+ extend Maintain
10
+ end
11
+ end
12
+
13
+ # Basic overview / class methods
14
+ it "should extend things that include it" do
15
+ MaintainTest.should respond_to(:maintains)
16
+ end
17
+
18
+ it "should alias the maintain method as `maintains`" do
19
+ MaintainTest.should respond_to(:maintains)
20
+ end
21
+
22
+ it "should accept a block" do
23
+ lambda {
24
+ MaintainTest.maintain :non_existant_attribute do
25
+
26
+ end
27
+ }.should_not raise_error
28
+ end
29
+
30
+ it "should store a reference to all of the defined states in the class" do
31
+ MaintainTest.maintain :non_existant_attribute
32
+ MaintainTest.send(:maintainers)[:non_existant_attribute].should be_instance_of(Maintain::Maintainer)
33
+ end
34
+
35
+ it "should define accessors for non-existant attributes" do
36
+ MaintainTest.maintain :non_existant_attribute
37
+ MaintainTest.new.should respond_to('non_existant_attribute', 'non_existant_attribute=')
38
+ end
39
+
40
+ it "shouldn't care about existant attributes" do
41
+ lambda {
42
+ MaintainTest.maintain :existant_attribute
43
+ }.should_not raise_error
44
+ end
45
+ end
@@ -0,0 +1,7 @@
1
+ describe 'Maintain' do
2
+ it "should not monkey patch Object" do
3
+ lambda {
4
+ require "lib/maintain"
5
+ }.should_not change(Object, :methods)
6
+ end
7
+ end
@@ -0,0 +1,124 @@
1
+ # Comparing state values
2
+
3
+ require 'lib/maintain'
4
+
5
+ describe Maintain do
6
+ before :each do
7
+ class MaintainTest
8
+ attr_accessor :existant_attribute
9
+ extend Maintain
10
+ end
11
+
12
+ end
13
+
14
+ describe "`class` calls" do
15
+ it "should return NilClass for states without a value" do
16
+ MaintainTest.maintain :state do
17
+ state :new
18
+ state :overdue
19
+ state :closed
20
+ end
21
+ MaintainTest.new.state.class.should == NilClass
22
+ end
23
+
24
+ it "should return Symbol for states with a string column" do
25
+ MaintainTest.maintain :state do
26
+ state :new
27
+ state :overdue
28
+ state :closed
29
+ end
30
+ maintain_test = MaintainTest.new
31
+ maintain_test.state = :overdue
32
+ maintain_test.state.class.should == Symbol
33
+ end
34
+
35
+ it "should return Integer for states with an integer column" do
36
+ MaintainTest.maintain :state do
37
+ state :new, 0
38
+ state :overdue, 1
39
+ state :closed, 2
40
+ end
41
+ maintain_test = MaintainTest.new
42
+ maintain_test.state = :closed
43
+ maintain_test.state.class.should == Fixnum
44
+ end
45
+ end
46
+
47
+ describe "`inspect` calls" do
48
+ it "should return 'nil' for states without a default" do
49
+ MaintainTest.maintain :state do
50
+ state :new
51
+ state :overdue
52
+ state :closed
53
+ end
54
+ MaintainTest.new.state.inspect.should == 'nil'
55
+ end
56
+
57
+ it "should return ':new' for a state with a default value of :new" do
58
+ MaintainTest.maintain :state, :default => :new do
59
+ state :new
60
+ state :overdue
61
+ state :closed
62
+ end
63
+ MaintainTest.new.state.inspect.should == ':new'
64
+ end
65
+
66
+ it "should return '2' for a state with a default value of :new, 2 and an :integer column" do
67
+ MaintainTest.maintain :state, :default => :new do
68
+ state :new, 2
69
+ state :overdue, 5
70
+ state :closed, 22
71
+ end
72
+ MaintainTest.new.state.inspect.should == '2'
73
+ end
74
+ end
75
+
76
+ describe "`nil?` calls" do
77
+ it "should return true for states without a default" do
78
+ MaintainTest.maintain :state do
79
+ state :new
80
+ state :overdue
81
+ state :closed
82
+ end
83
+ MaintainTest.new.state.nil?.should be_true
84
+ end
85
+
86
+ it "should return false for states with a default" do
87
+ MaintainTest.maintain :state, :default => :new do
88
+ state :new
89
+ state :overdue
90
+ state :closed
91
+ end
92
+ MaintainTest.new.state.nil?.should_not be_true
93
+ end
94
+ end
95
+
96
+ describe "`to_s` calls" do
97
+ it "should return '' for states without a default" do
98
+ MaintainTest.maintain :state do
99
+ state :new
100
+ state :overdue
101
+ state :closed
102
+ end
103
+ MaintainTest.new.state.to_s.should == ''
104
+ end
105
+
106
+ it "should return 'new' for a state with a default value of :new" do
107
+ MaintainTest.maintain :state, :default => :new do
108
+ state :new
109
+ state :overdue
110
+ state :closed
111
+ end
112
+ MaintainTest.new.state.to_s.should == 'new'
113
+ end
114
+
115
+ it "should return '2' for a state with a default value of :new, 2 and an :integer column" do
116
+ MaintainTest.maintain :state, :default => :new do
117
+ state :new, 2
118
+ state :overdue, 5
119
+ state :closed, 22
120
+ end
121
+ MaintainTest.new.state.to_s.should == '2'
122
+ end
123
+ end
124
+ end