lemon 0.9.0 → 0.9.2
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/{HISTORY.rdoc → HISTORY.md} +42 -11
- data/LICENSE.txt +27 -0
- data/README.md +48 -34
- data/{spec/coverage/01_complete.rdoc → demo/coverage/01_complete.md} +3 -3
- data/{spec/coverage/02_incomplete.rdoc → demo/coverage/02_incomplete.md} +2 -2
- data/{spec/coverage/03_extensions.rdoc → demo/coverage/03_extensions.md} +2 -2
- 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/cli.rb +19 -8
- data/lib/lemon/core_ext/module.rb +9 -0
- data/lib/lemon/core_ext.rb +2 -2
- 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/lib/lemon.rb +1 -15
- metadata +71 -147
- data/.gemspec +0 -152
- data/.gitignore +0 -8
- data/.reap/digest +0 -678
- data/.reap/test.reap +0 -7
- data/.ruby +0 -49
- 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/lib/lemon.yml +0 -49
- 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/try/.test +0 -8
- data/try/case_error.rb +0 -18
- data/try/case_fail.rb +0 -19
- data/try/case_pass.rb +0 -42
- data/try/case_pending.rb +0 -18
- data/try/case_singleton.rb +0 -18
- data/try/case_untested.rb +0 -14
- data/try/fixtures/calculator.rb +0 -15
- data/try/fixtures/example-use.rb +0 -5
- data/try/fixtures/example.rb +0 -20
- data/try/helpers/loadpath.rb +0 -1
- 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
- /data/bin/{lemonade → lemons} +0 -0
- /data/{work/deprecated/features/support → demo/applique}/ae.rb +0 -0
- /data/{spec → demo}/applique/fs.rb +0 -0
- /data/{spec → demo}/coverage/applique/lemon.rb +0 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 6bc4b46bb63cecf471821a2b8997ba3f2d976917775f90eb28eab9b017051a8b
|
|
4
|
+
data.tar.gz: b55cc5338d2ed16736d51cc15e60458dd8ecca01aab1af0f9b8c6160ca6e2bef
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 49acc3b4d7778393804c67097e96f96ff7461d86dc44768d6c599982d66a03e54ae006fdd108065219fcb0ffc50d874c44336870753688b48552330577e24fc0
|
|
7
|
+
data.tar.gz: aa0ab93ed5a3e4b6357793745f6e530ba09db52ad3ffa8034ab785577f5371807b7ef79e5495ef0829dd14b7f15f11122b1f1f87237d97e1ee4ec167dd898f3d
|
data/{HISTORY.rdoc → HISTORY.md}
RENAMED
|
@@ -1,6 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
# RELEASE HISTORY
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 0.9.2 / 2026-03-31
|
|
4
|
+
|
|
5
|
+
Maintenance release. Modernized project tooling and cleaned up documentation.
|
|
6
|
+
|
|
7
|
+
Changes:
|
|
8
|
+
|
|
9
|
+
* Replace custom Indexer system with standard gemspec.
|
|
10
|
+
* Replace Travis CI with GitHub Actions.
|
|
11
|
+
* Replace Assembly/Reapfile with Rakefile.
|
|
12
|
+
* Simplify version handling (VERSION constant in module).
|
|
13
|
+
* Fix typos and update URLs to HTTPS.
|
|
14
|
+
* Move site from gh-pages to docs/.
|
|
15
|
+
* Remove obsolete files.
|
|
16
|
+
* Clean up .gitignore.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## 0.9.1 / 2012-03-17
|
|
20
|
+
|
|
21
|
+
Thie release fixes some evaluation scope issues, improves how omit and skip
|
|
22
|
+
methods work, makes test generation usable and generally cleans-up internals.
|
|
23
|
+
All in all, this release should be a fair bit more robust than previous releases
|
|
24
|
+
and ready for the big 1.0 after one more good coding session.
|
|
25
|
+
|
|
26
|
+
Changes:
|
|
27
|
+
|
|
28
|
+
* Fix test scope so it's properly isolated.
|
|
29
|
+
* Improve skip and omit methods w/ non-block forms.
|
|
30
|
+
* Use Ripper instead of RubyParse for scaffolding.
|
|
31
|
+
* Greatly improve usability of code generation tool.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## 0.9.0 / 2011-08-11
|
|
4
35
|
|
|
5
36
|
Version 0.9 is a huge release for Lemon. This release finally makes the transition
|
|
6
37
|
to the new unit subcase syntax --a bit more verbose than the old style but a more
|
|
@@ -31,7 +62,7 @@ Changes:
|
|
|
31
62
|
* Implemented new unit block syntax.
|
|
32
63
|
|
|
33
64
|
|
|
34
|
-
|
|
65
|
+
## 0.8.5 / 2011-07-15
|
|
35
66
|
|
|
36
67
|
This release fixes exit code status, which should be -1 if there
|
|
37
68
|
are errors or failures.
|
|
@@ -41,7 +72,7 @@ Changes:
|
|
|
41
72
|
* Fix exit code status.
|
|
42
73
|
|
|
43
74
|
|
|
44
|
-
|
|
75
|
+
## 0.8.4 / 2011-07-11
|
|
45
76
|
|
|
46
77
|
Fix reported issue #6 to get lemon passing it own tests. (Note: the
|
|
47
78
|
tests need to be run with `test/fixtures` in the loadpath). There was
|
|
@@ -57,7 +88,7 @@ Changes:
|
|
|
57
88
|
* Lemon can test itself (albeit test are not complete).
|
|
58
89
|
|
|
59
90
|
|
|
60
|
-
|
|
91
|
+
## 0.8.3 / 2011-05-19
|
|
61
92
|
|
|
62
93
|
Looks like Lemon is pretty damn near 1.0 status. She probably won't get
|
|
63
94
|
any major changes for a good while. This release simply adds TAP-Y/J reporters.
|
|
@@ -69,7 +100,7 @@ Changes:
|
|
|
69
100
|
* Configuration directory can be `.lemon/`.
|
|
70
101
|
|
|
71
102
|
|
|
72
|
-
|
|
103
|
+
## 0.8.2 / 2010-09-05
|
|
73
104
|
|
|
74
105
|
This release overhauls how coverage is performed so it does not need to
|
|
75
106
|
take a system snapshot after requiring each covered file. This greatly
|
|
@@ -84,7 +115,7 @@ Changes:
|
|
|
84
115
|
* Improved output formats.
|
|
85
116
|
|
|
86
117
|
|
|
87
|
-
|
|
118
|
+
## 0.8.1 / 2010-07-11
|
|
88
119
|
|
|
89
120
|
This release adds a timer to the verbose output, which help isolate unit tests
|
|
90
121
|
that are slow. It also fixed bug in Before and After advice that prevented them
|
|
@@ -95,7 +126,7 @@ Changes:
|
|
|
95
126
|
* Add times to verbose reporter.
|
|
96
127
|
|
|
97
128
|
|
|
98
|
-
|
|
129
|
+
## 0.8.0 / 2010-06-21
|
|
99
130
|
|
|
100
131
|
This release removes coverage information from testing. Coverage can be time
|
|
101
132
|
consuming, but running test should be as fast as possbile. For this reason
|
|
@@ -108,7 +139,7 @@ Changes:
|
|
|
108
139
|
* Test generator defaults to public methods only.
|
|
109
140
|
|
|
110
141
|
|
|
111
|
-
|
|
142
|
+
## 0.7.0 / 2010-05-04
|
|
112
143
|
|
|
113
144
|
This release fixes issue with coverage reports. To do this we have interoduced
|
|
114
145
|
the +Covers+ method. This allows Lemon to distingush between code that is
|
|
@@ -125,7 +156,7 @@ Changes:
|
|
|
125
156
|
* New Snapshot class improves encapsulation to coverage state.
|
|
126
157
|
|
|
127
158
|
|
|
128
|
-
|
|
159
|
+
## 0.6.0 / 2010-03-06
|
|
129
160
|
|
|
130
161
|
This release adds coverage reporting to testing and improves the generator.
|
|
131
162
|
|
|
@@ -136,7 +167,7 @@ Changes:
|
|
|
136
167
|
* Suite class has Coverage instance.
|
|
137
168
|
|
|
138
169
|
|
|
139
|
-
|
|
170
|
+
## 0.5.0 / 2009-12-31
|
|
140
171
|
|
|
141
172
|
This is the initial public release of Lemon. Lemon is still under development
|
|
142
173
|
and should be considered betaware, but it's API is stable and the system usable
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Lemon - Pucker-Strength Unit Testing
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2009 Rubyworks. All rights reserved
|
|
4
|
+
|
|
5
|
+
Licensed (spdx) BSD-2-Clause
|
|
6
|
+
|
|
7
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
|
8
|
+
permitted provided that the following conditions are met:
|
|
9
|
+
|
|
10
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
|
11
|
+
conditions and the following disclaimer.
|
|
12
|
+
|
|
13
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
14
|
+
of conditions and the following disclaimer in the documentation and/or other materials
|
|
15
|
+
provided with the distribution.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
|
18
|
+
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
19
|
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
|
20
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
21
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
23
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
24
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
25
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
|
|
27
|
+
(http://rubyworks.github.com/lemon)
|
data/README.md
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
# Lemon
|
|
2
2
|
|
|
3
|
-
[Homepage](
|
|
4
|
-
[
|
|
5
|
-
[
|
|
6
|
-
|
|
3
|
+
[Homepage](https://rubyworks.github.io/lemon) |
|
|
4
|
+
[Development](https://github.com/rubyworks/lemon) |
|
|
5
|
+
[Issues](https://github.com/rubyworks/lemon/issues)
|
|
6
|
+
|
|
7
|
+
[](https://rubygems.org/gems/lemon)
|
|
8
|
+
[](https://github.com/rubyworks/lemon/actions/workflows/test.yml)
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
## DESCRIPTION
|
|
10
12
|
|
|
11
13
|
Lemon is a Unit Testing Framework that enforces a strict test structure mirroring the class/module and method structure of the target code. Arguably this promotes the proper technique for low-level unit testing and helps ensure good test coverage.
|
|
12
14
|
|
|
13
|
-
The difference between unit testing and functional testing, and all other forms of testing for that matter, is simply a matter of where the testing *concern* lies. The concerns of unit testing are the concerns of unit tests
|
|
15
|
+
The difference between unit testing and functional testing, and all other forms of testing for that matter, is simply a matter of where the testing *concern* lies. The concerns of unit testing are the concerns of unit tests, which, in object-oriented design, drills down to individual methods.
|
|
14
16
|
|
|
15
|
-
IMPORTANT
|
|
17
|
+
**IMPORTANT!** As of v0.9+ the API has changed. The `unit :name => "description"` notation is no longer supported.
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
## EXAMPLE
|
|
19
21
|
|
|
20
22
|
Lemon tests are broken down into target class or module and target methods.
|
|
21
|
-
|
|
23
|
+
Within these lie the actual tests.
|
|
22
24
|
|
|
23
25
|
Let's say we have a script 'mylib.rb' consisting of the class X:
|
|
24
26
|
|
|
@@ -28,23 +30,23 @@ class X
|
|
|
28
30
|
end
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
A test case for the class would be written:
|
|
32
34
|
|
|
33
35
|
``` ruby
|
|
34
|
-
|
|
36
|
+
covers 'mylib'
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
testcase X do
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
setup "Description of setup." do
|
|
39
41
|
@x = X.new
|
|
40
42
|
end
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
method :a do
|
|
45
|
+
test "method #a does something expected" do
|
|
44
46
|
@x.a.assert.is_a? String
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
test "method #a does something else expected" do
|
|
48
50
|
@x.a.assert == "x"
|
|
49
51
|
end
|
|
50
52
|
end
|
|
@@ -56,46 +58,58 @@ The `covers` method works just like `require` with the exception that it records
|
|
|
56
58
|
|
|
57
59
|
The setup (also called the *concern*) is run for every subsequent test until a new setup is defined.
|
|
58
60
|
|
|
59
|
-
In conjunction with the `#setup` method, there is a `#teardown` method which can be used "tidy-up" after each test
|
|
60
|
-
|
|
61
|
-
You might have also notice by the documentation that the test methods do not have to be capitalized.
|
|
61
|
+
In conjunction with the `#setup` method, there is a `#teardown` method which can be used "tidy-up" after each test.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
The `#unit` method is also aliased as `#methed` which is actually a bit more readable. Along with that there is `class_unit` and its alias `class_method` for testing class-level methods. Also note that the test methods may be capitalized (e.g. `#TestCase`), if you prefer that style.
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
## USAGE
|
|
67
67
|
|
|
68
68
|
### Running Tests
|
|
69
69
|
|
|
70
|
-
Tests can be run using the `
|
|
70
|
+
Tests can be run using the `lemons` command line tool.
|
|
71
71
|
|
|
72
|
-
$
|
|
72
|
+
$ lemons test test/cases/name_case.rb
|
|
73
73
|
|
|
74
|
-
Lemon utilizes the
|
|
74
|
+
Lemon utilizes the RubyTest universal test harness to run tests, the `lemons test` command simply passes off control to `rubytest` command. So the `rubytest` command-line utility can also be used directly:
|
|
75
75
|
|
|
76
|
-
$
|
|
76
|
+
$ rubytest -r lemon test/cases/name_case.rb
|
|
77
77
|
|
|
78
|
-
Normal output is
|
|
78
|
+
Normal output is typically a _dot progression_. Other output types can be specified by the `--format` or `-f` option.
|
|
79
79
|
|
|
80
|
-
$
|
|
80
|
+
$ rubytest -r lemon -f tapy test/cases/name_case.rb
|
|
81
81
|
|
|
82
|
-
See [
|
|
82
|
+
See [RubyTest](https://github.com/rubyworks/rubytest) for more information.
|
|
83
83
|
|
|
84
84
|
### Checking Test Coverage
|
|
85
85
|
|
|
86
|
-
Lemon can check test coverage by loading your target system and comparing it to your tests. To do this use the
|
|
86
|
+
Lemon can check per-unit test coverage by loading your target system and comparing it to your tests. To do this use the `lemons coverage` command.
|
|
87
87
|
|
|
88
|
-
$
|
|
88
|
+
$ lemons coverage -Ilib test/cases/*.rb
|
|
89
89
|
|
|
90
|
-
The coverage tool provides class/module and method coverage and is meant
|
|
90
|
+
The coverage tool provides class/module and method coverage and is meant as a "guidance system" for developers working toward complete test coverage. It is not a LOC (lines of code) coverage tool and should not be considered a substitute for one.
|
|
91
91
|
|
|
92
92
|
### Generating Test Skeletons
|
|
93
93
|
|
|
94
|
-
Because of the one
|
|
94
|
+
Because of the one-to-one correspondence of test case and unit test to class/module and method, Lemon can also generate test scaffolding for previously written code. To do this, use the `lemons generate` or `lemons scaffold` command line utilities.
|
|
95
|
+
|
|
96
|
+
The `generate` command outputs test skeletons to the console. You can use this output as a simple reference or redirect the output to a file and then copy and paste portions into separate files as desired. The `scaffold` command will create actual files in your test directory. Other than that, and the options that go with it (e.g. `--output`), the two commands are the same.
|
|
97
|
+
|
|
98
|
+
To get a set of test skeletons simply provide the files to be covered.
|
|
99
|
+
|
|
100
|
+
$ lemons generate lib/**/*.rb
|
|
101
|
+
|
|
102
|
+
The generator can take into account tests already written, so as not to include units that already have tests. To do this provide a list of test files after a dash (`-`).
|
|
103
|
+
|
|
104
|
+
$ lemons generate -Ilib lib/**/*.rb - test/**/*.rb
|
|
105
|
+
|
|
106
|
+
Test skeletons can be generated on a per-file or per-case bases. By case is the default. Use the `-f`/`--file` option to do otherwise.
|
|
107
|
+
|
|
108
|
+
$ lemon scaffold -f lib/foo.rb
|
|
95
109
|
|
|
96
|
-
|
|
110
|
+
The default output location is `test/`. You can change this with the `-o/--output` option.
|
|
97
111
|
|
|
98
|
-
Generating test case scaffolding from code will undoubtedly strike test-driven developers as a case of putting the cart before the horse. However, it is not unreasonable to argue that high-level, behavior-driven, functional testing frameworks, such as Q.E.D. and Cucumber are better suited to test-first methodologies. While test-driven development can obviously be done with Lemon, unit-testing
|
|
112
|
+
Generating test case scaffolding from code will undoubtedly strike test-driven developers as a case of putting the cart before the horse. However, it is not unreasonable to argue that high-level, behavior-driven, functional testing frameworks, such as Q.E.D. and Cucumber, are better suited to test-first methodologies. While test-driven development can obviously be done with Lemon, unit-testing best suited to testing specific, critical portions of code, or for achieving full test coverage for mission critical applications.
|
|
99
113
|
|
|
100
114
|
### Test Directory
|
|
101
115
|
|
|
@@ -106,8 +120,8 @@ There is no special directory for Lemon tests. Since they are unit tests, `test/
|
|
|
106
120
|
|
|
107
121
|
Lemon Unit Testing Framework
|
|
108
122
|
|
|
109
|
-
Copyright (c) 2009 Thomas Sawyer
|
|
123
|
+
Copyright (c) 2009 Thomas Sawyer, Rubyworks
|
|
110
124
|
|
|
111
|
-
Lemon is
|
|
125
|
+
Lemon is distributable in accordance with the **BSD-2-Clause** license.
|
|
112
126
|
|
|
113
|
-
See the
|
|
127
|
+
See the LICENSE.txt for details.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
## Complete Coverage
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
### Complete Coverage of Public Interface
|
|
4
4
|
|
|
5
5
|
Given an example script in 'lib/complete_example.rb' as follows:
|
|
6
6
|
|
|
@@ -76,7 +76,7 @@ In addition there should be no uncovered_cases or undefined_units.
|
|
|
76
76
|
coverage.undefined_units.assert = []
|
|
77
77
|
coverage.uncovered_cases.assert = []
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
### Including Private and Protected Methods
|
|
80
80
|
|
|
81
81
|
We will use the same example classes as above, but in this case we will
|
|
82
82
|
add coverage for private and protected methods as well, given a test case
|
data/lib/lemon/cli/base.rb
CHANGED
|
@@ -2,17 +2,14 @@ module Lemon
|
|
|
2
2
|
|
|
3
3
|
require 'optparse'
|
|
4
4
|
|
|
5
|
-
# TODO: What about a config file?
|
|
6
|
-
|
|
7
|
-
# CLI Interfaces handle all lemon sub-commands.
|
|
8
5
|
module CLI
|
|
9
6
|
|
|
10
7
|
# Base class for all commands.
|
|
11
8
|
class Base
|
|
12
9
|
|
|
13
10
|
#
|
|
14
|
-
def
|
|
15
|
-
|
|
11
|
+
def self.run(argv)
|
|
12
|
+
new.run(argv)
|
|
16
13
|
end
|
|
17
14
|
|
|
18
15
|
#
|
|
@@ -25,12 +22,28 @@ module Lemon
|
|
|
25
22
|
begin
|
|
26
23
|
command_parse(argv)
|
|
27
24
|
command_run(argv)
|
|
28
|
-
rescue => err
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
#rescue => err
|
|
26
|
+
# raise err if $DEBUG
|
|
27
|
+
# $stderr.puts('ERROR: ' + err.to_s)
|
|
31
28
|
end
|
|
32
29
|
end
|
|
33
30
|
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Initialize new command instance. This will be overriden in subclasses.
|
|
35
|
+
#
|
|
36
|
+
def initialize(argv=ARGV)
|
|
37
|
+
@options = {}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#
|
|
41
|
+
# Parse command line argument. This is a no-op as it will be overridden
|
|
42
|
+
# in subclasses.
|
|
43
|
+
#
|
|
44
|
+
def command_parse(argv)
|
|
45
|
+
end
|
|
46
|
+
|
|
34
47
|
#
|
|
35
48
|
def option_parser
|
|
36
49
|
@option_parser ||= (
|
|
@@ -54,7 +67,7 @@ module Lemon
|
|
|
54
67
|
)
|
|
55
68
|
end
|
|
56
69
|
|
|
57
|
-
#
|
|
70
|
+
# -n --namespace
|
|
58
71
|
def option_namespaces
|
|
59
72
|
option_parser.on('-n', '--namespace NAME', 'add a namespace to output') do |name|
|
|
60
73
|
options[:namespaces] ||= []
|
|
@@ -68,54 +81,63 @@ module Lemon
|
|
|
68
81
|
# end
|
|
69
82
|
#end
|
|
70
83
|
|
|
84
|
+
# -f --format
|
|
71
85
|
def option_format
|
|
72
86
|
option_parser.on('-f', '--format NAME', 'output format') do |name|
|
|
73
87
|
options[:format] = name
|
|
74
88
|
end
|
|
75
89
|
end
|
|
76
90
|
|
|
91
|
+
# -v --verbose
|
|
77
92
|
def option_verbose
|
|
78
93
|
option_parser.on('-v', '--verbose', 'shortcut for `-f verbose`') do |name|
|
|
79
94
|
options[:format] = 'verbose'
|
|
80
95
|
end
|
|
81
96
|
end
|
|
82
97
|
|
|
83
|
-
|
|
98
|
+
# -c --covered, -u --uncovered and -a --all
|
|
99
|
+
def option_coverage
|
|
84
100
|
option_parser.on('-c', '--covered', 'include covered units') do
|
|
85
|
-
|
|
101
|
+
if options[:coverage] == :uncovered
|
|
102
|
+
options[:coverage] = :all
|
|
103
|
+
else
|
|
104
|
+
options[:coverage] = :covered
|
|
105
|
+
end
|
|
86
106
|
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def option_uncovered
|
|
90
107
|
option_parser.on('-u', '--uncovered', 'include only uncovered units') do
|
|
91
|
-
options[:
|
|
108
|
+
if options[:coverage] == :covered
|
|
109
|
+
options[:coverage] = :all
|
|
110
|
+
else
|
|
111
|
+
options[:coverage] = :uncovered
|
|
112
|
+
end
|
|
92
113
|
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def option_all
|
|
96
114
|
option_parser.on('-a', '--all', 'include all namespaces and units') do
|
|
97
|
-
options[:
|
|
115
|
+
options[:coverage] = :all
|
|
98
116
|
end
|
|
99
117
|
end
|
|
100
118
|
|
|
119
|
+
# -p --private
|
|
101
120
|
def option_private
|
|
102
121
|
option_parser.on('-p', '--private', 'include private and protected methods') do
|
|
103
122
|
options[:private] = true
|
|
104
123
|
end
|
|
105
124
|
end
|
|
106
125
|
|
|
126
|
+
# -z --zealous
|
|
107
127
|
def option_zealous
|
|
108
128
|
option_parser.on('-z', '--zealous', 'include undefined case methods') do
|
|
109
129
|
options[:zealous] = true
|
|
110
130
|
end
|
|
111
131
|
end
|
|
112
132
|
|
|
133
|
+
# -o --output
|
|
113
134
|
def option_output
|
|
114
|
-
option_parser.on('-o', '--output DIRECTORY', '
|
|
135
|
+
option_parser.on('-o', '--output DIRECTORY', 'output directory') do |dir|
|
|
115
136
|
options[:output] = dir
|
|
116
137
|
end
|
|
117
138
|
end
|
|
118
139
|
|
|
140
|
+
# -I
|
|
119
141
|
def option_loadpath
|
|
120
142
|
option_parser.on("-I PATH" , 'add directory to $LOAD_PATH') do |path|
|
|
121
143
|
paths = path.split(/[:;]/)
|
|
@@ -124,6 +146,7 @@ module Lemon
|
|
|
124
146
|
end
|
|
125
147
|
end
|
|
126
148
|
|
|
149
|
+
# -r
|
|
127
150
|
def option_requires
|
|
128
151
|
option_parser.on("-r FILE" , 'require file(s) (before doing anything else)') do |files|
|
|
129
152
|
files = files.split(/[:;]/)
|
|
@@ -132,6 +155,13 @@ module Lemon
|
|
|
132
155
|
end
|
|
133
156
|
end
|
|
134
157
|
|
|
158
|
+
# --dryrun
|
|
159
|
+
def option_dryrun
|
|
160
|
+
option_parser.on('--dryrun', 'no disk writes') do
|
|
161
|
+
options[:dryrun] = true
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
135
165
|
end
|
|
136
166
|
|
|
137
167
|
end
|
data/lib/lemon/cli/generate.rb
CHANGED
|
@@ -5,11 +5,20 @@ module Lemon
|
|
|
5
5
|
require 'lemon/cli/base'
|
|
6
6
|
|
|
7
7
|
# Generate Command
|
|
8
|
+
#
|
|
8
9
|
class Generate < Base
|
|
9
10
|
|
|
10
11
|
# Generate test templates.
|
|
11
|
-
def command_run(
|
|
12
|
-
|
|
12
|
+
def command_run(files)
|
|
13
|
+
if i = files.index('-')
|
|
14
|
+
options[:files] = files[0...i]
|
|
15
|
+
options[:tests] = files[i+1..-1]
|
|
16
|
+
else
|
|
17
|
+
options[:files] = files
|
|
18
|
+
options[:tests] = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
require 'lemon/coverage/generator'
|
|
13
22
|
|
|
14
23
|
loadpath = options[:loadpath] || []
|
|
15
24
|
requires = options[:requires] || []
|
|
@@ -17,31 +26,57 @@ module Lemon
|
|
|
17
26
|
loadpath.each{ |path| $LOAD_PATH.unshift(path) }
|
|
18
27
|
requires.each{ |path| require(path) }
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
#suite = Lemon::TestSuite.new(test_files, :cover=>cover) #, :cover_all=>true)
|
|
22
|
-
generator = Lemon::Generator.new(test_files, options)
|
|
29
|
+
generator = Lemon::Generator.new(options)
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
render_map = generator.generate
|
|
32
|
+
|
|
33
|
+
generate_output(render_map)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
def generate_output(render_map)
|
|
38
|
+
render_map.each do |group, test|
|
|
39
|
+
puts "# --- #{group} ---"
|
|
40
|
+
puts
|
|
41
|
+
puts test
|
|
42
|
+
puts
|
|
43
|
+
end
|
|
29
44
|
end
|
|
30
45
|
|
|
31
46
|
#
|
|
32
47
|
def command_parse(argv)
|
|
33
|
-
option_parser.banner = "Usage:
|
|
34
|
-
|
|
48
|
+
option_parser.banner = "Usage: lemons generate [options] [files ...]"
|
|
49
|
+
|
|
50
|
+
setup_options
|
|
51
|
+
|
|
52
|
+
option_parser.parse!(argv)
|
|
53
|
+
end
|
|
35
54
|
|
|
55
|
+
#
|
|
56
|
+
def setup_options
|
|
57
|
+
option_group
|
|
36
58
|
option_namespaces
|
|
37
|
-
option_covered
|
|
38
|
-
option_uncovered
|
|
39
|
-
option_all
|
|
40
59
|
option_private
|
|
60
|
+
option_caps
|
|
41
61
|
option_loadpath
|
|
42
62
|
option_requires
|
|
63
|
+
end
|
|
43
64
|
|
|
44
|
-
|
|
65
|
+
# -f --file
|
|
66
|
+
def option_group
|
|
67
|
+
option_parser.on('-f', '--file', 'group tests by file') do
|
|
68
|
+
options[:group] = :file
|
|
69
|
+
end
|
|
70
|
+
#option_parser.on('-c', '--case', 'group tests by case') do
|
|
71
|
+
# options[:group] = :case
|
|
72
|
+
#end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# -C --caps
|
|
76
|
+
def option_caps
|
|
77
|
+
option_parser.on('-C', '--caps', 'use capitalized test terms') do
|
|
78
|
+
options[:caps] = true
|
|
79
|
+
end
|
|
45
80
|
end
|
|
46
81
|
|
|
47
82
|
end
|