openrain-scenarios 0.1.2 → 0.2.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.
- data/LICENSE +22 -0
- data/Rakefile +1 -1
- data/VERSION.yml +1 -1
- data/examples/additional_scenarios/load_me.rb +1 -0
- data/examples/additional_scenarios/load_me_too.rb +1 -0
- data/lib/scenarios/scenario.rb +138 -0
- data/lib/scenarios/spec.rb +43 -0
- data/lib/scenarios.rb +4 -139
- data/spec/scenario_spec.rb +1 -3
- data/spec/scenario_spec_spec.rb +37 -0
- data/spec/spec_helper.rb +4 -0
- metadata +9 -3
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009 OpenRain, LLC. All rights reserved.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
s.name = "scenarios"
|
10
10
|
s.summary = "Create, Organize, and Run arbitrary snippets of Ruby code"
|
11
11
|
s.email = "remi@remitaylor.com"
|
12
|
-
s.homepage = "http://github.com/
|
12
|
+
s.homepage = "http://github.com/openrain/scenarios"
|
13
13
|
s.description = "Create, Organize, and Run arbitrary snippets of Ruby code"
|
14
14
|
s.authors = %w( remi )
|
15
15
|
s.files = FileList["[A-Z]*", "{lib,spec,examples,rails_generators}/**/*"]
|
data/VERSION.yml
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
$set_by_load_me = 'I was set by load_me'
|
@@ -0,0 +1 @@
|
|
1
|
+
$set_by_load_me_too = 'I was set by load_me_too!'
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# a Scenario is some set of data/logic that can be loaded up easily
|
2
|
+
# to run an application against.
|
3
|
+
#
|
4
|
+
# if you need to enter abunchof data manually into the a website
|
5
|
+
# to test something you're working on, this is a good candidate for
|
6
|
+
# a scenario.
|
7
|
+
#
|
8
|
+
# we can also use scenarios for loading up the base foundation of
|
9
|
+
# data that's required to load the web application
|
10
|
+
#
|
11
|
+
# TODO define what is public/private and document public API in README and
|
12
|
+
# actually give private methods a private visibility
|
13
|
+
#
|
14
|
+
class Scenario
|
15
|
+
|
16
|
+
attr_accessor :file_path
|
17
|
+
|
18
|
+
def initialize file_path
|
19
|
+
@file_path = file_path
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
File.basename(file_path).sub(/\.rb$/, '')
|
24
|
+
end
|
25
|
+
alias to_s name
|
26
|
+
|
27
|
+
# if the first line of the scenario's source code
|
28
|
+
# is a comment, we use it as the scenario's description
|
29
|
+
#
|
30
|
+
# ideally, all scenarios should have a short simple description
|
31
|
+
#
|
32
|
+
def description
|
33
|
+
if first_line =~ /^#/
|
34
|
+
first_line.sub(/^#*/, '').strip
|
35
|
+
else
|
36
|
+
''
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def first_line
|
41
|
+
source_code.split("\n").first
|
42
|
+
end
|
43
|
+
|
44
|
+
def source_code
|
45
|
+
File.read file_path
|
46
|
+
end
|
47
|
+
|
48
|
+
# evaluates the code of the scenario
|
49
|
+
def load
|
50
|
+
self.class.load self # pass the loading off to the class
|
51
|
+
end
|
52
|
+
|
53
|
+
class << self
|
54
|
+
|
55
|
+
# an array of the paths where scenarios can be found
|
56
|
+
#
|
57
|
+
# any .rb file found in these directories is assumed to
|
58
|
+
# be a scenario
|
59
|
+
#
|
60
|
+
attr_accessor :load_paths, :verbose, :before_blocks
|
61
|
+
|
62
|
+
# returns all Scenarios found using Scenario#load_paths
|
63
|
+
def all
|
64
|
+
load_paths.inject([]) do |all_scenarios, load_path|
|
65
|
+
Dir[ File.join(load_path, '**', '*.rb') ].each do |found_scenario_file|
|
66
|
+
all_scenarios << Scenario.new(found_scenario_file)
|
67
|
+
end
|
68
|
+
all_scenarios
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def verbose= value
|
73
|
+
if value == true && @verbose != true
|
74
|
+
puts "Scenario verbose enable."
|
75
|
+
puts "Scenario load_paths => #{ Scenario.load_paths.inspect }"
|
76
|
+
puts "#{ Scenario.all.length } scenario(s) found"
|
77
|
+
end
|
78
|
+
@verbose = value
|
79
|
+
end
|
80
|
+
|
81
|
+
# run some block of code before any scenarios run
|
82
|
+
#
|
83
|
+
# good for last-minute require statements and whatnot
|
84
|
+
#
|
85
|
+
def before &block
|
86
|
+
@before_blocks ||= []
|
87
|
+
@before_blocks << block if block
|
88
|
+
end
|
89
|
+
|
90
|
+
# returns a scenario by name, eg. Scenario[:foo]
|
91
|
+
#
|
92
|
+
# if 1 name is passed in, we'll return that scenario or nil
|
93
|
+
#
|
94
|
+
# if more than 1 name is passed in, we'll return an array of
|
95
|
+
# scenarios (or an empty array)
|
96
|
+
#
|
97
|
+
def [] *names
|
98
|
+
puts "looking for scenario(s) with name(s): #{ names.inspect }" if Scenario.verbose
|
99
|
+
if names.length == 1
|
100
|
+
puts "all scenario names: #{ all.map(&:name) }" if Scenario.verbose
|
101
|
+
puts "btw, the load paths are: #{ load_paths.inspect }" if Scenario.verbose
|
102
|
+
all.find {|scenario| scenario.name.downcase == names.first.to_s.downcase }
|
103
|
+
else
|
104
|
+
names.map {|name| self[ name ] }.compact
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# loads a Scenario, evaluating its code
|
109
|
+
#
|
110
|
+
# we do this here so we can easily eval in a certain context,
|
111
|
+
# if we want to add a context later
|
112
|
+
#
|
113
|
+
# Scenario.load @scenario1, @scenario2
|
114
|
+
# Scenario.load :names, 'work', :too
|
115
|
+
#
|
116
|
+
def load *scenarios
|
117
|
+
puts "called Scenario.load with scenarios #{ scenarios.inspect }" if Scenario.verbose
|
118
|
+
@before_blocks.each { |b| b.call } if @before_blocks and not @before_blocks.empty?
|
119
|
+
# TODO should be able to define some block that scenarios get evaluated in!
|
120
|
+
# or some things that scenarios might want to require or ...
|
121
|
+
scenarios.each do |scenario|
|
122
|
+
scenario = self[scenario] unless scenario.is_a?Scenario # try getting using self[] if not a scenario
|
123
|
+
puts "loading #{ scenario.name } (#{ scenario.description })" if Scenario.verbose && scenario.is_a?(Scenario)
|
124
|
+
begin
|
125
|
+
if scenario.is_a?Scenario
|
126
|
+
puts "eval'ing scenario: #{ scenario.inspect }" if Scenario.verbose
|
127
|
+
eval scenario.source_code
|
128
|
+
else
|
129
|
+
puts "Unsure how to load scenario: #{ scenario.inspect }"
|
130
|
+
end
|
131
|
+
rescue => ex
|
132
|
+
raise "An Exception was thrown by scenario: #{ scenario.name }\n\n#{ ex }"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Scenario
|
2
|
+
|
3
|
+
# scenario helpers that can be used in your specs
|
4
|
+
#
|
5
|
+
# specifically, a #scenarios method for easily loading scenarios
|
6
|
+
#
|
7
|
+
module Spec
|
8
|
+
|
9
|
+
# scenarios to load in a spec
|
10
|
+
#
|
11
|
+
# scenario :foo
|
12
|
+
# scenarios :foo, :bar
|
13
|
+
# scenarios :foo, :bar, :before => :all
|
14
|
+
# scenarios :foo, :bar, :before => :each
|
15
|
+
#
|
16
|
+
# defaults to before each
|
17
|
+
#
|
18
|
+
# to use this in your own specs, in your spec_helper.rb
|
19
|
+
#
|
20
|
+
# require 'scenarios'
|
21
|
+
#
|
22
|
+
# Spec::Runner.configure do |config|
|
23
|
+
# include Scenario::Spec
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# is RSpec is loaded, we'll load up the Scenario::Spec for
|
27
|
+
# you automatically. if you need to manually load this:
|
28
|
+
#
|
29
|
+
# require 'scenarios/spec'
|
30
|
+
#
|
31
|
+
def scenario *scenarios
|
32
|
+
puts "Scenario::Spec::Helper.scenario #{ scenarios.inspect }" if Scenario.verbose
|
33
|
+
options = (scenarios.last.is_a?Hash) ? scenarios.pop : { }
|
34
|
+
options[:before] ||= :each
|
35
|
+
before options[:before] do
|
36
|
+
Scenario.load *scenarios
|
37
|
+
end
|
38
|
+
end
|
39
|
+
alias scenarios scenario
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/scenarios.rb
CHANGED
@@ -1,143 +1,8 @@
|
|
1
1
|
$:.unshift File.dirname(__FILE__)
|
2
2
|
|
3
|
-
|
4
|
-
# to run an application against.
|
5
|
-
#
|
6
|
-
# if you need to enter abunchof data manually into the a website
|
7
|
-
# to test something you're working on, this is a good candidate for
|
8
|
-
# a scenario.
|
9
|
-
#
|
10
|
-
# we can also use scenarios for loading up the base foundation of
|
11
|
-
# data that's required to load the web application
|
12
|
-
#
|
13
|
-
# TODO define what is public/private and document public API in README and
|
14
|
-
# actually give private methods a private visibility
|
15
|
-
#
|
16
|
-
class Scenario
|
3
|
+
require 'scenarios/scenario'
|
17
4
|
|
18
|
-
|
5
|
+
Scenario.load_paths ||= [ 'scenarios' ] # default to a 'scenarios' directory relative to your current location
|
6
|
+
Scenario.verbose = false
|
19
7
|
|
20
|
-
|
21
|
-
@file_path = file_path
|
22
|
-
end
|
23
|
-
|
24
|
-
def name
|
25
|
-
File.basename(file_path).sub(/\.rb$/, '')
|
26
|
-
end
|
27
|
-
alias to_s name
|
28
|
-
|
29
|
-
# if the first line of the scenario's source code
|
30
|
-
# is a comment, we use it as the scenario's description
|
31
|
-
#
|
32
|
-
# ideally, all scenarios should have a short simple description
|
33
|
-
#
|
34
|
-
def description
|
35
|
-
if first_line =~ /^#/
|
36
|
-
first_line.sub(/^#*/, '').strip
|
37
|
-
else
|
38
|
-
''
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def first_line
|
43
|
-
source_code.split("\n").first
|
44
|
-
end
|
45
|
-
|
46
|
-
def source_code
|
47
|
-
File.read file_path
|
48
|
-
end
|
49
|
-
|
50
|
-
# evaluates the code of the scenario
|
51
|
-
def load
|
52
|
-
self.class.load self # pass the loading off to the class
|
53
|
-
end
|
54
|
-
|
55
|
-
class << self
|
56
|
-
|
57
|
-
# an array of the paths where scenarios can be found
|
58
|
-
#
|
59
|
-
# any .rb file found in these directories is assumed to
|
60
|
-
# be a scenario
|
61
|
-
#
|
62
|
-
attr_accessor :load_paths, :verbose, :before_blocks
|
63
|
-
|
64
|
-
# returns all Scenarios found using Scenario#load_paths
|
65
|
-
def all
|
66
|
-
load_paths.inject([]) do |all_scenarios, load_path|
|
67
|
-
Dir[ File.join(load_path, '**', '*.rb') ].each do |found_scenario_file|
|
68
|
-
all_scenarios << Scenario.new(found_scenario_file)
|
69
|
-
end
|
70
|
-
all_scenarios
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def verbose= value
|
75
|
-
if value == true && @verbose != true
|
76
|
-
puts "Scenario verbose enable."
|
77
|
-
puts "Scenario load_paths => #{ Scenario.load_paths.inspect }"
|
78
|
-
puts "#{ Scenario.all.length } scenario(s) found"
|
79
|
-
end
|
80
|
-
@verbose = value
|
81
|
-
end
|
82
|
-
|
83
|
-
# run some block of code before any scenarios run
|
84
|
-
#
|
85
|
-
# good for last-minute require statements and whatnot
|
86
|
-
#
|
87
|
-
def before &block
|
88
|
-
@before_blocks ||= []
|
89
|
-
@before_blocks << block if block
|
90
|
-
end
|
91
|
-
|
92
|
-
# returns a scenario by name, eg. Scenario[:foo]
|
93
|
-
#
|
94
|
-
# if 1 name is passed in, we'll return that scenario or nil
|
95
|
-
#
|
96
|
-
# if more than 1 name is passed in, we'll return an array of
|
97
|
-
# scenarios (or an empty array)
|
98
|
-
#
|
99
|
-
def [] *names
|
100
|
-
puts "looking for scenario(s) with name(s): #{ names.inspect }" if Scenario.verbose
|
101
|
-
if names.length == 1
|
102
|
-
puts "all scenario names: #{ all.map(&:name) }" if Scenario.verbose
|
103
|
-
puts "btw, the load paths are: #{ load_paths.inspect }" if Scenario.verbose
|
104
|
-
all.find {|scenario| scenario.name.downcase == names.first.to_s.downcase }
|
105
|
-
else
|
106
|
-
names.map {|name| self[ name ] }.compact
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# loads a Scenario, evaluating its code
|
111
|
-
#
|
112
|
-
# we do this here so we can easily eval in a certain context,
|
113
|
-
# if we want to add a context later
|
114
|
-
#
|
115
|
-
# Scenario.load @scenario1, @scenario2
|
116
|
-
# Scenario.load :names, 'work', :too
|
117
|
-
#
|
118
|
-
def load *scenarios
|
119
|
-
puts "called Scenario.load with scenarios #{ scenarios.inspect }" if Scenario.verbose
|
120
|
-
@before_blocks.each { |b| b.call } if @before_blocks and not @before_blocks.empty?
|
121
|
-
# TODO should be able to define some block that scenarios get evaluated in!
|
122
|
-
# or some things that scenarios might want to require or ...
|
123
|
-
scenarios.each do |scenario|
|
124
|
-
scenario = self[scenario] unless scenario.is_a?Scenario # try getting using self[] if not a scenario
|
125
|
-
puts "loading #{ scenario.name } (#{ scenario.description })" if Scenario.verbose && scenario.is_a?(Scenario)
|
126
|
-
begin
|
127
|
-
if scenario.is_a?Scenario
|
128
|
-
puts "eval'ing scenario: #{ scenario.inspect }" if Scenario.verbose
|
129
|
-
eval scenario.source_code
|
130
|
-
else
|
131
|
-
puts "Unsure how to load scenario: #{ scenario.inspect }"
|
132
|
-
end
|
133
|
-
rescue => ex
|
134
|
-
raise "An Exception was thrown by scenario: #{ scenario.name }\n\n#{ ex }"
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
Scenario.load_paths ||= [ 'scenarios' ] # default to a 'scenarios' directory relative to your current location
|
141
|
-
Scenario.verbose = false
|
142
|
-
|
143
|
-
end
|
8
|
+
require 'scenarios/spec' if defined? Spec
|
data/spec/scenario_spec.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
2
|
|
3
|
-
# this isn't exactly a model ... just something that helps
|
4
|
-
# with out development and speccing
|
5
3
|
describe Scenario do
|
6
4
|
|
7
5
|
def path_to_test_scenarios
|
@@ -104,7 +102,7 @@ describe Scenario do
|
|
104
102
|
it 'should allow globbing in load_paths' do
|
105
103
|
Scenario.load_paths = [ File.join(File.dirname(__FILE__), '..', 'examp*', '**') ]
|
106
104
|
|
107
|
-
Scenario.all.length.should ==
|
105
|
+
Scenario.all.length.should == 4
|
108
106
|
Scenario.all.map(&:name).should include('first')
|
109
107
|
Scenario.all.map(&:name).should include('foo')
|
110
108
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Scenario::Spec do
|
4
|
+
|
5
|
+
def path_to_test_scenarios
|
6
|
+
File.join File.dirname(__FILE__), '..', 'examples', 'scenarios'
|
7
|
+
end
|
8
|
+
def path_to_additional_scenarios
|
9
|
+
File.join File.dirname(__FILE__), '..', 'examples', 'additional_scenarios'
|
10
|
+
end
|
11
|
+
|
12
|
+
before :all do
|
13
|
+
$set_by_load_me.should be_nil
|
14
|
+
$set_by_load_me_too.should be_nil
|
15
|
+
@original_scenario_paths = Scenario.load_paths
|
16
|
+
end
|
17
|
+
after :all do
|
18
|
+
Scenario.load_paths = @original_scenario_paths
|
19
|
+
end
|
20
|
+
|
21
|
+
scenarios :load_me, :load_me_too # <---- this is what we're testing here
|
22
|
+
# see spec_helper.rb for how to
|
23
|
+
# add this method to your app!
|
24
|
+
|
25
|
+
it 'should have the scenarios we want to try running' do
|
26
|
+
Scenario.load_paths = [ path_to_additional_scenarios ]
|
27
|
+
Scenario.all.length.should == 2
|
28
|
+
Scenario.all.map(&:name).should include('load_me')
|
29
|
+
Scenario.all.map(&:name).should include('load_me_too')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should actually load the scenarios ok' do
|
33
|
+
$set_by_load_me.should == 'I was set by load_me'
|
34
|
+
$set_by_load_me_too.should == 'I was set by load_me_too!'
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openrain-scenarios
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- remi
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-02-
|
12
|
+
date: 2009-02-06 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -22,17 +22,23 @@ extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
24
|
files:
|
25
|
-
- MIT-LICENSE
|
26
25
|
- Rakefile
|
27
26
|
- VERSION.yml
|
28
27
|
- README.markdown
|
28
|
+
- LICENSE
|
29
29
|
- lib/scenarios
|
30
|
+
- lib/scenarios/spec.rb
|
31
|
+
- lib/scenarios/scenario.rb
|
30
32
|
- lib/scenarios/tasks.rb
|
31
33
|
- lib/scenarios.rb
|
32
34
|
- spec/scenario_spec.rb
|
33
35
|
- spec/spec_helper.rb
|
36
|
+
- spec/scenario_spec_spec.rb
|
34
37
|
- examples/scenarios
|
35
38
|
- examples/scenarios/first.rb
|
39
|
+
- examples/additional_scenarios
|
40
|
+
- examples/additional_scenarios/load_me_too.rb
|
41
|
+
- examples/additional_scenarios/load_me.rb
|
36
42
|
- examples/more_scenarios
|
37
43
|
- examples/more_scenarios/foo.rb
|
38
44
|
- rails_generators/scenario
|