cascadence 0.1.1

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.
Files changed (64) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +8 -0
  3. data/Gemfile.lock +36 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.markdown +23 -0
  6. data/Rakefile +36 -0
  7. data/VERSION +1 -0
  8. data/cascadence.gemspec +111 -0
  9. data/coverage/.last_run.json +5 -0
  10. data/coverage/.resultset.json +588 -0
  11. data/coverage/assets/0.7.1/application.css +1110 -0
  12. data/coverage/assets/0.7.1/application.js +626 -0
  13. data/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  14. data/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  15. data/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  16. data/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  17. data/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  18. data/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  19. data/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  20. data/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  21. data/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  22. data/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  23. data/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  24. data/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  25. data/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  26. data/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  27. data/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  28. data/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  29. data/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  30. data/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  31. data/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  32. data/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  33. data/coverage/assets/0.7.1/favicon_green.png +0 -0
  34. data/coverage/assets/0.7.1/favicon_red.png +0 -0
  35. data/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  36. data/coverage/assets/0.7.1/loading.gif +0 -0
  37. data/coverage/assets/0.7.1/magnify.png +0 -0
  38. data/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  39. data/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  40. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  41. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  42. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  43. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  44. data/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  45. data/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  46. data/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  47. data/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  48. data/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  49. data/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  50. data/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  51. data/coverage/index.html +3702 -0
  52. data/lib/cascadence/class_methods.rb +39 -0
  53. data/lib/cascadence/flow.rb +17 -0
  54. data/lib/cascadence/helper.rb +21 -0
  55. data/lib/cascadence/stateful.rb +81 -0
  56. data/lib/cascadence.rb +7 -0
  57. data/spec/cascadence/class_methods_spec.rb +128 -0
  58. data/spec/cascadence/flow_spec.rb +64 -0
  59. data/spec/cascadence/fork_merge_spec.rb +86 -0
  60. data/spec/cascadence/helper_spec.rb +106 -0
  61. data/spec/cascadence/stateful_spec.rb +136 -0
  62. data/spec/cascadence_spec.rb +13 -0
  63. data/spec/spec_helper.rb +4 -0
  64. metadata +178 -0
