features 0.1.4 → 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.
Potentially problematic release.
This version of features might be problematic. Click here for more details.
- data/Manifest +59 -0
- data/README.markdown +31 -1
- data/Rakefile +1 -1
- data/features.gemspec +3 -3
- data/generators/features/templates/run_features.rb +27 -0
- data/lib/ObjC/objc_feature.rb +4 -27
- data/lib/ObjC/objc_scenario.rb +1 -58
- data/lib/ObjC/objc_step.rb +0 -31
- data/lib/ObjC/objc_suite.rb +14 -122
- data/lib/Rails/rails_feature.rb +7 -30
- data/lib/Rails/rails_scenario.rb +0 -57
- data/lib/Rails/rails_step.rb +1 -30
- data/lib/Rails/rails_suite.rb +16 -132
- data/lib/feature.rb +29 -1
- data/lib/scenario.rb +99 -0
- data/lib/step.rb +28 -0
- data/lib/suite.rb +124 -0
- data/website/README +10 -0
- data/website/Rakefile +44 -0
- data/website/config.yaml +18 -0
- data/website/deploy.rb +29 -0
- data/website/deploy/1251795725/features/browserfix.css +7 -0
- data/website/deploy/1251795725/features/default.css +257 -0
- data/website/deploy/1251795725/features/images/bodybg.gif +0 -0
- data/website/deploy/1251795725/features/images/header-bg.gif +0 -0
- data/website/deploy/1251795725/features/images/logo.png +0 -0
- data/website/deploy/1251795725/features/images/minus.png +0 -0
- data/website/deploy/1251795725/features/images/plus.png +0 -0
- data/website/deploy/1251795725/features/images/sidebarbg.gif +0 -0
- data/website/deploy/1251795725/features/index.html +229 -0
- data/website/deploy/1251796894/features/browserfix.css +7 -0
- data/website/deploy/1251796894/features/default.css +257 -0
- data/website/deploy/1251796894/features/images/bodybg.gif +0 -0
- data/website/deploy/1251796894/features/images/header-bg.gif +0 -0
- data/website/deploy/1251796894/features/images/logo.png +0 -0
- data/website/deploy/1251796894/features/images/minus.png +0 -0
- data/website/deploy/1251796894/features/images/output-screen-1.png +0 -0
- data/website/deploy/1251796894/features/images/plus.png +0 -0
- data/website/deploy/1251796894/features/images/sidebarbg.gif +0 -0
- data/website/deploy/1251796894/features/index.html +229 -0
- data/website/deploy/1251822430/features/browserfix.css +7 -0
- data/website/deploy/1251822430/features/default.css +257 -0
- data/website/deploy/1251822430/features/images/bodybg.gif +0 -0
- data/website/deploy/1251822430/features/images/header-bg.gif +0 -0
- data/website/deploy/1251822430/features/images/logo.png +0 -0
- data/website/deploy/1251822430/features/images/minus.png +0 -0
- data/website/deploy/1251822430/features/images/output-screen-1.png +0 -0
- data/website/deploy/1251822430/features/images/plus.png +0 -0
- data/website/deploy/1251822430/features/images/sidebarbg.gif +0 -0
- data/website/deploy/1251822430/features/index.html +229 -0
- data/website/ext/init.rb +10 -0
- data/website/out/browserfix.css +7 -0
- data/website/out/default.css +257 -0
- data/website/out/images/bodybg.gif +0 -0
- data/website/out/images/header-bg.gif +0 -0
- data/website/out/images/logo.png +0 -0
- data/website/out/images/minus.png +0 -0
- data/website/out/images/output-screen-1.png +0 -0
- data/website/out/images/plus.png +0 -0
- data/website/out/images/sidebarbg.gif +0 -0
- data/website/out/index.html +229 -0
- data/website/src/browserfix.css +7 -0
- data/website/src/default.css +257 -0
- data/website/src/default.template +92 -0
- data/website/src/images/bodybg.gif +0 -0
- data/website/src/images/deploy.rb +29 -0
- data/website/src/images/header-bg.gif +0 -0
- data/website/src/images/logo.png +0 -0
- data/website/src/images/minus.png +0 -0
- data/website/src/images/output-screen-1.png +0 -0
- data/website/src/images/plus.png +0 -0
- data/website/src/images/sidebarbg.gif +0 -0
- data/website/src/images/webgen.rb +3 -0
- data/website/src/index.page +139 -0
- data/website/webgen.cache +0 -0
- data/website/webgen.rb +3 -0
- metadata +61 -2
data/Manifest
CHANGED
@@ -26,3 +26,62 @@ lib/scenario.rb
|
|
26
26
|
lib/step.rb
|
27
27
|
lib/string_extension.rb
|
28
28
|
lib/suite.rb
|
29
|
+
website/README
|
30
|
+
website/Rakefile
|
31
|
+
website/config.yaml
|
32
|
+
website/deploy.rb
|
33
|
+
website/deploy/1251795725/features/browserfix.css
|
34
|
+
website/deploy/1251795725/features/default.css
|
35
|
+
website/deploy/1251795725/features/images/bodybg.gif
|
36
|
+
website/deploy/1251795725/features/images/header-bg.gif
|
37
|
+
website/deploy/1251795725/features/images/logo.png
|
38
|
+
website/deploy/1251795725/features/images/minus.png
|
39
|
+
website/deploy/1251795725/features/images/plus.png
|
40
|
+
website/deploy/1251795725/features/images/sidebarbg.gif
|
41
|
+
website/deploy/1251795725/features/index.html
|
42
|
+
website/deploy/1251796894/features/browserfix.css
|
43
|
+
website/deploy/1251796894/features/default.css
|
44
|
+
website/deploy/1251796894/features/images/bodybg.gif
|
45
|
+
website/deploy/1251796894/features/images/header-bg.gif
|
46
|
+
website/deploy/1251796894/features/images/logo.png
|
47
|
+
website/deploy/1251796894/features/images/minus.png
|
48
|
+
website/deploy/1251796894/features/images/output-screen-1.png
|
49
|
+
website/deploy/1251796894/features/images/plus.png
|
50
|
+
website/deploy/1251796894/features/images/sidebarbg.gif
|
51
|
+
website/deploy/1251796894/features/index.html
|
52
|
+
website/deploy/1251822430/features/browserfix.css
|
53
|
+
website/deploy/1251822430/features/default.css
|
54
|
+
website/deploy/1251822430/features/images/bodybg.gif
|
55
|
+
website/deploy/1251822430/features/images/header-bg.gif
|
56
|
+
website/deploy/1251822430/features/images/logo.png
|
57
|
+
website/deploy/1251822430/features/images/minus.png
|
58
|
+
website/deploy/1251822430/features/images/output-screen-1.png
|
59
|
+
website/deploy/1251822430/features/images/plus.png
|
60
|
+
website/deploy/1251822430/features/images/sidebarbg.gif
|
61
|
+
website/deploy/1251822430/features/index.html
|
62
|
+
website/ext/init.rb
|
63
|
+
website/out/browserfix.css
|
64
|
+
website/out/default.css
|
65
|
+
website/out/images/bodybg.gif
|
66
|
+
website/out/images/header-bg.gif
|
67
|
+
website/out/images/logo.png
|
68
|
+
website/out/images/minus.png
|
69
|
+
website/out/images/output-screen-1.png
|
70
|
+
website/out/images/plus.png
|
71
|
+
website/out/images/sidebarbg.gif
|
72
|
+
website/out/index.html
|
73
|
+
website/src/browserfix.css
|
74
|
+
website/src/default.css
|
75
|
+
website/src/default.template
|
76
|
+
website/src/images/bodybg.gif
|
77
|
+
website/src/images/deploy.rb
|
78
|
+
website/src/images/header-bg.gif
|
79
|
+
website/src/images/logo.png
|
80
|
+
website/src/images/minus.png
|
81
|
+
website/src/images/output-screen-1.png
|
82
|
+
website/src/images/plus.png
|
83
|
+
website/src/images/sidebarbg.gif
|
84
|
+
website/src/images/webgen.rb
|
85
|
+
website/src/index.page
|
86
|
+
website/webgen.cache
|
87
|
+
website/webgen.rb
|
data/README.markdown
CHANGED
@@ -87,7 +87,7 @@ will look like in the different languages:
|
|
87
87
|
}
|
88
88
|
@end
|
89
89
|
|
90
|
-
* Other Languages (Java, C#, C++, Python) will follow soon ...
|
90
|
+
* Other Languages (Java, C#, C++, Python, PHP) will follow soon ...
|
91
91
|
|
92
92
|
|
93
93
|
### Provide Step Implementations
|
@@ -97,6 +97,36 @@ that inherits from the language specific TestCase class (eg 'ActionController::I
|
|
97
97
|
and that itself is the parent of the generated TestCases. This way, all test method implementations (aka Scenarios)
|
98
98
|
will have access to the steps.
|
99
99
|
|
100
|
+
The implementation follows the some patterns :
|
101
|
+
|
102
|
+
* Only use characters that may appear in method and class definitions.
|
103
|
+
* Spaces in the step definition map to underscores in the implementation:
|
104
|
+
|
105
|
+
(Rails) Given something => given_Something
|
106
|
+
(ObjC) Given something => Given_Something
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
* Place Holders for variable strings (that can be passed to the step implementation) are
|
111
|
+
identified by double underscores (plus underscores for spaces) in the step implementation and strings are single quoted
|
112
|
+
in the step definition:
|
113
|
+
|
114
|
+
# Step definition
|
115
|
+
When i say 'Hello, World!'
|
116
|
+
|
117
|
+
# Rails Step implementation
|
118
|
+
def when_i_say___(string)
|
119
|
+
# do something
|
120
|
+
end
|
121
|
+
|
122
|
+
# ObjectiveC Step implementation
|
123
|
+
-(void) When_i_say___:(NSString *) string
|
124
|
+
{
|
125
|
+
// do something
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
|
100
130
|
## Installation
|
101
131
|
|
102
132
|
gem install features
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('features', '0.
|
5
|
+
Echoe.new('features', '0.2.0') do |p|
|
6
6
|
p.description = "Plaintext User Stories Parser supporting native programming languages."
|
7
7
|
p.url = "http://features.rubyforge.org"
|
8
8
|
p.author = "Matthias Hennemeyer"
|
data/features.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{features}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Matthias Hennemeyer"]
|
9
|
-
s.date = %q{2009-09-
|
9
|
+
s.date = %q{2009-09-05}
|
10
10
|
s.description = %q{Plaintext User Stories Parser supporting native programming languages.}
|
11
11
|
s.email = %q{mhennemeyer@me.com}
|
12
12
|
s.extra_rdoc_files = ["README.markdown", "lib/ObjC/objc_feature.rb", "lib/ObjC/objc_scenario.rb", "lib/ObjC/objc_step.rb", "lib/ObjC/objc_suite.rb", "lib/Rails/rails_feature.rb", "lib/Rails/rails_scenario.rb", "lib/Rails/rails_step.rb", "lib/Rails/rails_suite.rb", "lib/feature.rb", "lib/features.rb", "lib/objc.rb", "lib/parser.rb", "lib/rails.rb", "lib/scenario.rb", "lib/step.rb", "lib/string_extension.rb", "lib/suite.rb"]
|
13
|
-
s.files = ["Manifest", "README.markdown", "Rakefile", "generators/features/USAGE", "generators/features/features_generator.rb", "generators/features/templates/HelloWorld.feature", "generators/features/templates/custom_steps.rb", "generators/features/templates/features_helper.rb", "generators/features/templates/features_test_case_class.rb", "generators/features/templates/run_features.rb", "generators/features/templates/test_cases_file.rb", "lib/ObjC/objc_feature.rb", "lib/ObjC/objc_scenario.rb", "lib/ObjC/objc_step.rb", "lib/ObjC/objc_suite.rb", "lib/Rails/rails_feature.rb", "lib/Rails/rails_scenario.rb", "lib/Rails/rails_step.rb", "lib/Rails/rails_suite.rb", "lib/feature.rb", "lib/features.rb", "lib/objc.rb", "lib/parser.rb", "lib/rails.rb", "lib/scenario.rb", "lib/step.rb", "lib/string_extension.rb", "lib/suite.rb", "features.gemspec"]
|
13
|
+
s.files = ["Manifest", "README.markdown", "Rakefile", "generators/features/USAGE", "generators/features/features_generator.rb", "generators/features/templates/HelloWorld.feature", "generators/features/templates/custom_steps.rb", "generators/features/templates/features_helper.rb", "generators/features/templates/features_test_case_class.rb", "generators/features/templates/run_features.rb", "generators/features/templates/test_cases_file.rb", "lib/ObjC/objc_feature.rb", "lib/ObjC/objc_scenario.rb", "lib/ObjC/objc_step.rb", "lib/ObjC/objc_suite.rb", "lib/Rails/rails_feature.rb", "lib/Rails/rails_scenario.rb", "lib/Rails/rails_step.rb", "lib/Rails/rails_suite.rb", "lib/feature.rb", "lib/features.rb", "lib/objc.rb", "lib/parser.rb", "lib/rails.rb", "lib/scenario.rb", "lib/step.rb", "lib/string_extension.rb", "lib/suite.rb", "website/README", "website/Rakefile", "website/config.yaml", "website/deploy.rb", "website/deploy/1251795725/features/browserfix.css", "website/deploy/1251795725/features/default.css", "website/deploy/1251795725/features/images/bodybg.gif", "website/deploy/1251795725/features/images/header-bg.gif", "website/deploy/1251795725/features/images/logo.png", "website/deploy/1251795725/features/images/minus.png", "website/deploy/1251795725/features/images/plus.png", "website/deploy/1251795725/features/images/sidebarbg.gif", "website/deploy/1251795725/features/index.html", "website/deploy/1251796894/features/browserfix.css", "website/deploy/1251796894/features/default.css", "website/deploy/1251796894/features/images/bodybg.gif", "website/deploy/1251796894/features/images/header-bg.gif", "website/deploy/1251796894/features/images/logo.png", "website/deploy/1251796894/features/images/minus.png", "website/deploy/1251796894/features/images/output-screen-1.png", "website/deploy/1251796894/features/images/plus.png", "website/deploy/1251796894/features/images/sidebarbg.gif", "website/deploy/1251796894/features/index.html", "website/deploy/1251822430/features/browserfix.css", "website/deploy/1251822430/features/default.css", "website/deploy/1251822430/features/images/bodybg.gif", "website/deploy/1251822430/features/images/header-bg.gif", "website/deploy/1251822430/features/images/logo.png", "website/deploy/1251822430/features/images/minus.png", "website/deploy/1251822430/features/images/output-screen-1.png", "website/deploy/1251822430/features/images/plus.png", "website/deploy/1251822430/features/images/sidebarbg.gif", "website/deploy/1251822430/features/index.html", "website/ext/init.rb", "website/out/browserfix.css", "website/out/default.css", "website/out/images/bodybg.gif", "website/out/images/header-bg.gif", "website/out/images/logo.png", "website/out/images/minus.png", "website/out/images/output-screen-1.png", "website/out/images/plus.png", "website/out/images/sidebarbg.gif", "website/out/index.html", "website/src/browserfix.css", "website/src/default.css", "website/src/default.template", "website/src/images/bodybg.gif", "website/src/images/deploy.rb", "website/src/images/header-bg.gif", "website/src/images/logo.png", "website/src/images/minus.png", "website/src/images/output-screen-1.png", "website/src/images/plus.png", "website/src/images/sidebarbg.gif", "website/src/images/webgen.rb", "website/src/index.page", "website/webgen.cache", "website/webgen.rb", "features.gemspec"]
|
14
14
|
s.homepage = %q{http://features.rubyforge.org}
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Features", "--main", "README.markdown"]
|
16
16
|
s.require_paths = ["lib"]
|
@@ -2,6 +2,33 @@ require "rubygems"
|
|
2
2
|
require "features"
|
3
3
|
|
4
4
|
current_dir = File.dirname(File.expand_path(__FILE__))
|
5
|
+
|
6
|
+
# pass in config options directly as a hash. What follows are the possible keys:
|
7
|
+
#
|
8
|
+
# :feature_files_path
|
9
|
+
# The path to the directory containing your plaintext user stories files
|
10
|
+
#
|
11
|
+
# :feature_file_suffix
|
12
|
+
# A suffix to the plaintext user stories filenames. The default is .feature. Ommit the dot!
|
13
|
+
#
|
14
|
+
# :test_cases_file
|
15
|
+
# The path to the file that holds the tests generated by features.
|
16
|
+
#
|
17
|
+
# :features_helper
|
18
|
+
# The path to the file that will be required inside the test_cases_file.
|
19
|
+
#
|
20
|
+
# :feature_keyword
|
21
|
+
# The keyword that is prepended to the User Stories title. Defaults to 'Feature:'. With colon.
|
22
|
+
#
|
23
|
+
# :scenario_keyword
|
24
|
+
# The keyword that is prepended to the Scenario or Acceptance tests titles. Defaults to 'Scenario:'. With colon.
|
25
|
+
#
|
26
|
+
# :given_scenario_keyword
|
27
|
+
# The keyword that identifies a Scenario to be reused inside another Scenario. Defaults to 'GivenScenario:'. With colon.
|
28
|
+
#
|
29
|
+
# :project_name
|
30
|
+
# The project name will be shown at the top of the html output. Defaults to 'Features'.
|
31
|
+
|
5
32
|
suite = RailsSuite.new({
|
6
33
|
:feature_files_path => current_dir,
|
7
34
|
:test_cases_file => current_dir + "/support/test_cases_file.rb",
|
data/lib/ObjC/objc_feature.rb
CHANGED
@@ -1,36 +1,13 @@
|
|
1
1
|
class ObjcFeature < Feature
|
2
|
-
|
3
|
-
:title, :body, :parent, :parser,
|
4
|
-
:given_scenario_keyword, :keyword
|
5
|
-
|
6
|
-
def initialize(hash={})
|
7
|
-
@title = hash[:title]
|
8
|
-
@body = hash[:body]
|
9
|
-
@parent = hash[:parent]
|
10
|
-
@keyword = hash[:keyword] || "Feature:"
|
11
|
-
@scenario_keyword = hash[:scenario_keyword] || "Scenario:"
|
12
|
-
@given_scenario_keyword = hash[:given_scenario_keyword] || "GivenScenario:"
|
13
|
-
|
14
|
-
raise "No title given" unless title
|
15
|
-
raise "No body given" unless body
|
16
|
-
end
|
17
|
-
|
18
|
-
def story
|
19
|
-
body.split(/#{scenario_keyword}/)[0].split(/#{keyword}\s#{title}/).join(" ").strip
|
20
|
-
end
|
21
|
-
|
22
|
-
def story_html
|
23
|
-
story.split("\n").join(" <br />")
|
24
|
-
end
|
25
|
-
|
26
|
-
def parse_scenarios
|
2
|
+
def parse_scenarios(klass=ObjcScenario)
|
27
3
|
title_body_arr = Parser.title_and_body_by_keyword_from_string({
|
28
4
|
:string => body,
|
29
5
|
:keyword => scenario_keyword
|
30
6
|
})
|
31
|
-
@scenarios = title_body_arr.map {|hash|
|
7
|
+
@scenarios = title_body_arr.map {|hash| klass.new(hash.update({
|
32
8
|
:parent => self,
|
33
|
-
:given_scenario_keyword => given_scenario_keyword
|
9
|
+
:given_scenario_keyword => given_scenario_keyword,
|
10
|
+
:follow_up_keyword => follow_up_keyword
|
34
11
|
}))}
|
35
12
|
@scenarios.each {|scenario| scenario.collect_steps}
|
36
13
|
self
|
data/lib/ObjC/objc_scenario.rb
CHANGED
@@ -1,34 +1,4 @@
|
|
1
1
|
class ObjcScenario < Scenario
|
2
|
-
attr_reader :steps, :lines, :given_scenario_keyword,
|
3
|
-
:title, :body, :parent, :passed
|
4
|
-
|
5
|
-
def initialize(hash)
|
6
|
-
@title = hash[:title]
|
7
|
-
@body = hash[:body]
|
8
|
-
@parent = hash[:parent]
|
9
|
-
@given_scenario_keyword = hash[:given_scenario_keyword] || "GivenScenario:"
|
10
|
-
|
11
|
-
raise "No title given" unless title
|
12
|
-
raise "No body given" unless body
|
13
|
-
end
|
14
|
-
|
15
|
-
def keyword
|
16
|
-
parent.scenario_keyword
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_html
|
20
|
-
<<-END
|
21
|
-
<div class="scenario #{passed? ? "passed" : "failed"}">
|
22
|
-
<h2 class="scenario_title">#{keyword} #{title}</h2>
|
23
|
-
#{steps.map {|s| s.to_html}.join(" \n")}
|
24
|
-
</div>
|
25
|
-
END
|
26
|
-
end
|
27
|
-
|
28
|
-
def passed?
|
29
|
-
!!@passed
|
30
|
-
end
|
31
|
-
|
32
2
|
def verify_status(results="")
|
33
3
|
test_case_name = parent.test_case_name
|
34
4
|
#Test Case '-[SayHelloTest testWithABlankObject]' failed (0.001 seconds).
|
@@ -43,35 +13,8 @@ class ObjcScenario < Scenario
|
|
43
13
|
end
|
44
14
|
end
|
45
15
|
|
46
|
-
def collect_steps
|
47
|
-
|
48
|
-
if has_given_scenarios?
|
49
|
-
@body = expand_given_scenarios_in_body.strip
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
@lines = body.split(/\n+/).map {|s| s.strip}
|
54
|
-
raise "No Steps found" if lines.empty?
|
55
|
-
|
56
|
-
@steps = parse_lines
|
57
|
-
self
|
58
|
-
end
|
59
|
-
|
60
|
-
def expand_given_scenarios_in_body
|
61
|
-
raise "No associated Feature" unless parent
|
62
|
-
raise "Associated Feature has no Scenarios" unless parent.scenarios
|
63
|
-
body.gsub(/#{given_scenario_keyword}(.*)/) do |m|
|
64
|
-
existing_scenario = parent.scenarios.detect {|s| s.title == $1.strip }
|
65
|
-
existing_scenario ? existing_scenario.body.strip : ""
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
16
|
def parse_lines
|
70
|
-
lines.map {|l| ObjcStep.new({:
|
71
|
-
end
|
72
|
-
|
73
|
-
def has_given_scenarios?
|
74
|
-
!!(body =~ /#{given_scenario_keyword}(.*)/)
|
17
|
+
lines.map {|l| ObjcStep.new({:body => l}).aggregate!}
|
75
18
|
end
|
76
19
|
|
77
20
|
def to_s
|
data/lib/ObjC/objc_step.rb
CHANGED
@@ -1,39 +1,8 @@
|
|
1
1
|
class ObjcStep < Step
|
2
|
-
attr_reader :message
|
3
|
-
|
4
|
-
attr_reader :title, :body, :parent
|
5
|
-
def initialize(hash)
|
6
|
-
@title = hash[:title]
|
7
|
-
@body = hash[:body]
|
8
|
-
@parent = hash[:parent]
|
9
|
-
raise "No title given" unless title
|
10
|
-
raise "No body given" unless body
|
11
|
-
end
|
12
|
-
|
13
|
-
def to_html
|
14
|
-
s = <<-END
|
15
|
-
<h3 class="step">#{title}</h3>
|
16
|
-
END
|
17
|
-
s.strip
|
18
|
-
end
|
19
|
-
|
20
|
-
def aggregate!
|
21
|
-
@message = first_part + args_string
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
2
|
def first_part
|
26
3
|
body.gsub(/\s+/,"_").gsub(/'[^']*'/, "__").remove_invalid_chars
|
27
4
|
end
|
28
5
|
|
29
|
-
def has_args?
|
30
|
-
!args.empty?
|
31
|
-
end
|
32
|
-
|
33
|
-
def args
|
34
|
-
@args ||= body.scan(/'([^']*)'/).map {|a| a[0]}
|
35
|
-
end
|
36
|
-
|
37
6
|
def args_string
|
38
7
|
if has_args?
|
39
8
|
([":@\"#{args[0]}\""] +
|
data/lib/ObjC/objc_suite.rb
CHANGED
@@ -4,7 +4,8 @@ class ObjcSuite < Suite
|
|
4
4
|
:features, :test_cases_file,
|
5
5
|
:feature_class_header_files, :given_scenario_keyword,
|
6
6
|
:feature_keyword, :scenario_keyword,
|
7
|
-
:project_name, :passed
|
7
|
+
:project_name, :passed,
|
8
|
+
:follow_up_keyword
|
8
9
|
|
9
10
|
def initialize(hash)
|
10
11
|
@feature_files_path = hash[:feature_files_path]
|
@@ -15,96 +16,23 @@ class ObjcSuite < Suite
|
|
15
16
|
@scenario_keyword = hash[:scenario_keyword] || "Scenario:"
|
16
17
|
@given_scenario_keyword = hash[:given_scenario_keyword] || "GivenScenario:"
|
17
18
|
@project_name = hash[:project_name] || "Features"
|
19
|
+
@follow_up_keyword = hash[:follow_up_keyword] || "And"
|
18
20
|
@feature_files = all_feature_files
|
19
21
|
@feature_files_as_strings = all_feature_files_as_strings
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
def parse_results(results="")
|
38
|
-
parse
|
39
|
-
@passed = true
|
40
|
-
features.each do |f|
|
41
|
-
f.scenarios.each do |s|
|
42
|
-
s.verify_status(results)
|
43
|
-
@passed &&= s.passed?
|
44
|
-
end
|
24
|
+
def parse_features(klass=ObjcFeature)
|
25
|
+
title_body_arr = Parser.title_and_body_by_keyword_from_string({
|
26
|
+
:string => feature_files_as_strings.join(" "),
|
27
|
+
:keyword => feature_keyword
|
28
|
+
})
|
29
|
+
@features = title_body_arr.map do |hash|
|
30
|
+
klass.new(hash.update({
|
31
|
+
:keyword => feature_keyword,
|
32
|
+
:scenario_keyword => scenario_keyword,
|
33
|
+
:given_scenario_keyword => given_scenario_keyword,
|
34
|
+
:follow_up_keyword => follow_up_keyword}))
|
45
35
|
end
|
46
|
-
self
|
47
|
-
end
|
48
|
-
|
49
|
-
def passed?
|
50
|
-
@passed
|
51
|
-
end
|
52
|
-
|
53
|
-
def html
|
54
|
-
<<-END
|
55
|
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
56
|
-
<html>
|
57
|
-
<head>
|
58
|
-
<style type="text/css">
|
59
|
-
body {
|
60
|
-
font-family: Lucida Grande;
|
61
|
-
background-color: #FEFEFE;
|
62
|
-
padding: 5px;
|
63
|
-
}
|
64
|
-
* {-webkit-border-radius: 10px;}
|
65
|
-
body {background-color: #EEE; -webkit-border-radius: 0px;}
|
66
|
-
.feature { background-color: #CCC;padding: 20px; margin: 20px;}
|
67
|
-
.scenario { background-color: #EEE; padding: 20px; margin: 20px}
|
68
|
-
.failed {border: 1px solid #C88; background-color: #B77; }
|
69
|
-
.passed {border: 1px solid #8C8; background-color: #7B7; }
|
70
|
-
.feature_title {font-size: 24pt; }
|
71
|
-
.story { font-size: 18pt; padding-left: 40px;}
|
72
|
-
#indicator { width: 100%; height: 20px; }
|
73
|
-
#wrap { background-color: #EEE; padding: 20px }
|
74
|
-
</style></head>
|
75
|
-
</head>
|
76
|
-
<body>
|
77
|
-
<div id="wrap">
|
78
|
-
<div id="header">
|
79
|
-
<div id="indicator" class="#{passed? ? "passed" : "failed"}"> </div>
|
80
|
-
<h1 class="project_name">#{project_name}</h1>
|
81
|
-
|
82
|
-
</div>
|
83
|
-
#{features.map {|f| f.to_html }.join(" \n")}
|
84
|
-
</div>
|
85
|
-
</body>
|
86
|
-
</html>
|
87
|
-
END
|
88
|
-
end
|
89
|
-
|
90
|
-
def valid?
|
91
|
-
unique_feature_test_case_names?
|
92
|
-
end
|
93
|
-
|
94
|
-
def unique_feature_test_case_names?
|
95
|
-
feature_test_case_name = features.map {|f| f.test_case_name }
|
96
|
-
feature_test_case_name == feature_test_case_name.uniq
|
97
|
-
end
|
98
|
-
|
99
|
-
def run
|
100
|
-
parse
|
101
|
-
raise "Invalid: Duplicated Titles" unless valid?
|
102
|
-
File.open(test_cases_file, "w") { |f| f.puts self }
|
103
|
-
end
|
104
|
-
|
105
|
-
def parse
|
106
|
-
parse_features
|
107
|
-
parse_feature_scenarios
|
108
36
|
end
|
109
37
|
|
110
38
|
def to_s
|
@@ -113,40 +41,4 @@ class ObjcSuite < Suite
|
|
113
41
|
#{features.map {|f| f.to_s }.join(" ")}
|
114
42
|
END
|
115
43
|
end
|
116
|
-
|
117
|
-
def parse_features
|
118
|
-
title_body_arr = Parser.title_and_body_by_keyword_from_string({
|
119
|
-
:string => feature_files_as_strings.join(" "),
|
120
|
-
:keyword => feature_keyword
|
121
|
-
})
|
122
|
-
@features = title_body_arr.map {|hash| ObjcFeature.new(hash.update({:keyword => feature_keyword, :scenario_keyword => scenario_keyword}))}
|
123
|
-
end
|
124
|
-
|
125
|
-
def parse_feature_scenarios
|
126
|
-
features.each do |feature|
|
127
|
-
feature.parse_scenarios
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def all_feature_files
|
132
|
-
all_entries_in_feature_files_path = Dir.new(feature_files_path).entries
|
133
|
-
feature_entries = all_entries_in_feature_files_path.select do |file|
|
134
|
-
!!(file =~ /\.#{feature_file_suffix}$/)
|
135
|
-
end
|
136
|
-
feature_entries.map do |file|
|
137
|
-
feature_files_path + "/" + file
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def all_feature_files_as_strings
|
142
|
-
feature_files.map do |file|
|
143
|
-
feature_string = ""
|
144
|
-
File.open(file) do |f|
|
145
|
-
f.readlines.each do |l|
|
146
|
-
feature_string << l
|
147
|
-
end
|
148
|
-
end
|
149
|
-
feature_string
|
150
|
-
end
|
151
|
-
end
|
152
44
|
end
|