cascadence 0.2.3 → 0.2.4

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.
@@ -3,74 +3,20 @@ module Cascadence
3
3
 
4
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
5
  def version
6
- puts "El Psy Congroo"
6
+ Cascadence::Commander::Version.instance.run
7
7
  end
8
8
 
9
9
  desc "flow [FILEPATH]", "Runs the flow specified in the given file. If given a directory, runs all the flows in the directory."
10
10
  def flow(filepath=Dir.pwd)
11
- abs_file_path = _absolutize_filepath filepath
12
- files = _get_files_from_filepath abs_file_path
13
- _setup_environment_from_filepath!(_absolutize_filepath filepath)
14
- tasks = files.map { |file| _get_task_from_file file }
15
- _run_tasks tasks
11
+ Cascadence::Commander::Flow.instance.run(filepath)
16
12
  end
17
13
 
18
- private
19
-
20
- def _run_tasks(tasks)
21
- Cascadence.runner.run_tasks tasks
22
- end
23
-
24
- def _absolutize_filepath(filepath)
25
- return filepath if filepath =~ /^\//
26
- return File.expand_path(filepath) if filepath =~ /^~/
27
- return File.join(Dir.pwd, filepath)
28
- end
29
-
30
- def _get_files_from_filepath(filepath)
31
- return [filepath] if _flow_file? filepath
32
- return [] unless File.exists? filepath
33
- Dir[File.join(filepath, "*")].map { |file_or_dir| _get_files_from_filepath file_or_dir }.flatten
34
- end
35
-
36
- def _flow_file?(filepath)
37
- (filepath =~ /_flow\.rb$/) && File.file?(filepath)
38
- end
39
-
40
- def _setup_environment_from_filepath!(filepath)
41
- require _find_flow_helper_from_filepath filepath
42
- end
43
-
44
- def _find_flow_helper_from_filepath( filepath )
45
- _find_flow_helper_from_filepath File.expand_path("..", filepath) unless File.directory? filepath
46
- throw :NoFlowHelperFound if filepath == "/"
47
- Dir[File.join(filepath, "*")].select { |file| _flow_helper? file }.first || _find_flow_helper_from_filepath( File.expand_path("..", filepath) )
48
- end
49
-
50
- def _flow_helper?(filepath)
51
- (filepath =~ /\/flow_helper\.rb$/) && File.file?(filepath)
52
- end
53
-
54
- def _get_task_from_file(file)
55
- flow = _get_flow_from_file file
56
- Cascadence::Task.new(_get_zero_state_generator_from_flow flow) do |state=nil|
57
- flow.new(state).run_states
58
- end
59
- end
60
-
61
- def _get_zero_state_generator_from_flow(flow)
62
- return flow.zero_state_generator if flow.respond_to? :zero_state_generator
63
- return Cascadence.config.zero_state_generator if flow == Object || !flow.respond_to?(:parent)
64
- _get_zero_state_generator_from_flow(flow.parent)
65
- end
66
-
67
- def _get_flow_from_file(file)
68
- Cascadence::Flow.subclasses.select { |subclass| _reasonably_matched?(subclass.to_s, file.chomp(".rb")) }.first
69
- end
70
-
71
- def _reasonably_matched?(str1, str2)
72
- !(str2.to_s.gsub(/^\/?/, "/") =~ Regexp.new("\/" + str1.to_s.split("::").map(&:underscore).join("/") + "$")).nil?
14
+ desc "generate [FLOWNAME]", "generates the flow project as specified by the name with respect to your current directory."
15
+ def generate(flowname)
16
+ Cascadence::Commander::Generate.start ["dosomeshit", flowname, Dir.pwd]
73
17
  end
74
18
 
75
19
  end