@@ -0,0 +1,39 @@
1
+
2
+ module Cascadence
3
+
4
+ module ClassMethods
5
+ # Yes, I realize this is confusing
6
+ # I'm sorry for code-gulfing
7
+ # TODO: Write this class so we don't depend so heavily
8
+ # on recusion and "lazy evaluation" to get the ordering.
9
+ # This is probably 100% necessary if this project were
10
+ # ever to get big and require junk
11
+ def cascadence_order
12
+ @cascadence_order ||= []
13
+ @forked_position ||= []
14
+ @merge_position ||= []
15
+ unless @cascadence_order.nil?
16
+ Helper.generate_tributary(@cascadence_order.reverse, @forked_position.clone, @merge_position.clone)
17
+ end
18
+ end
19
+
20
+ def cascading_order( *order )
21
+ @cascadence_order ||= []
22
+ @cascadence_order << order
23
+ end
24
+
25
+ def fork_after( location )
26
+ @forked_position ||= []
27
+ index = cascadence_order.index location
28
+ @forked_position << (index + 1)
29
+ end
30
+
31
+ def merge_before( location )
32
+ @merge_position ||= []
33
+ index = cascadence_order.index location
34
+ @merge_position << (index - 1)
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Cascadence
3
+
4
+ # A simple implementation of stateful
5
+ class Flow
6
+ include Stateful
7
+ attr_accessor :state
8
+
9
+ def self.inherited(child)
10
+ if child.superclass.respond_to? :cascadence_order
11
+ order = child.superclass.cascadence_order
12
+ child.cascading_order *order
13
+ end
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,21 @@
1
+ module Cascadence
2
+ module Helper
3
+ # see the specs for what these guys do
4
+ def self.generate_tributary( arrays, starts=[], finish=[] )
5
+
6
+ if starts.empty? || arrays.count == 1
7
+ return arrays.reverse.flatten
8
+ end
9
+ generate_tributary arrays.push(replace_in_part(arrays.pop, arrays.pop, starts.pop, finish.pop) ), starts, finish
10
+ end
11
+
12
+ def self.replace_in_part(original, chunk, start, finish=nil)
13
+ return chunk if original.nil? || original.empty?
14
+ throw :OutOfRange if start >= original.count
15
+ result = original.clone
16
+ result[start..(finish||-1)] = chunk
17
+ return result
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,81 @@
1
+
2
+ module Cascadence
3
+
4
+ module Stateful
5
+
6
+ def self.included( base )
7
+ base.extend ClassMethods
8
+ base.class_exec do
9
+ attr_reader :cascadence_position
10
+ end # class_exec
11
+ end
12
+
13
+ def run_states
14
+ run_until :end
15
+ end
16
+
17
+ def run_until( target=nil )
18
+
19
+ return run_next if target.nil? and !block_given?
20
+
21
+ if block_given?
22
+ while !_cascadence_end? and !yield(self)
23
+ run_next
24
+ end
25
+ return self
26
+ end
27
+
28
+ case target.class.to_s
29
+ when "String", "Symbol"
30
+ return run_until { |state| state.current_step_name.to_s == target.to_s }
31
+ when "Fixnum", "Integer"
32
+ return run_until { |state| state.cascadence_position == target }
33
+ else
34
+ throw "Bad input error." unless target.respond_to? :call
35
+ return run_until { |state| target.call state }
36
+ end
37
+ end
38
+
39
+ def run_next
40
+ _debug_helper
41
+
42
+ unless next_step_name.nil?
43
+ send next_step_name
44
+ _increment_cascadence
45
+ end
46
+ self
47
+ end
48
+
49
+ def current_step_name
50
+ return nil if cascadence_position.nil?
51
+ self.class.cascadence_order[cascadence_position]
52
+ end
53
+
54
+ def next_step_name
55
+ return self.class.cascadence_order.first if cascadence_position.nil?
56
+ self.class.cascadence_order[cascadence_position+1]
57
+ end
58
+
59
+ private
60
+
61
+ def _cascadence_end?
62
+ return false if cascadence_position.nil?
63
+ cascadence_position >= self.class.cascadence_order.count - 1
64
+ end
65
+
66
+ def _increment_cascadence
67
+ if @cascadence_position.nil?
68
+ @cascadence_position = 0
69
+ else
70
+ @cascadence_position += 1
71
+ end
72
+ end
73
+
74
+ def _debug_helper
75
+ @debug_counter ||= 0
76
+ @debug_counter += 1
77
+ throw "Recursion Limit Reached! cascadence_position: #{cascadence_position} --> #{next_step_name}" if 100 < @debug_counter
78
+ end
79
+ end
80
+
81
+ end
data/lib/cascadence.rb ADDED
@@ -0,0 +1,7 @@
1
+
2
+ module Cascadence
3
+ autoload :Stateful, File.join( File.dirname(__FILE__), "cascadence", "stateful" )
4
+ autoload :ClassMethods, File.join( File.dirname(__FILE__), "cascadence", "class_methods" )
5
+ autoload :Flow, File.join( File.dirname(__FILE__), "cascadence", "flow" )
6
+ autoload :Helper, File.join( File.dirname(__FILE__), "cascadence", "helper")
7
+ end
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cascadence::ClassMethods do
4
+
5
+ let(:life) do
6
+ Class.new( Cascadence::Flow ) do
7
+ cascading_order :childhood, :teenage, :adulthood, :marriage, :mid_age, :old_age, :death
8
+
9
+ def initialize
10
+ self.state = "created"
11
+ end
12
+
13
+ def childhood
14
+ self.state += "-happy"
15
+ end
16
+
17
+ def teenage
18
+ self.state += "-misunderstood"
19
+ end
20
+
21
+ def adulthood
22
+ self.state += "-responsible"
23
+ end
24
+
25
+ def marriage
26
+ self.state += "-busy"
27
+ end
28
+
29
+ def mid_age
30
+ self.state += "-content"
31
+ end
32
+
33
+ def old_age
34
+ self.state += "-tired"
35
+ end
36
+
37
+ def death
38
+ self.state += "-rip"
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "position" do
44
+
45
+ it "should give me the correct numerical value for the index command" do
46
+ life.cascadence_order.index(:teenage).should eq 1
47
+ end
48
+ end
49
+
50
+ describe "inheritance" do
51
+ let(:japanese) { Class.new(life) }
52
+
53
+ describe "defaults" do
54
+
55
+ describe "#cascadence_order" do
56
+ subject { japanese.cascadence_order }
57
+
58
+ it "should be inherited from the parent cascadence order" do
59
+ should eq life.cascadence_order
60
+ end
61
+ end
62
+
63
+ describe "#run_states" do
64
+ subject { japanese.new.run_states.state }
65
+
66
+ it "should match exactly the states as run by the parent" do
67
+ should eq life.new.run_states.state
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ describe "difference" do
74
+
75
+ before :each do
76
+ japanese.class_exec do
77
+ def loli
78
+ self.state += "-kawaii"
79
+ end
80
+
81
+ def schoolgirl
82
+ self.state += "-chikan"
83
+ end
84
+
85
+ def ol
86
+ self.state += "-alcoholic"
87
+ end
88
+
89
+ def settle
90
+ self.state += "-ntr"
91
+ end
92
+
93
+ def mid_age
94
+ self.state += "-depressed"
95
+ end
96
+ end
97
+ end
98
+
99
+ describe "position" do
100
+ it "should have the correct position" do
101
+ japanese.fork_after :childhood
102
+ japanese.merge_before :mid_age
103
+ japanese.cascadence_order.should eq [:childhood, :teenage, :adulthood, :marriage, :mid_age, :old_age, :death]
104
+ japanese.cascading_order :loli, :schoolgirl, :ol, :settle
105
+ japanese.cascadence_order.should eq [:childhood, :loli, :schoolgirl, :ol, :settle, :mid_age, :old_age, :death]
106
+ end
107
+ end
108
+
109
+ describe "results" do
110
+ before :each do
111
+ japanese.fork_after :childhood
112
+ japanese.merge_before :mid_age
113
+ japanese.cascading_order :loli, :schoolgirl, :ol, :settle
114
+ end
115
+ it "should have a different cascadence order than the parent class" do
116
+ life.cascadence_order.should_not eq japanese.cascadence_order
117
+ end
118
+
119
+ it "should result in a different terminal state when the states are run" do
120
+ life.new.run_states.state.should_not eq japanese.new.run_states.state
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ class FlowTest < Cascadence::Flow
4
+
5
+ cascading_order :step1, :step2, :step3, :step4
6
+
7
+ def initialize
8
+ self.state = "initialized"
9
+ end
10
+
11
+ def step1
12
+ self.state += "-step1"
13
+ end
14
+
15
+ def step2
16
+ self.state += "-step2"
17
+ end
18
+
19
+ def step3
20
+ self.state += "-step3"
21
+ end
22
+
23
+ def step4
24
+ self.state += "-step4"
25
+ end
26
+
27
+ end
28
+
29
+ describe Cascadence::Flow do
30
+
31
+ before :each do
32
+ @flow = FlowTest.new
33
+ end
34
+
35
+ describe "sanity" do
36
+
37
+ it "should be an instance of flowtest" do
38
+ @flow.class.should eq FlowTest
39
+ end
40
+
41
+ it "should respond to state" do
42
+ @flow.should respond_to :state
43
+ @flow.should respond_to :state=
44
+ @flow.state.should eq "initialized"
45
+ end
46
+
47
+ it "should be an instance of cascadence::flow" do
48
+ FlowTest.superclass.should eq Cascadence::Flow
49
+ end
50
+
51
+ end
52
+
53
+ describe "run states" do
54
+
55
+ before(:each) { @expected = "initialized-step1-step2-step3-step4" }
56
+ let(:actual) { @flow.run_states }
57
+
58
+ it "should run all four states in the specified cascading order" do
59
+ actual.state.should eq @expected
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cascadence::Flow do
4
+ let(:euphrates) do
5
+ Class.new( Cascadence::Flow ) do
6
+ cascading_order :eden, :babylon, :gulf
7
+
8
+ def initialize
9
+ self.state = "created"
10
+ end
11
+
12
+ def eden
13
+ self.state += "-innocence"
14
+ end
15
+
16
+ def babylon
17
+ self.state += "-prosperity"
18
+ end
19
+
20
+ def gulf
21
+ self.state += "-downfall"
22
+ end
23
+
24
+ end
25
+ end
26
+
27
+ let(:tigris) do
28
+ Class.new( euphrates ) do
29
+ fork_after :eden
30
+ merge_before :gulf
31
+ cascading_order :sumer, :israel
32
+ def sumer
33
+ self.state += "-discovery"
34
+ end
35
+
36
+ def israel
37
+ self.state += "-arrogance"
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#cascadence_order" do
43
+
44
+ context "parent" do
45
+ subject { euphrates.cascadence_order }
46
+
47
+ it "should remain unchanged from what it was" do
48
+ should eq [:eden, :babylon, :gulf]
49
+ end
50
+ end
51
+
52
+ context "child" do
53
+ subject { tigris.cascadence_order }
54
+
55
+ it "should have been forked from the parent cascadence order" do
56
+ should eq [:eden, :sumer, :israel, :gulf]
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ describe "#run_state" do
63
+
64
+ describe "parent" do
65
+ subject { euphrates.new.run_states.state }
66
+
67
+ it "should generate the expected state without regard to forks" do
68
+ should eq "created-innocence-prosperity-downfall"
69
+ end
70
+ end
71
+
72
+ describe "child" do
73
+ subject { tigris.new.run_states.state }
74
+
75
+ it "should have the right states to run" do
76
+ tigris.cascadence_order.should eq [:eden, :sumer, :israel, :gulf]
77
+ tigris.new.run_states.state.should eq "created-innocence-discovery-arrogance-downfall"
78
+ end
79
+ it "should generate the expected state after succesful forking from the parent" do
80
+ should eq "created-innocence-discovery-arrogance-downfall"
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cascadence::Helper do
4
+ let(:api) { Cascadence::Helper }
5
+
6
+ describe "#generate_tributary" do
7
+ context "standard usage" do
8
+ before :each do
9
+ @arrays = [
10
+ ["o","t"] ,
11
+ ["a","g"] ,
12
+ ["f","b","c","g"]
13
+ ]
14
+ @starts = [1]
15
+ @finishes = [2]
16
+ @expected = ["f","a","g","g","o","t"]
17
+ end
18
+
19
+ it "should reduce the given array to the expected array" do
20
+ api.generate_tributary(@arrays, @starts, @finishes).should eq @expected
21
+ end
22
+
23
+ it "should work with simpler arrays also" do
24
+ arrays = [
25
+ ['a','g','g','o'] ,
26
+ ['f','b','b','b','t']
27
+ ]
28
+ start = [1]
29
+ merge = [3]
30
+ api.generate_tributary(arrays, start, merge).should eq @expected
31
+ end
32
+ end
33
+
34
+ context "weird input" do
35
+ before :each do
36
+ @arrays = [
37
+ ["o","t"] ,
38
+ ["a","g"] ,
39
+ ["f","b","c","g"]
40
+ ]
41
+ @starts = [1]
42
+ @finishes = [2]
43
+ @expected = ["f","a","g","g","o","t"]
44
+ end
45
+
46
+ it "should return the array as is" do
47
+ api.generate_tributary([[1,2,3,4]]).should eq [1,2,3,4]
48
+ end
49
+
50
+ it "should entirely ignore merge points if no fork points were specified" do
51
+ api.generate_tributary(@arrays, [1], [23,234,23,23,3,2]).should eq @expected
52
+ end
53
+
54
+ it "should entirely replace to the end if no merge points were specified" do
55
+ arrays = [
56
+ "I love eating food".split(" ") ,
57
+ "big throbbing ipad".split(" ") ,
58
+ "explicitive deleted".split(" ")
59
+ ].reverse
60
+ api.generate_tributary(arrays, [4,2]).join(" ").should eq "I love big throbbing explicitive deleted"
61
+ end
62
+ end
63
+
64
+ context "bad input" do
65
+
66
+ it "should do as much as possible and ignore the rest of the starts if the initial array isn't long enough" do
67
+ api.generate_tributary([[1,2,3,4,5], [10,2,3,4]], [5,4,3,1]).should eq [10,1,2,3,4,5]
68
+ end
69
+
70
+ it "should throw an error if you attempt to start well after the array" do
71
+ expect do
72
+ api.generate_tributary([[1,2,3,4],[1,2,3]], [99])
73
+ end.to throw_symbol :OutOfRange
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ describe "#replace_in_part" do
80
+
81
+ it "should replace the specified chunk in a given array" do
82
+ original = "f a b t".split " "
83
+ chunk = "g g o".split " "
84
+ api.replace_in_part( original, chunk, 2, 2).join.should eq "faggot"
85
+ original.join.should eq "fabt"
86
+ chunk.join.should eq "ggo"
87
+ end
88
+ end
89
+
90
+ it "should replace as much as possible and then just append the rest in the case the replacement is longer than the original" do
91
+ original = "asd".split ""
92
+ chunk = "sshole".split ""
93
+ api.replace_in_part(original, chunk, 1).join.should eq "asshole"
94
+ end
95
+
96
+ it "should return the chunk if the original array is empty; it should ignore the other options" do
97
+ api.replace_in_part([], [1,2,3,4], 42).should eq [1,2,3,4]
98
+ end
99
+
100
+ it "should return a cropped version of the array if the replacement chunk is empty" do
101
+ api.replace_in_part([1,2,3,4], [], 2).should eq [1,2]
102
+ api.replace_in_part([0,1,2,3,4,5,6,7],[], 2, 4).should eq [0,1,5,6,7]
103
+ end
104
+
105
+
106
+ end
@@ -0,0 +1,136 @@
1
+ require "spec_helper"
2
+
3
+ class CascadeTest
4
+ include Cascadence::Stateful
5
+
6
+ cascading_order :step1, :step2, :step3
7
+
8
+ attr_reader :foo
9
+
10
+ def step1
11
+ @foo = 2
12
+ end
13
+
14
+ def step2
15
+ @foo *= 3
16
+ end
17
+
18
+ def step3
19
+ @foo -= 5
20
+ end
21
+ end
22
+
23
+ describe Cascadence do
24
+
25
+ before :each do
26
+ @test = CascadeTest.new
27
+ end
28
+
29
+ describe "CascadeTest.new" do
30
+
31
+ it "should have the cascadence_position property" do
32
+ @test.should respond_to :cascadence_position
33
+ end
34
+
35
+ it "should have a null current step" do
36
+ @test.current_step_name.should be_nil
37
+ end
38
+
39
+ it "should have step1 as it's next step" do
40
+ @test.next_step_name.should eq :step1
41
+ end
42
+
43
+ end
44
+
45
+ describe "CascadeTest" do
46
+
47
+ it "should have the cascadence_order property" do
48
+ CascadeTest.should respond_to :cascadence_order
49
+ end
50
+
51
+ end
52
+
53
+ describe "run next" do
54
+
55
+ it "should run the first thing specified by the cascadence order" do
56
+ @test.run_next.foo.should eq 2
57
+ end
58
+
59
+ it "should run the first two steps specified by the cascadence order" do
60
+ @test.run_next.tap do |cascade|
61
+ cascade.foo.should eq 2
62
+ end.run_next.foo.should eq 6
63
+ end
64
+
65
+ it "should run all 3 steps specified by the cascadence order" do
66
+ @test.run_next.run_next.run_next.foo.should eq 1
67
+ end
68
+
69
+ it "should not do anything to the result on extra calls" do
70
+ exp = [2,6,1]
71
+ (0..6).to_a.inject(@test) do |mem, nex|
72
+ n = nex < 3 ? nex : 2
73
+ res = mem.run_next
74
+ res.class.should eq CascadeTest
75
+ res.foo.should_not be_nil
76
+ exp[n].should_not be_nil
77
+ res.foo.should eq exp[n]
78
+ res
79
+ end.foo.should eq exp.last
80
+ end
81
+ end
82
+
83
+ describe "run states" do
84
+
85
+ let(:final) { @test.run_states }
86
+
87
+ it "should have a valid final state" do
88
+ final.should_not be_nil
89
+ end
90
+
91
+ it "should have maintained the correct cascadence order" do
92
+ final.class.cascadence_order.should eq [:step1, :step2, :step3]
93
+ end
94
+
95
+ it "should have advanced to the final cascadence position" do
96
+ final.cascadence_position.should eq 2
97
+ end
98
+
99
+ it "should have the correct cascadence result" do
100
+ final.foo.should eq 1
101
+ end
102
+
103
+ end
104
+
105
+ describe "run until" do
106
+
107
+ it "should run to a specified block" do
108
+ result = @test.run_until do |state|
109
+ :step3 == state.current_step_name
110
+ end
111
+ result.current_step_name.should eq :step3
112
+ result.foo.should eq 1
113
+ end
114
+
115
+ it "should run to a specified order" do
116
+ @test.run_until(:step2).foo.should eq 6
117
+ end
118
+
119
+ it "should run to a specified number" do
120
+ @test.run_until(1).foo.should eq 6
121
+ end
122
+
123
+ it "should run to a specified foreign class" do
124
+ checker = lambda do |state|
125
+ state.current_step_name == :step3
126
+ end
127
+ @test.run_until(checker).foo.should eq 1
128
+ end
129
+
130
+ it "should have the same result when calling successively" do
131
+ @test.run_until.run_until.run_until.foo.should eq 1
132
+ end
133
+
134
+ end
135
+
136
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ describe Cascadence do
4
+ it "should pass the presence sanity test" do
5
+ Cascadence.class.should eq Module
6
+ end
7
+
8
+ [:Flow, :ClassMethods, :Stateful, :Helper].each do |constant|
9
+ it "should contain the correct #{constant} constant" do
10
+ Cascadence.const_get(constant).should_not be_nil
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ require 'simplecov'
2
+ require File.join File.expand_path("..", File.dirname(__FILE__)), "lib", "cascadence"
3
+
4
+ SimpleCov.start