cascadence 0.1.2 → 0.2.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.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +7 -0
- data/VERSION +1 -1
- data/bin/cascadence +4 -0
- data/cascadence.gemspec +31 -4
- data/coverage/.last_run.json +1 -1
- data/coverage/.resultset.json +648 -86
- data/coverage/index.html +3893 -377
- data/fixtures/README.md +1 -0
- data/fixtures/amazon/madeira_flow.rb +26 -0
- data/fixtures/amazon/rio_negro_flow.rb +1 -0
- data/fixtures/amazon_flow.rb +2 -0
- data/fixtures/dogwood.clj +1 -0
- data/fixtures/faggot_spec.rb +1 -0
- data/fixtures/flow_helper.rb +3 -0
- data/fixtures/lib/nothing.rb +1 -0
- data/fixtures/nile/blue_nile_flow.rb +1 -0
- data/fixtures/nile/white_nile/gray_nile_flow.rb +1 -0
- data/fixtures/nile/white_nile_flow.rb +1 -0
- data/fixtures/nile_flow.rb +1 -0
- data/lib/cascadence.rb +15 -1
- data/lib/cascadence/commander.rb +75 -0
- data/lib/cascadence/config.rb +12 -0
- data/lib/cascadence/flow.rb +4 -0
- data/lib/cascadence/runner.rb +62 -0
- data/lib/cascadence/task.rb +14 -0
- data/spec/cascadence/advanced_fork_merge_spec.rb +122 -0
- data/spec/cascadence/commander_spec.rb +184 -0
- data/spec/cascadence/flow_spec.rb +12 -1
- data/spec/cascadence/runner_spec.rb +28 -0
- data/spec/spec_helper.rb +5 -1
- metadata +65 -29
data/fixtures/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fasdfa\n=
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Amazon
|
|
2
|
+
class MadeiraFlow < ::Cascadence::Flow
|
|
3
|
+
cascading_order :step1, :step2, :step3
|
|
4
|
+
|
|
5
|
+
def initialize(state)
|
|
6
|
+
self.state = state || "initialized"
|
|
7
|
+
puts state
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def step1
|
|
11
|
+
self.state += "1"
|
|
12
|
+
puts state
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def step2
|
|
16
|
+
self.state += "2"
|
|
17
|
+
puts state
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def step3
|
|
21
|
+
self.state += "3"
|
|
22
|
+
puts state
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
asdf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(defn dogwood [ca] (ca) )
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
describe Faggot do; end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
asdfasdfasdfasdf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dfasdf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fajsdf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dfasdf
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
describe Faggot do; end
|
data/lib/cascadence.rb
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
require "thor"
|
|
2
|
+
require "active_support/core_ext/string"
|
|
3
|
+
require "active_support/core_ext/module"
|
|
4
|
+
require "singleton"
|
|
2
5
|
module Cascadence
|
|
3
6
|
autoload :Stateful, File.join( File.dirname(__FILE__), "cascadence", "stateful" )
|
|
4
7
|
autoload :ClassMethods, File.join( File.dirname(__FILE__), "cascadence", "class_methods" )
|
|
5
8
|
autoload :Flow, File.join( File.dirname(__FILE__), "cascadence", "flow" )
|
|
6
9
|
autoload :Helper, File.join( File.dirname(__FILE__), "cascadence", "helper")
|
|
10
|
+
autoload :Commander, File.join( File.dirname(__FILE__), "cascadence", "commander")
|
|
11
|
+
autoload :Runner, File.join( File.dirname(__FILE__), "cascadence", "runner")
|
|
12
|
+
autoload :Config, File.join( File.dirname(__FILE__), "cascadence", "config")
|
|
13
|
+
autoload :Task, File.join( File.dirname(__FILE__), "cascadence", "task")
|
|
14
|
+
def self.config
|
|
15
|
+
Config.instance
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.runner
|
|
19
|
+
Runner.instance
|
|
20
|
+
end
|
|
7
21
|
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module Cascadence
|
|
2
|
+
class Commander < Thor
|
|
3
|
+
|
|
4
|
+
desc "version", "Not implemented yet. That's right, the command that tells you what version of cascadence you're running has not been implemented yet."
|
|
5
|
+
def version
|
|
6
|
+
puts "El Psy Congroo"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc "flow", "Runs the flow specified in the given file. If given a directory, runs all the flows in the directory."
|
|
10
|
+
def flow(filepath=Dir.pwd)
|
|
11
|
+
files = _get_files_from_filepath _absolutize_filepath filepath
|
|
12
|
+
_setup_environment_from_filepath!(filepath)
|
|
13
|
+
tasks = files.map { |file| _get_task_from_file file }
|
|
14
|
+
_run_tasks tasks
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def _run_tasks(tasks)
|
|
20
|
+
Cascadence.runner.run_tasks tasks
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def _absolutize_filepath(filepath)
|
|
24
|
+
return filepath if filepath =~ /^\//
|
|
25
|
+
return File.expand_path(filepath) if filepath =~ /^~/
|
|
26
|
+
return File.join(Dir.pwd, filepath)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def _get_files_from_filepath(filepath)
|
|
30
|
+
return [filepath] if _flow_file? filepath
|
|
31
|
+
return [] unless File.exists? filepath
|
|
32
|
+
Dir[File.join(filepath, "*")].map { |file_or_dir| _get_files_from_filepath file_or_dir }.flatten
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def _flow_file?(filepath)
|
|
36
|
+
(filepath =~ /_flow\.rb$/) && File.file?(filepath)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def _setup_environment_from_filepath!(filepath)
|
|
40
|
+
require _find_flow_helper_from_filepath filepath
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def _find_flow_helper_from_filepath( filepath )
|
|
44
|
+
_find_flow_helper_from_filepath File.expand_path("..", filepath) unless File.directory? filepath
|
|
45
|
+
throw :NoFlowHelperFound if filepath == "/"
|
|
46
|
+
Dir[File.join(filepath, "*")].select { |file| _flow_helper? file }.first || _find_flow_helper_from_filepath( File.expand_path("..", filepath) )
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def _flow_helper?(filepath)
|
|
50
|
+
(filepath =~ /\/flow_helper\.rb$/) && File.file?(filepath)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def _get_task_from_file(file)
|
|
54
|
+
flow = _get_flow_from_file file
|
|
55
|
+
Cascadence::Task.new(_get_zero_state_generator_from_flow flow) do |state=nil|
|
|
56
|
+
flow.new(state).run_states
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def _get_zero_state_generator_from_flow(flow)
|
|
61
|
+
return flow.zero_state_generator if flow.respond_to? :zero_state_generator
|
|
62
|
+
return Cascadence.config.zero_state_generator if flow == Object
|
|
63
|
+
_get_zero_state_generator_from_flow(flow.parent)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def _get_flow_from_file(file)
|
|
67
|
+
Cascadence::Flow.subclasses.select { |subclass| _reasonably_matched?(subclass.to_s, file.chomp(".rb")) }.first
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def _reasonably_matched?(str1, str2)
|
|
71
|
+
!(str2.to_s.gsub(/^\/?/, "/") =~ Regexp.new("\/" + str1.to_s.split("::").map(&:underscore).join("/") + "$")).nil?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
data/lib/cascadence/flow.rb
CHANGED
|
@@ -6,7 +6,11 @@ module Cascadence
|
|
|
6
6
|
include Stateful
|
|
7
7
|
attr_accessor :state
|
|
8
8
|
|
|
9
|
+
def self.subclasses
|
|
10
|
+
@@subclasses ||= []
|
|
11
|
+
end
|
|
9
12
|
def self.inherited(child)
|
|
13
|
+
Flow.subclasses.push child
|
|
10
14
|
if child.superclass.respond_to? :cascadence_order
|
|
11
15
|
order = child.superclass.cascadence_order
|
|
12
16
|
child.cascading_order *order
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Cascadence
|
|
2
|
+
class Runner
|
|
3
|
+
include Singleton
|
|
4
|
+
|
|
5
|
+
def run_tasks(tasks)
|
|
6
|
+
if Cascadence.config.parallel
|
|
7
|
+
_run_parallel tasks
|
|
8
|
+
else
|
|
9
|
+
_run_sequential tasks
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# def _run_parallel(tasks)
|
|
16
|
+
# threads = []
|
|
17
|
+
# puts "Attempting to run with #{tasks.count} tasks"
|
|
18
|
+
# tasks.each do |task|
|
|
19
|
+
# thread = Thread.new do
|
|
20
|
+
# puts "Spinning up thread number #{threads.count}"
|
|
21
|
+
# task.call
|
|
22
|
+
# end
|
|
23
|
+
# puts "Pushing thread number #{threads.count} to thread pool"
|
|
24
|
+
# threads << thread
|
|
25
|
+
# sleep 0.5
|
|
26
|
+
# end
|
|
27
|
+
# while threads.inject(false) { |finished, thread| finished || thread.alive? }
|
|
28
|
+
# sleep 0.5
|
|
29
|
+
# end
|
|
30
|
+
# end
|
|
31
|
+
|
|
32
|
+
def _run_parallel(tasks, threads=[])
|
|
33
|
+
return if tasks.empty? && threads.empty?
|
|
34
|
+
package = _maybe_spin_up_thread(tasks, threads)
|
|
35
|
+
new_tasks = package.first
|
|
36
|
+
new_threads = package.last
|
|
37
|
+
_run_parallel new_tasks, new_threads
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def _maybe_spin_up_thread(tasks, threads=[])
|
|
41
|
+
if threads.count > Cascadence.config.max_thread_count
|
|
42
|
+
new_threads = threads
|
|
43
|
+
new_tasks = tasks
|
|
44
|
+
else
|
|
45
|
+
new_threads = _spin_up_task(tasks.pop, threads)
|
|
46
|
+
new_tasks = tasks
|
|
47
|
+
end
|
|
48
|
+
sleep 0.5
|
|
49
|
+
return [new_tasks, new_threads.select(&:alive?)]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def _spin_up_task(task, threads=[])
|
|
53
|
+
puts "Spinning up thread no.#{threads.count} out of #{Cascadence.config.max_thread_count}"
|
|
54
|
+
thread = Thread.new { task.call } unless task.nil?
|
|
55
|
+
threads.push thread unless thread.nil?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def _run_sequential(tasks)
|
|
59
|
+
tasks.map(&:call).map(&:state)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Cascadence
|
|
2
|
+
class Task
|
|
3
|
+
def initialize(zero_state_generator=nil, &block)
|
|
4
|
+
@block = block
|
|
5
|
+
@zstate_gen = zero_state_generator
|
|
6
|
+
@zstate_gen ||= Cascadence.config.zero_state_generator
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def call
|
|
10
|
+
@block.call @zstate_gen.call
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Cascadence::Flow do
|
|
4
|
+
let(:amazon) do
|
|
5
|
+
Class.new(Cascadence::Flow) do
|
|
6
|
+
cascading_order :step1, :step2, :step3, :stepcrap
|
|
7
|
+
def initialize
|
|
8
|
+
self.state = "initialize"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def step1
|
|
12
|
+
self.state += "1"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def step2
|
|
16
|
+
self.state += "2"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def step3
|
|
20
|
+
self.state += "3"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def stepcrap
|
|
24
|
+
self.state += "crap"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
context "preemptivization" do
|
|
29
|
+
let(:amazon_zero) do
|
|
30
|
+
Class.new(amazon) do
|
|
31
|
+
merge_before :step1
|
|
32
|
+
cascading_order :step0
|
|
33
|
+
|
|
34
|
+
def step0
|
|
35
|
+
self.state += "0"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
describe "#cascadence_order" do
|
|
40
|
+
context "child" do
|
|
41
|
+
subject { amazon_zero.cascadence_order }
|
|
42
|
+
|
|
43
|
+
it "should be a continuation of the parent" do
|
|
44
|
+
pending "Not going to worry about this unless this is actually needed"
|
|
45
|
+
should eq [:step0, :step1, :step2, :step3, :stepcrap]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
context "parent" do
|
|
49
|
+
subject { amazon.cascadence_order }
|
|
50
|
+
|
|
51
|
+
it "should be as expected from the declaration" do
|
|
52
|
+
should eq [:step1, :step2, :step3, :stepcrap]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
describe "#run_states" do
|
|
57
|
+
context "child" do
|
|
58
|
+
subject { amazon_zero.new.run_states.state }
|
|
59
|
+
|
|
60
|
+
it "should give the expected state value" do
|
|
61
|
+
pending "Not going to worry about this unless this is actually needed"
|
|
62
|
+
should eq "initialize0123crap"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
context "parent" do
|
|
66
|
+
subject {amazon.new.run_states.state }
|
|
67
|
+
it "should give the expected parent state value" do
|
|
68
|
+
should eq "initialize123crap"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
context "continuation" do
|
|
74
|
+
let(:amazon_prime) do
|
|
75
|
+
Class.new(amazon) do
|
|
76
|
+
fork_after :step3
|
|
77
|
+
cascading_order :step4, :step5
|
|
78
|
+
|
|
79
|
+
def step4
|
|
80
|
+
self.state += "4"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def step5
|
|
84
|
+
self.state += "5"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe "#cascadence_order" do
|
|
90
|
+
context "child" do
|
|
91
|
+
subject { amazon_prime.cascadence_order }
|
|
92
|
+
|
|
93
|
+
it "should be a continuation of the parent" do
|
|
94
|
+
should eq [:step1, :step2, :step3, :step4, :step5]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
context "parent" do
|
|
98
|
+
subject { amazon.cascadence_order }
|
|
99
|
+
|
|
100
|
+
it "should be as expected from the declaration" do
|
|
101
|
+
should eq [:step1, :step2, :step3, :stepcrap]
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe "#run_states" do
|
|
107
|
+
context "child" do
|
|
108
|
+
subject { amazon_prime.new.run_states.state }
|
|
109
|
+
|
|
110
|
+
it "should give the expected state value" do
|
|
111
|
+
should eq "initialize12345"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
context "parent" do
|
|
115
|
+
subject {amazon.new.run_states.state }
|
|
116
|
+
it "should give the expected parent state value" do
|
|
117
|
+
should eq "initialize123crap"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
describe Cascadence::Commander do
|
|
5
|
+
let(:lolcat) { Cascadence::Commander.new }
|
|
6
|
+
context "public api" do
|
|
7
|
+
describe "#flow" do
|
|
8
|
+
let(:result) { lolcat.flow File.join(RSpec::FixturePath, "amazon", "madeira_flow.rb") }
|
|
9
|
+
it "should run the flow stated" do
|
|
10
|
+
result.should eq ["initialized123"]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
context "private" do
|
|
15
|
+
describe "#_get_zero_state_generator_from_flow" do
|
|
16
|
+
module GetZero
|
|
17
|
+
def self.zero_state_generator
|
|
18
|
+
lambda { "get_zero" }
|
|
19
|
+
end
|
|
20
|
+
class Fagbar < Cascadence::Flow
|
|
21
|
+
class HeyzapFlow < ::Cascadence::Flow
|
|
22
|
+
class CrossFlow
|
|
23
|
+
class WeHaveToGoDeeper
|
|
24
|
+
def self.zero_state_generator
|
|
25
|
+
lambda { "we_have_to_go_deeper" }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
it "should properly give me parents where applicable" do
|
|
33
|
+
GetZero::Fagbar::HeyzapFlow::CrossFlow::WeHaveToGoDeeper.parent.should eq GetZero::Fagbar::HeyzapFlow::CrossFlow
|
|
34
|
+
end
|
|
35
|
+
it "should give me nil for the outer level" do
|
|
36
|
+
GetZero.parent.should == Object
|
|
37
|
+
end
|
|
38
|
+
let(:result) { lolcat.send "_get_zero_state_generator_from_flow", @flow }
|
|
39
|
+
context "warpspeed" do
|
|
40
|
+
before :each do
|
|
41
|
+
@flow = GetZero::Fagbar::HeyzapFlow::CrossFlow
|
|
42
|
+
end
|
|
43
|
+
it "should get me the first zero_state_generator" do
|
|
44
|
+
result.call.should eq "get_zero"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
context "inception" do
|
|
48
|
+
before :each do
|
|
49
|
+
@flow = GetZero::Fagbar::HeyzapFlow::CrossFlow::WeHaveToGoDeeper
|
|
50
|
+
end
|
|
51
|
+
it "should get the closest zero state generator" do
|
|
52
|
+
result.call.should eq "we_have_to_go_deeper"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
describe "#_absolutize_filepath" do
|
|
57
|
+
let(:path) { lolcat.send "_absolutize_filepath", @input }
|
|
58
|
+
let(:result) { path.should eq @expected }
|
|
59
|
+
context "standard usage" do
|
|
60
|
+
before :each do
|
|
61
|
+
@input = "dog"
|
|
62
|
+
@expected = File.join Dir.pwd, @input
|
|
63
|
+
end
|
|
64
|
+
it( "should give me an absolute path to the file regardless of existence") { result }
|
|
65
|
+
end
|
|
66
|
+
context "~" do
|
|
67
|
+
before :each do
|
|
68
|
+
@input = "~/dogfucker"
|
|
69
|
+
@expected = File.join File.expand_path("~"), "dogfucker"
|
|
70
|
+
end
|
|
71
|
+
it( "should expand the tilde to the absolute path") { result }
|
|
72
|
+
end
|
|
73
|
+
context "absolute path" do
|
|
74
|
+
before :each do
|
|
75
|
+
@input = "/home/shinka/something"
|
|
76
|
+
@expected = @input
|
|
77
|
+
end
|
|
78
|
+
it("should not touch the input if it is already absolute") { result }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
describe "#_reasonably_matched?" do
|
|
82
|
+
let(:match) { lambda { |s1, s2| lolcat.send "_reasonably_matched?", s1, s2 } }
|
|
83
|
+
context "true" do
|
|
84
|
+
before :each do
|
|
85
|
+
@expectations = {
|
|
86
|
+
"Dog::Cat::Bat" => "/dog/cat/bat",
|
|
87
|
+
"AssFuck::Shot" => "/ass_fuck/shot",
|
|
88
|
+
"Dicker::BatMan::Robin" => "apples/oranges/dicker/bat_man/robin",
|
|
89
|
+
"Snot" => "/asdf/asdf/asdf/ff/snot"
|
|
90
|
+
}
|
|
91
|
+
end
|
|
92
|
+
it "should be a reasonable match" do
|
|
93
|
+
@expectations.each { |key, val| match.call(key,val).should be_true }
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
context "false" do
|
|
97
|
+
before :each do
|
|
98
|
+
@expectations = {
|
|
99
|
+
"Dog::Cat::Bat" => "/fdasf/dog/cat/rat",
|
|
100
|
+
"" => "/anything/really" ,
|
|
101
|
+
"Dicker::AssMan" => "/fd/dicker/ass_man/something"
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
it "should not be reasonable matches" do
|
|
105
|
+
@expectations.each { |key,val| match.call(key,val).should_not be_true }
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
describe "#_get_flow_from_file" do
|
|
110
|
+
let(:flow) { lolcat.send "_get_flow_from_file", @file }
|
|
111
|
+
let(:expected) { Amazon::MadeiraFlow }
|
|
112
|
+
before :each do
|
|
113
|
+
@file = File.join RSpec::FixturePath, "amazon", "madeira_flow.rb"
|
|
114
|
+
require @file
|
|
115
|
+
end
|
|
116
|
+
context "standard usage" do
|
|
117
|
+
it "should find the flow class in question" do
|
|
118
|
+
flow.should eq expected
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
describe "#_get_task_from_file" do
|
|
122
|
+
let(:task) { lolcat.send("_get_task_from_file", @file) }
|
|
123
|
+
|
|
124
|
+
it "should be a lambda" do
|
|
125
|
+
task.should respond_to :call
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should run and give me the correct result" do
|
|
129
|
+
task.call.state.should eq "initialized123"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
describe "#_find_flow_helper_from_filepath" do
|
|
134
|
+
let(:path) { lolcat.send "_find_flow_helper_from_filepath", @starting }
|
|
135
|
+
context "null case" do
|
|
136
|
+
before :each do
|
|
137
|
+
@starting = File.expand_path __FILE__
|
|
138
|
+
end
|
|
139
|
+
it "should throw an symbol as it cannot find the flow helper" do
|
|
140
|
+
expect { path }.to throw_symbol :NoFlowHelperFound
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
context "dumb case" do
|
|
144
|
+
before :each do
|
|
145
|
+
@starting = File.join RSpec::FixturePath, "flow_helper.rb"
|
|
146
|
+
@expected = @starting
|
|
147
|
+
end
|
|
148
|
+
it "should find it right away" do
|
|
149
|
+
path.should eq @expected
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
context "standard usage" do
|
|
153
|
+
before :each do
|
|
154
|
+
@starting = File.join RSpec::FixturePath, "nile", "white_nile"
|
|
155
|
+
@expected = File.join RSpec::FixturePath, "flow_helper.rb"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should find the expected flow helper in the fixture folder" do
|
|
159
|
+
path.should eq @expected
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
describe "#_get_files_from_filepath" do
|
|
164
|
+
context "standard usage" do
|
|
165
|
+
let(:files) { lolcat.send( "_get_files_from_filepath", File.join(RSpec::FixturePath) ) }
|
|
166
|
+
before :each do
|
|
167
|
+
@expected = Dir[File.join(RSpec::FixturePath, "*_flow.rb")].map { |f| f }
|
|
168
|
+
@expected += Dir[File.join(RSpec::FixturePath,"**", "*_flow.rb")].map { |f| f }
|
|
169
|
+
@expected += Dir[File.join(RSpec::FixturePath,"**", "**", "*_flow.rb")].map { |f| f }
|
|
170
|
+
@expected.uniq!
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it "should fetch all the files that are flow rubies" do
|
|
174
|
+
files.sort.should eq @expected.sort
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
context "null usage" do
|
|
178
|
+
it "should out an empty array if the path doesn't exist" do
|
|
179
|
+
lolcat.send("_get_files_from_filepath", "nigstack").should be_empty
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|