76
- end
20
+ end
21
+
22
+ Dir[File.join(File.dirname(__FILE__), "commander", "*.rb")].each { |f| require f }
@@ -0,0 +1,74 @@
1
+ module Cascadence
2
+ class Commander
3
+ class Flow
4
+ include Singleton
5
+
6
+ def run(filepath)
7
+ abs_file_path = _absolutize_filepath filepath
8
+ files = _get_files_from_filepath abs_file_path
9
+ _setup_environment_from_filepath!(_absolutize_filepath filepath)
10
+ tasks = files.map { |file| _get_task_from_file file }
11
+ _run_tasks tasks
12
+ end
13
+
14
+ private
15
+
16
+ def _run_tasks(tasks)
17
+ Cascadence.runner.run_tasks tasks
18
+ end
19
+
20
+ def _absolutize_filepath(filepath)
21
+ return filepath if filepath =~ /^\//
22
+ return File.expand_path(filepath) if filepath =~ /^~/
23
+ return File.join(Dir.pwd, filepath)
24
+ end
25
+
26
+ def _get_files_from_filepath(filepath)
27
+ return [filepath] if _flow_file? filepath
28
+ return [] unless File.exists? filepath
29
+ Dir[File.join(filepath, "*")].map { |file_or_dir| _get_files_from_filepath file_or_dir }.flatten
30
+ end
31
+
32
+ def _flow_file?(filepath)
33
+ (filepath =~ /_flow\.rb$/) && File.file?(filepath)
34
+ end
35
+
36
+ def _setup_environment_from_filepath!(filepath)
37
+ require _find_flow_helper_from_filepath filepath
38
+ end
39
+
40
+ def _find_flow_helper_from_filepath( filepath )
41
+ _find_flow_helper_from_filepath File.expand_path("..", filepath) unless File.directory? filepath
42
+ throw :NoFlowHelperFound if filepath == "/"
43
+ Dir[File.join(filepath, "*")].select { |file| _flow_helper? file }.first || _find_flow_helper_from_filepath( File.expand_path("..", filepath) )
44
+ end
45
+
46
+ def _flow_helper?(filepath)
47
+ (filepath =~ /\/flow_helper\.rb$/) && File.file?(filepath)
48
+ end
49
+
50
+ def _get_task_from_file(file)
51
+ flow = _get_flow_from_file file
52
+ throw "Bad flow from #{file}. Available flows: #{Cascadence::Flow.subclasses.to_s}" if flow.nil?
53
+ Cascadence::Task.new(_get_zero_state_generator_from_flow flow) do |state=nil|
54
+ flow.new(state).run_states
55
+ end
56
+ end
57
+
58
+ def _get_zero_state_generator_from_flow(flow)
59
+ return flow.zero_state_generator if flow.respond_to? :zero_state_generator
60
+ return Cascadence.config.zero_state_generator if flow == Object || !flow.respond_to?(:parent)
61
+ _get_zero_state_generator_from_flow(flow.parent)
62
+ end
63
+
64
+ def _get_flow_from_file(file)
65
+ Cascadence::Flow.subclasses.select { |subclass| _reasonably_matched?(subclass.to_s, file.chomp(".rb")) }.first
66
+ end
67
+
68
+ def _reasonably_matched?(str1, str2)
69
+ !(str2.to_s.gsub(/^\/?/, "/") =~ Regexp.new("\/" + str1.to_s.split("::").map(&:underscore).join("/") + "$")).nil?
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,35 @@
1
+ module Cascadence
2
+ class Commander
3
+ class Generate < Thor
4
+ include Singleton
5
+ include Thor::Actions
6
+ attr_accessor :project_name, :project_dir
7
+
8
+ desc "dosomeshit [FLOWNAME] [PROJECTDIR]", "Generates a project name."
9
+ def dosomeshit(flowname, project_dir=Dir.pwd)
10
+ _setup_instance_variables!(flowname, project_dir)
11
+ directory _get_source_path, _get_destination
12
+ end
13
+
14
+ def self.source_root
15
+ File.expand_path("../../templates", __FILE__)
16
+ end
17
+
18
+ private
19
+
20
+ def _setup_instance_variables!(flowname, project_dir)
21
+ @project_name = flowname
22
+ @project_dir = project_dir
23
+ end
24
+
25
+ def _get_source_path
26
+ self.class.source_root
27
+ end
28
+
29
+ def _get_destination
30
+ File.join(project_dir, project_name, "flows")
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ module Cascadence
2
+ class Commander
3
+ class Version
4
+ include Singleton
5
+
6
+ def run
7
+ File.read File.expand_path("../../../../VERSION", __FILE__)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ require File.join(File.dirname(__FILE__), "<%= project_name.underscore %>", "base_flow")
2
+ module <%= project_name.camelcase %>
3
+ def self.zero_state_generator
4
+ throw :ImplementOrDeleteMe
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ module <%= project_name.camelcase %>
2
+ class BaseFlow < ::Cascadence::Flow
3
+
4
+ def initialize(state)
5
+ throw :NotImplementedError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ require "capybara"
2
+ Dir[File.expand_path("../*.rb", __FILE__)].each { |f| require f }
3
+
4
+ Cascadence.config do |config|
5
+ # Cascadence supports parallelism when running your flows.
6
+ # Each file that ends with _flow.rb will be treated as an
7
+ # individual flow that you want cascadence to run. It is
8
+ # highly recommended that you set max_thread_count to a
9
+ # reasonably small number since running firefox instances
10
+ # tend to be fairly expensive
11
+ config.parallel = false
12
+ config.max_thread_count = 4
13
+
14
+ # The zero_state_generator creates the initial state used
15
+ # by your flows. Global configs here is just the default
16
+ # generator used in the event specific generators are not
17
+ # provided in the individual flows.
18
+ config.zero_state_generator = lambda { Capybara::Session.new :selenium }
19
+ end
@@ -0,0 +1,175 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cascadence::Commander::Flow do
4
+ let(:lolcat) { Cascadence::Commander::Flow.instance }
5
+ context "private" do
6
+ describe "#_get_zero_state_generator_from_flow" do
7
+ module GetZero
8
+ def self.zero_state_generator
9
+ lambda { "get_zero" }
10
+ end
11
+ class Fagbar < Cascadence::Flow
12
+ class HeyzapFlow < ::Cascadence::Flow
13
+ class CrossFlow
14
+ class WeHaveToGoDeeper
15
+ def self.zero_state_generator
16
+ lambda { "we_have_to_go_deeper" }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ it "should properly give me parents where applicable" do
24
+ GetZero::Fagbar::HeyzapFlow::CrossFlow::WeHaveToGoDeeper.parent.should eq GetZero::Fagbar::HeyzapFlow::CrossFlow
25
+ end
26
+ it "should give me nil for the outer level" do
27
+ GetZero.parent.should == Object
28
+ end
29
+ let(:result) { lolcat.send "_get_zero_state_generator_from_flow", @flow }
30
+ context "warpspeed" do
31
+ before :each do
32
+ @flow = GetZero::Fagbar::HeyzapFlow::CrossFlow
33
+ end
34
+ it "should get me the first zero_state_generator" do
35
+ result.call.should eq "get_zero"
36
+ end
37
+ end
38
+ context "inception" do
39
+ before :each do
40
+ @flow = GetZero::Fagbar::HeyzapFlow::CrossFlow::WeHaveToGoDeeper
41
+ end
42
+ it "should get the closest zero state generator" do
43
+ result.call.should eq "we_have_to_go_deeper"
44
+ end
45
+ end
46
+ end
47
+ describe "#_absolutize_filepath" do
48
+ let(:path) { lolcat.send "_absolutize_filepath", @input }
49
+ let(:result) { path.should eq @expected }
50
+ context "standard usage" do
51
+ before :each do
52
+ @input = "dog"
53
+ @expected = File.join Dir.pwd, @input
54
+ end
55
+ it( "should give me an absolute path to the file regardless of existence") { result }
56
+ end
57
+ context "~" do
58
+ before :each do
59
+ @input = "~/dogfucker"
60
+ @expected = File.join File.expand_path("~"), "dogfucker"
61
+ end
62
+ it( "should expand the tilde to the absolute path") { result }
63
+ end
64
+ context "absolute path" do
65
+ before :each do
66
+ @input = "/home/shinka/something"
67
+ @expected = @input
68
+ end
69
+ it("should not touch the input if it is already absolute") { result }
70
+ end
71
+ end
72
+ describe "#_reasonably_matched?" do
73
+ let(:match) { lambda { |s1, s2| lolcat.send "_reasonably_matched?", s1, s2 } }
74
+ context "true" do
75
+ before :each do
76
+ @expectations = {
77
+ "Dog::Cat::Bat" => "/dog/cat/bat",
78
+ "AssFuck::Shot" => "/ass_fuck/shot",
79
+ "Dicker::BatMan::Robin" => "apples/oranges/dicker/bat_man/robin",
80
+ "Snot" => "/asdf/asdf/asdf/ff/snot"
81
+ }
82
+ end
83
+ it "should be a reasonable match" do
84
+ @expectations.each { |key, val| match.call(key,val).should be_true }
85
+ end
86
+ end
87
+ context "false" do
88
+ before :each do
89
+ @expectations = {
90
+ "Dog::Cat::Bat" => "/fdasf/dog/cat/rat",
91
+ "" => "/anything/really" ,
92
+ "Dicker::AssMan" => "/fd/dicker/ass_man/something"
93
+ }
94
+ end
95
+ it "should not be reasonable matches" do
96
+ @expectations.each { |key,val| match.call(key,val).should_not be_true }
97
+ end
98
+ end
99
+ end
100
+ describe "#_get_flow_from_file" do
101
+ let(:flow) { lolcat.send "_get_flow_from_file", @file }
102
+ let(:expected) { Amazon::MadeiraFlow }
103
+ before :each do
104
+ @file = File.join RSpec::FixturePath, "amazon", "madeira_flow.rb"
105
+ require @file
106
+ end
107
+ context "standard usage" do
108
+ it "should find the flow class in question" do
109
+ flow.should eq expected
110
+ end
111
+ end
112
+ describe "#_get_task_from_file" do
113
+ let(:task) { lolcat.send("_get_task_from_file", @file) }
114
+
115
+ it "should be a lambda" do
116
+ task.should respond_to :call
117
+ end
118
+
119
+ it "should run and give me the correct result" do
120
+ task.call.state.should eq "initialized123"
121
+ end
122
+ end
123
+ end
124
+ describe "#_find_flow_helper_from_filepath" do
125
+ let(:path) { lolcat.send "_find_flow_helper_from_filepath", @starting }
126
+ context "null case" do
127
+ before :each do
128
+ @starting = File.expand_path __FILE__
129
+ end
130
+ it "should throw an symbol as it cannot find the flow helper" do
131
+ expect { path }.to throw_symbol :NoFlowHelperFound
132
+ end
133
+ end
134
+ context "dumb case" do
135
+ before :each do
136
+ @starting = File.join RSpec::FixturePath, "flow_helper.rb"
137
+ @expected = @starting
138
+ end
139
+ it "should find it right away" do
140
+ path.should eq @expected
141
+ end
142
+ end
143
+ context "standard usage" do
144
+ before :each do
145
+ @starting = File.join RSpec::FixturePath, "nile", "white_nile"
146
+ @expected = File.join RSpec::FixturePath, "flow_helper.rb"
147
+ end
148
+
149
+ it "should find the expected flow helper in the fixture folder" do
150
+ path.should eq @expected
151
+ end
152
+ end
153
+ end
154
+ describe "#_get_files_from_filepath" do
155
+ context "standard usage" do
156
+ let(:files) { lolcat.send( "_get_files_from_filepath", File.join(RSpec::FixturePath) ) }
157
+ before :each do
158
+ @expected = Dir[File.join(RSpec::FixturePath, "*_flow.rb")].map { |f| f }
159
+ @expected += Dir[File.join(RSpec::FixturePath,"**", "*_flow.rb")].map { |f| f }
160
+ @expected += Dir[File.join(RSpec::FixturePath,"**", "**", "*_flow.rb")].map { |f| f }
161
+ @expected.uniq!
162
+ end
163
+
164
+ it "should fetch all the files that are flow rubies" do
165
+ files.sort.should eq @expected.sort
166
+ end
167
+ end
168
+ context "null usage" do
169
+ it "should out an empty array if the path doesn't exist" do
170
+ lolcat.send("_get_files_from_filepath", "nigstack").should be_empty
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe Cascadence::Commander::Generate do
4
+ let(:api) { Cascadence::Commander::Generate }
5
+ context "public" do
6
+ describe "#dosomeshit" do
7
+ let(:pubic) { api.start ["dosomeshit", @project_name, RSpec::RootPath] }
8
+ before :each do
9
+ @project_name = "tmp_shit"
10
+ @directory = File.join RSpec::RootPath, @project_name
11
+ FileUtils.rm_r @directory if Dir.exists? @directory
12
+ end
13
+ it "should create the new folder with all the sorts of crap in there" do
14
+ Dir.exists?(@directory).should_not be_true
15
+ pubic
16
+ Dir.exists?(@directory).should be_true
17
+ end
18
+ after :each do
19
+ FileUtils.rm_r @directory if Dir.exists? @directory
20
+ end
21
+ end
22
+ end
23
+ context "private" do
24
+ describe "#_setup_instance_variables!" do
25
+
26
+ end
27
+ describe "#_get_source_path" do
28
+
29
+ end
30
+ describe "#_get_destination" do
31
+
32
+ end
33
+ end
34
+
35
+ end