lemon 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +23 -14
- data/.yardopts +6 -0
- data/Config.rb +14 -0
- data/{HISTORY.rdoc → HISTORY.md} +26 -11
- data/LICENSE.txt +27 -0
- data/README.md +42 -28
- data/SPECSHEET.md +314 -0
- data/bin/{lemonade → lemons} +0 -0
- data/lib/lemon.yml +23 -14
- data/lib/lemon/cli.rb +19 -8
- data/lib/lemon/cli/base.rb +50 -20
- data/lib/lemon/cli/generate.rb +51 -16
- data/lib/lemon/cli/lemon.ascii +84 -0
- data/lib/lemon/cli/obrother.rb +35 -0
- data/lib/lemon/cli/scaffold.rb +116 -0
- data/lib/lemon/core_ext.rb +2 -2
- data/lib/lemon/core_ext/module.rb +9 -0
- data/lib/lemon/coverage/analyzer.rb +76 -5
- data/lib/lemon/coverage/cover_unit.rb +38 -14
- data/lib/lemon/coverage/formats/verbose.rb +1 -1
- data/lib/lemon/coverage/generator.rb +196 -0
- data/lib/lemon/coverage/snapshot.rb +16 -16
- data/lib/lemon/coverage/source_parser.rb +103 -37
- data/lib/lemon/ignore_callers.rb +19 -0
- data/lib/lemon/test_case.rb +135 -26
- data/lib/lemon/test_class.rb +16 -3
- data/lib/lemon/test_class_method.rb +58 -0
- data/lib/lemon/test_method.rb +57 -68
- data/lib/lemon/test_module.rb +47 -44
- data/lib/lemon/test_proc.rb +28 -2
- data/lib/lemon/test_scope.rb +14 -0
- data/lib/lemon/test_setup.rb +1 -1
- data/lib/lemon/test_world.rb +7 -0
- data/{work/deprecated/features/support → spec/applique}/ae.rb +0 -0
- data/spec/coverage/{01_complete.rdoc → 01_complete.md} +3 -3
- data/spec/coverage/{02_incomplete.rdoc → 02_incomplete.md} +2 -2
- data/spec/coverage/{03_extensions.rdoc → 03_extensions.md} +2 -2
- data/try/case_scope.rb +19 -0
- metadata +50 -102
- data/.gemspec +0 -152
- data/.gitignore +0 -8
- data/.reap/digest +0 -678
- data/.reap/test.reap +0 -7
- data/Assembly +0 -37
- data/COPYING.rdoc +0 -33
- data/MANIFEST +0 -55
- data/PROFILE +0 -30
- data/Rakefile +0 -23
- data/VERSION +0 -1
- data/lib/lemon/core_ext/omission.rb +0 -18
- data/lib/lemon/generator.rb +0 -149
- data/notes/2010-05-05-coverage.rdoc +0 -47
- data/notes/2010-05-06-files-not-classes.rdoc +0 -19
- data/notes/2010-07-11-acid-testing.rdoc +0 -52
- data/notes/2010-08-02-enforcing-the-unit.md +0 -68
- data/notes/2010-08-03-new-api.md +0 -37
- data/notes/2011-07-07-nailing-down-the-nomenclature.md +0 -6
- data/site/.rsync-filter +0 -8
- data/site/assets/images/cut-lemon.png +0 -0
- data/site/assets/images/forkme.png +0 -0
- data/site/assets/images/github-logo.png +0 -0
- data/site/assets/images/lemon.jpg +0 -0
- data/site/assets/images/lemon.svg +0 -39
- data/site/assets/images/lemons-are-good.png +0 -0
- data/site/assets/images/opensource.png +0 -0
- data/site/assets/images/ruby-logo.png +0 -0
- data/site/assets/images/skin.jpg +0 -0
- data/site/assets/images/skin1.jpg +0 -0
- data/site/assets/images/tap.png +0 -0
- data/site/assets/images/title.png +0 -0
- data/site/assets/styles/class.css +0 -6
- data/site/assets/styles/reset.css +0 -17
- data/site/assets/styles/site.css +0 -33
- data/site/index.html +0 -218
- data/work/deprecated/command/abstract.rb +0 -29
- data/work/deprecated/command/coverage.rb +0 -115
- data/work/deprecated/command/generate.rb +0 -124
- data/work/deprecated/command/test.rb +0 -112
- data/work/deprecated/cucumber.yml +0 -3
- data/work/deprecated/features/coverage.feature +0 -65
- data/work/deprecated/features/generate.feature +0 -66
- data/work/deprecated/features/step_definitions/coverage_steps.rb +0 -1
- data/work/deprecated/features/support/aruba.rb +0 -1
- data/work/deprecated/features/test.feature +0 -67
- data/work/deprecated/model/dsl/advice.rb +0 -78
- data/work/deprecated/model/dsl/subject.rb +0 -40
- data/work/deprecated/model/main.rb +0 -87
- data/work/deprecated/model/test.rb +0 -54
- data/work/deprecated/model/test_base_dsl.rb +0 -88
- data/work/deprecated/model/test_clause.rb +0 -112
- data/work/deprecated/model/test_context.rb +0 -90
- data/work/deprecated/model/test_feature.rb +0 -128
- data/work/deprecated/model/test_scenario.rb +0 -137
- data/work/deprecated/model/test_suite.rb +0 -297
- data/work/deprecated/rake.rb +0 -103
- data/work/deprecated/test/case_coverage_analyzer.rb +0 -25
- data/work/deprecated/test/case_test_case_dsl.rb +0 -46
- data/work/deprecated/test/fixtures/case_complete.rb +0 -25
- data/work/deprecated/test/fixtures/case_inclusion.rb +0 -18
- data/work/deprecated/test/fixtures/case_incomplete.rb +0 -12
- data/work/deprecated/test/fixtures/example.rb +0 -13
- data/work/deprecated/test/fixtures/helper.rb +0 -13
- data/work/deprecated/test/runner +0 -2
- data/work/old-tests/case_example.rb +0 -15
- data/work/old-tests/feature_example.rb +0 -40
- data/work/reference/dsl2.rb +0 -140
- data/work/reference/dynamic_constant_lookup.rb +0 -76
@@ -1,112 +0,0 @@
|
|
1
|
-
module Lemon
|
2
|
-
|
3
|
-
#
|
4
|
-
class TestClause
|
5
|
-
|
6
|
-
# New unit test procedure.
|
7
|
-
#
|
8
|
-
def initialize(scenario, description, options={}) #, &procedure)
|
9
|
-
@context = scenario
|
10
|
-
@description = description
|
11
|
-
|
12
|
-
@type = options[:type]
|
13
|
-
|
14
|
-
#@subject = options[:subject]
|
15
|
-
#@aspect = options[:aspect]
|
16
|
-
#@omit = options[:omit]
|
17
|
-
|
18
|
-
#@procedure = procedure
|
19
|
-
|
20
|
-
@tested = false
|
21
|
-
end
|
22
|
-
|
23
|
-
attr :type
|
24
|
-
|
25
|
-
public
|
26
|
-
|
27
|
-
# The case to which this test belongs.
|
28
|
-
attr :context
|
29
|
-
|
30
|
-
# Setup and teardown procedures.
|
31
|
-
#attr :subject
|
32
|
-
|
33
|
-
#
|
34
|
-
#def target
|
35
|
-
# context.
|
36
|
-
#end
|
37
|
-
|
38
|
-
# Description of test.
|
39
|
-
attr :description
|
40
|
-
|
41
|
-
# Test procedure, in which test assertions should be made.
|
42
|
-
#attr :procedure
|
43
|
-
|
44
|
-
# The before and after advice from the context.
|
45
|
-
#def advice
|
46
|
-
# context.advice
|
47
|
-
#end
|
48
|
-
|
49
|
-
#
|
50
|
-
#def name ; @target ; end
|
51
|
-
|
52
|
-
# Is this unit test for a class or module level method?
|
53
|
-
#def function?
|
54
|
-
# context.function?
|
55
|
-
#end
|
56
|
-
|
57
|
-
#
|
58
|
-
attr_accessor :omit
|
59
|
-
|
60
|
-
#
|
61
|
-
def omit?
|
62
|
-
@omit
|
63
|
-
end
|
64
|
-
|
65
|
-
#
|
66
|
-
#attr_accessor :tested
|
67
|
-
|
68
|
-
#
|
69
|
-
#def to_s
|
70
|
-
# if function?
|
71
|
-
# "#{test_case}.#{target}"
|
72
|
-
# else
|
73
|
-
# "#{test_case}##{target}"
|
74
|
-
# end
|
75
|
-
#end
|
76
|
-
|
77
|
-
#
|
78
|
-
def to_s
|
79
|
-
"#{type.to_s.capitalize} #{description}"
|
80
|
-
end
|
81
|
-
|
82
|
-
#
|
83
|
-
def subject
|
84
|
-
end
|
85
|
-
|
86
|
-
#
|
87
|
-
def scope
|
88
|
-
context.scope
|
89
|
-
end
|
90
|
-
|
91
|
-
#
|
92
|
-
def to_proc
|
93
|
-
lambda{ call }
|
94
|
-
end
|
95
|
-
|
96
|
-
#
|
97
|
-
#def match?(match)
|
98
|
-
# match == target || match === aspect
|
99
|
-
#end
|
100
|
-
|
101
|
-
#
|
102
|
-
def call
|
103
|
-
context.run(self) do
|
104
|
-
#subject.run_setup(scope) if subject
|
105
|
-
scope.instance_exec(*arguments, &procedure)
|
106
|
-
#subject.run_teardown(scope) if subject
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
module Lemon
|
3
|
-
|
4
|
-
#
|
5
|
-
class TestContext
|
6
|
-
|
7
|
-
# The test case to which this concern belongs.
|
8
|
-
attr :test_case
|
9
|
-
|
10
|
-
# The description of this concern. Make this
|
11
|
-
# as detailed as you wish.
|
12
|
-
attr :description
|
13
|
-
|
14
|
-
# New case instance.
|
15
|
-
def initialize(test_case, description, options={}, &block)
|
16
|
-
@test_case = test_case
|
17
|
-
@description = description.to_s
|
18
|
-
@function = options[:function] || options[:singleton]
|
19
|
-
@type = options[:type] || :context
|
20
|
-
@block = block
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
def teardown=(procedure)
|
25
|
-
@teardown = procedure
|
26
|
-
end
|
27
|
-
|
28
|
-
# Teardown instance.
|
29
|
-
def teardown(scope=nil)
|
30
|
-
if scope
|
31
|
-
scope.instance_eval(&@teardown) if @teardown
|
32
|
-
else
|
33
|
-
@teardown
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Create instance.
|
38
|
-
def setup(scope)
|
39
|
-
if @block
|
40
|
-
scope.instance_eval(&@block)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def function? ; false ; end
|
45
|
-
alias_method :meta?, :function?
|
46
|
-
|
47
|
-
# Returns the description with newlines removed.
|
48
|
-
def to_s
|
49
|
-
description.gsub(/\n/, ' ')
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
=end
|
55
|
-
|
56
|
-
=begin
|
57
|
-
#
|
58
|
-
class TestInstance < TestContext
|
59
|
-
|
60
|
-
# Create instance.
|
61
|
-
def setup(scope)
|
62
|
-
if @block
|
63
|
-
ins = scope.instance_eval(&@block)
|
64
|
-
raise "target type mismatch" unless test_case.target === ins
|
65
|
-
end
|
66
|
-
ins
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
#
|
72
|
-
class TestSingleton < TestContext
|
73
|
-
|
74
|
-
# Create instance.
|
75
|
-
def setup(scope)
|
76
|
-
if @block
|
77
|
-
ins = scope.instance_eval(&@block)
|
78
|
-
raise "target type mismatch" unless test_case.target == ins
|
79
|
-
else
|
80
|
-
ins = @test_case.target
|
81
|
-
end
|
82
|
-
ins
|
83
|
-
end
|
84
|
-
|
85
|
-
def function? ; true ; end
|
86
|
-
alias_method :meta?, :function?
|
87
|
-
|
88
|
-
end
|
89
|
-
=end
|
90
|
-
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'lemon/model/pending'
|
2
|
-
require 'lemon/model/test_context'
|
3
|
-
require 'lemon/model/test_advice'
|
4
|
-
require 'lemon/model/test_scenario'
|
5
|
-
|
6
|
-
module Lemon
|
7
|
-
|
8
|
-
# The TestFeature ...
|
9
|
-
#
|
10
|
-
# * `tests` are _scenarios_,
|
11
|
-
# * `advice` are _given_, _when_ and _then_ rules.
|
12
|
-
#
|
13
|
-
class TestFeature < TestCase
|
14
|
-
|
15
|
-
#
|
16
|
-
def initialize(context, settings={}, &block)
|
17
|
-
@story = []
|
18
|
-
super(context, settings, &block)
|
19
|
-
end
|
20
|
-
|
21
|
-
## This has to be redefined in each subclass to pick
|
22
|
-
## up there respective DSL classes.
|
23
|
-
#def evaluate(&block)
|
24
|
-
# @dsl = DSL.new(self, &block)
|
25
|
-
#end
|
26
|
-
|
27
|
-
attr :story
|
28
|
-
|
29
|
-
# Feature scenarios are tests.
|
30
|
-
alias_method :scenarios, :tests
|
31
|
-
|
32
|
-
#
|
33
|
-
def to_s
|
34
|
-
"Feature #{target}"
|
35
|
-
end
|
36
|
-
|
37
|
-
#
|
38
|
-
def to_s #description
|
39
|
-
(["Feature: #{target}"] + story).join("\n ")
|
40
|
-
end
|
41
|
-
|
42
|
-
# Run test in the context of this case.
|
43
|
-
#
|
44
|
-
# @param [TestProc] test
|
45
|
-
# The test procedure instance to run.
|
46
|
-
#
|
47
|
-
def run(&block)
|
48
|
-
end
|
49
|
-
|
50
|
-
#
|
51
|
-
class DSL < Module
|
52
|
-
|
53
|
-
#
|
54
|
-
def initialize(feature, &code)
|
55
|
-
@feature = feature
|
56
|
-
|
57
|
-
module_eval(&code)
|
58
|
-
end
|
59
|
-
|
60
|
-
#
|
61
|
-
def To(description)
|
62
|
-
@feature.story << "To " + description
|
63
|
-
end
|
64
|
-
|
65
|
-
#
|
66
|
-
def As(description)
|
67
|
-
@feature.story << "As " + description
|
68
|
-
end
|
69
|
-
|
70
|
-
#
|
71
|
-
def We(description)
|
72
|
-
@feature.story << "We " + description
|
73
|
-
end
|
74
|
-
|
75
|
-
#
|
76
|
-
def Scenario(description, &procedure)
|
77
|
-
scenario = TestScenario.new(@feature, description, &procedure)
|
78
|
-
@feature.scenarios << scenario
|
79
|
-
scenario
|
80
|
-
end
|
81
|
-
alias_method :scenario, :Scenario
|
82
|
-
|
83
|
-
# Omit a scenario from test runs.
|
84
|
-
#
|
85
|
-
# omit unit :foo do
|
86
|
-
# # ...
|
87
|
-
# end
|
88
|
-
#
|
89
|
-
def Omit(scenario)
|
90
|
-
scenario.omit = true
|
91
|
-
end
|
92
|
-
alias_method :omit, :Omit
|
93
|
-
|
94
|
-
# Given ...
|
95
|
-
#
|
96
|
-
# @param [String] description
|
97
|
-
# A brief description of the _given_ criteria.
|
98
|
-
#
|
99
|
-
def Given(description, &procedure)
|
100
|
-
@feature.advice[:given][description] = procedure
|
101
|
-
end
|
102
|
-
alias_method :given, :Given
|
103
|
-
|
104
|
-
# When ...
|
105
|
-
#
|
106
|
-
# @param [String] description
|
107
|
-
# A brief description of the _when_ criteria.
|
108
|
-
#
|
109
|
-
def When(description, &procedure)
|
110
|
-
@feature.advice[:when][description] = procedure
|
111
|
-
end
|
112
|
-
alias_method :wence, :When
|
113
|
-
|
114
|
-
# Then ...
|
115
|
-
#
|
116
|
-
# @param [String] description
|
117
|
-
# A brief description of the _then_ criteria.
|
118
|
-
#
|
119
|
-
def Then(description, &procedure)
|
120
|
-
@feature.advice[:then][description] = procedure
|
121
|
-
end
|
122
|
-
alias_method :hence, :Then
|
123
|
-
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
@@ -1,137 +0,0 @@
|
|
1
|
-
require 'lemon/model/test_clause'
|
2
|
-
|
3
|
-
module Lemon
|
4
|
-
|
5
|
-
#
|
6
|
-
class TestScenario < TestCase
|
7
|
-
|
8
|
-
#
|
9
|
-
def initialize(feature, summary, options={}, &block)
|
10
|
-
@feature = feature
|
11
|
-
@summary = summary
|
12
|
-
|
13
|
-
@tests = []
|
14
|
-
|
15
|
-
evaluate(&block)
|
16
|
-
end
|
17
|
-
|
18
|
-
#
|
19
|
-
def evaluate(&procedure)
|
20
|
-
@dsl = DSL.new(self, &procedure)
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
attr :feature
|
25
|
-
|
26
|
-
#
|
27
|
-
attr :dsl
|
28
|
-
|
29
|
-
attr_accessor :omit
|
30
|
-
|
31
|
-
#
|
32
|
-
def omit?
|
33
|
-
@omit
|
34
|
-
end
|
35
|
-
|
36
|
-
#
|
37
|
-
def to_s
|
38
|
-
"Scenario: #{@summary}"
|
39
|
-
end
|
40
|
-
|
41
|
-
def subject
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
#
|
46
|
-
def run(clause)
|
47
|
-
type = clause.type
|
48
|
-
desc = clause.description
|
49
|
-
feature.advice[type].each do |mask, proc|
|
50
|
-
if md = match_regexp(mask).match(desc)
|
51
|
-
scope.instance_exec(*md[1..-1], &proc)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
#--
|
58
|
-
# TODO: Change so that the scope is the DSL
|
59
|
-
# and includes the DSL of the context?
|
60
|
-
#++
|
61
|
-
def scope
|
62
|
-
@scope ||= (
|
63
|
-
#if feature
|
64
|
-
# scope = feature.scope || Object.new
|
65
|
-
# scope.extend(dsl)
|
66
|
-
#else
|
67
|
-
scope = Object.new
|
68
|
-
scope.extend(dsl)
|
69
|
-
#end
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
#
|
74
|
-
#def find
|
75
|
-
# features.clauses[@type].find{ |c| c =~ @description }
|
76
|
-
#end
|
77
|
-
|
78
|
-
# Convert matching string into a regular expression. If the string
|
79
|
-
# contains double parenthesis, such as ((.*?)), then the text within
|
80
|
-
# them is treated as in regular expression and kept verbatium.
|
81
|
-
#
|
82
|
-
# TODO: Better way to isolate regexp. Maybe ?:(.*?) or /(.*?)/.
|
83
|
-
#
|
84
|
-
def match_regexp(str)
|
85
|
-
str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x|
|
86
|
-
x =~ /\A\(\((.*)\)\)\Z/ ? $1 : Regexp.escape(x)
|
87
|
-
}.join
|
88
|
-
str = str.gsub(/\\\s+/, '\s+')
|
89
|
-
Regexp.new(str, Regexp::IGNORECASE)
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
# TODO: Need to ensure the correct order of Given, When, Then.
|
94
|
-
class DSL < Module
|
95
|
-
|
96
|
-
#
|
97
|
-
def initialize(scenario, &code)
|
98
|
-
@scenario = scenario
|
99
|
-
|
100
|
-
module_eval(&code)
|
101
|
-
end
|
102
|
-
|
103
|
-
# Given ...
|
104
|
-
#
|
105
|
-
# @param [String] description
|
106
|
-
# A brief description of what the setup procedure sets-up.
|
107
|
-
#
|
108
|
-
def Given(description)
|
109
|
-
@scenario.tests << TestClause.new(@scenario, description, :type=>:given)
|
110
|
-
end
|
111
|
-
alias_method :given, :Given
|
112
|
-
|
113
|
-
# When ...
|
114
|
-
#
|
115
|
-
# @param [String] description
|
116
|
-
# A brief description of what the setup procedure sets-up.
|
117
|
-
#
|
118
|
-
def When(description)
|
119
|
-
@scenario.tests << TestClause.new(@scenario, description, :type=>:when)
|
120
|
-
end
|
121
|
-
alias_method :wence, :When
|
122
|
-
|
123
|
-
# Then ...
|
124
|
-
#
|
125
|
-
# @param [String] description
|
126
|
-
# A brief description of what the setup procedure sets-up.
|
127
|
-
#
|
128
|
-
def Then(description)
|
129
|
-
@scenario.tests << TestClause.new(@scenario, description, :type=>:then)
|
130
|
-
end
|
131
|
-
alias_method :hence, :Then
|
132
|
-
|
133
|
-
end
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|