lemon 0.8.4 → 0.8.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.config/cucumber.yml +3 -0
- data/.gitignore +8 -0
- data/.reap/digest +678 -0
- data/.reap/test.reap +7 -0
- data/.ruby +42 -45
- data/Assembly +43 -0
- data/HISTORY.rdoc +10 -0
- data/MANIFEST +65 -0
- data/PROFILE +9 -6
- data/Rakefile +14 -0
- data/VERSION +1 -1
- data/lemon.gemspec +152 -0
- data/lib/lemon.yml +42 -45
- data/lib/lemon/cli.rb +4 -2
- data/lib/lemon/controller/test_runner.rb +4 -0
- data/lib/lemon/model/test_case.rb +122 -40
- data/notes/2010-05-05-coverage.rdoc +47 -0
- data/notes/2010-05-06-files_not_classes.rdoc +19 -0
- data/notes/2010-07-11-acid_testing.rdoc +52 -0
- data/notes/2010-08-02-enforcing-the-unit.md +68 -0
- data/notes/2010-08-03-new-api.md +37 -0
- data/site/.rsync-filter +8 -0
- 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 +39 -0
- 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 +6 -0
- data/site/assets/styles/reset.css +17 -0
- data/site/assets/styles/site.css +33 -0
- data/site/index.html +217 -0
- data/work/deprecated/command/abstract.rb +29 -0
- data/work/deprecated/command/coverage.rb +115 -0
- data/work/deprecated/command/generate.rb +124 -0
- data/work/deprecated/command/test.rb +112 -0
- data/work/reference/dsl2.rb +136 -0
- data/work/reference/dynamic_constant_lookup.rb +76 -0
- data/work/sandbox/lib/sample.rb +13 -0
- data/work/sandbox/test/sample_case.rb +12 -0
- data/work/trash/example-cover.rb +5 -0
- data/work/trash/example.rb +16 -0
- metadata +134 -101
- data/.yardopts +0 -7
- data/QED.rdoc +0 -1
data/site/.rsync-filter
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
3
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
4
|
+
<svg id="svg1" sodipodi:version="0.32" inkscape:version="0.38.1" width="400.00000pt" height="400.00000pt" sodipodi:docbase="/var/www/html/svg_gallery/svg/fruits" sodipodi:docname="lemon.svg" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink">
|
5
|
+
<defs id="defs3">
|
6
|
+
<linearGradient id="linearGradient831">
|
7
|
+
<stop style="stop-color: rgb(255, 255, 0); stop-opacity: 1;" offset="0.0000000" id="stop832"/>
|
8
|
+
<stop style="stop-color: rgb(255, 227, 0); stop-opacity: 1;" offset="1.0000000" id="stop833"/>
|
9
|
+
</linearGradient>
|
10
|
+
<radialGradient xlink:href="#linearGradient831" id="radialGradient834" cx="0.33703703" cy="0.28358209" r="0.38183698" fx="0.33703703" fy="0.28358209"/>
|
11
|
+
</defs>
|
12
|
+
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.3195079" inkscape:cx="120.13018" inkscape:cy="204.09312" inkscape:window-width="910" inkscape:window-height="775" inkscape:window-x="119" inkscape:window-y="24"/>
|
13
|
+
<g id="g838">
|
14
|
+
<path style="fill: url(#radialGradient834) rgb(0, 0, 0); fill-rule: evenodd; stroke: rgb(0, 0, 0); stroke-width: 10; stroke-linejoin: round; stroke-dasharray: none;" d="M 68.708186,148.12939 C 228.69852,9.5810597 474.45687,146.15839 471.15810,289.65487 C 497.54826,315.22034 467.85933,343.25988 451.36548,350.68211 C 309.51838,525.51691 17.577254,382.02043 34.895796,237.69925 C 12.847026,174.32754 32.421718,155.55162 68.708186,148.12939 z " id="path827" sodipodi:nodetypes="ccccc"/>
|
15
|
+
<path style="fill-opacity: 0.133333; fill-rule: evenodd; stroke-width: 1pt;" d="M 44.330330,267.99099 C 65.580330,246.74099 68.080330,411.74099 378.08033,350.49099 C 371.83033,344.24099 338.08033,201.74099 458.08033,249.24099 C 504.95533,263.61599 358.70533,239.55349 410.58033,339.24099 C 418.62433,352.33698 416.20533,352.36599 438.08033,357.99099 C 305.58033,500.49099 46.830330,390.49099 44.330330,267.99099 z " id="path828" sodipodi:nodetypes="cccccc"/>
|
16
|
+
<path style="fill: rgb(255, 255, 255); fill-opacity: 0.7; fill-rule: evenodd; stroke-width: 1pt;" d="M 68.080330,155.83295 C 124.36962,90.490990 313.68568,43.977604 438.08033,203.33295 C 395.58033,249.58295 275.58033,49.582958 68.080330,155.83295 z " id="path829" sodipodi:nodetypes="ccc"/>
|
17
|
+
<path style="fill: rgb(255, 255, 255); fill-opacity: 0.7; fill-rule: evenodd; stroke-width: 1pt;" d="M 469.33033,295.49099 C 483.64639,312.99099 470.58033,332.99099 460.58033,330.49099 C 381.83033,309.24099 424.33033,287.99099 469.33033,295.49099 z " id="path830" sodipodi:nodetypes="ccc"/>
|
18
|
+
</g>
|
19
|
+
|
20
|
+
<rdf:RDF xmlns="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
21
|
+
<Work rdf:about="">
|
22
|
+
<dc:title>Clipart by Nicu Buculei - pear</dc:title>
|
23
|
+
<dc:rights>
|
24
|
+
<Agent>
|
25
|
+
<dc:title>Nicu Buculei</dc:title>
|
26
|
+
</Agent>
|
27
|
+
</dc:rights>
|
28
|
+
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
29
|
+
<license rdf:resource="http://web.resource.org/cc/PublicDomain"/>
|
30
|
+
</Work>
|
31
|
+
|
32
|
+
<License rdf:about="http://web.resource.org/cc/PublicDomain">
|
33
|
+
<permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
|
34
|
+
<permits rdf:resource="http://web.resource.org/cc/Distribution"/>
|
35
|
+
<permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
|
36
|
+
</License>
|
37
|
+
|
38
|
+
</rdf:RDF>
|
39
|
+
</svg>
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
html { font-family: sans-serif; font-size: 16px; color: black; }
|
2
|
+
body { padding: 0; margin: 0; font-family: sans-serif; font-size: 12px; background: #fff; }
|
3
|
+
|
4
|
+
h1 { font-size: 90px; margin: 20px; }
|
5
|
+
|
6
|
+
p { font-size: 110%; text-align: justify; margin: 20px 0; line-height: 150%; }
|
7
|
+
|
8
|
+
a { text-decoration: none; font-size: 100%; }
|
9
|
+
a:hover { text-decoration: underline; }
|
10
|
+
|
11
|
+
ul { margin: 0 auto; list-style-type: none; width: 300px; }
|
12
|
+
li { float: left; padding: 10px; text-align: center; }
|
13
|
+
|
14
|
+
pre { font-size: 130%; padding: 10px 0 0 0; -moz-border-radius: 10px; font-family: courier, monospace; color: #000; }
|
15
|
+
code { font-family: courier, monospace; }
|
16
|
+
|
17
|
+
img { border: none; }
|
@@ -0,0 +1,33 @@
|
|
1
|
+
h1 { font-family: times; font-size: 400%; margin: 20px 0; color: #f7d901; }
|
2
|
+
h2 { font-size: 220%; margin-top: 30px; color: #444; }
|
3
|
+
h3 { font-size: 190%; color: orange; }
|
4
|
+
|
5
|
+
p { color: #222; font-weight: normal; font-size: 120%; }
|
6
|
+
a { color: #262; }
|
7
|
+
a:hover { text-decoration: underline; }
|
8
|
+
|
9
|
+
pre { background: #ffffff; -moz-border-radius: 10px; line-height: 140%; }
|
10
|
+
code { color: #222; font-weight: bold; }
|
11
|
+
tt { color: #222; font-weight: bold; }
|
12
|
+
|
13
|
+
#nav { padding: 0 30px 20px 60px; text-align: left; color: pink; float: right; }
|
14
|
+
#nav a { font-size: 160%; font-weight: bold; line-height: 150%; }
|
15
|
+
#nav a:hover { color: #0C0; text-decoration: none; }
|
16
|
+
|
17
|
+
#header { height: 250px; text-align: left; }
|
18
|
+
#header h1 { font-size: 100px; padding: 40px 0 0 0; color: #f7d901; margin-left: -10px; }
|
19
|
+
|
20
|
+
#main { color: white; padding: 20px 0 30px 0; background: url(../images/skin.jpg) #f7e931; }
|
21
|
+
#main p { font-weight: bold; font-family: times; font-size: 150%; }
|
22
|
+
#main h2 { color: #333333; }
|
23
|
+
#main h3 { color: #333333; }
|
24
|
+
|
25
|
+
#footer { margin-top: 40px; padding: 40px 0; text-align: center; background: url(../images/skin.jpg) #f7e931; }
|
26
|
+
#footer .copyright { padding-top: 0; }
|
27
|
+
#footer .copyright p { color: #222; font-weight: normal; font-size: 80%; line-height: 150%; }
|
28
|
+
|
29
|
+
#forkme {
|
30
|
+
position: absolute;
|
31
|
+
top: 0; right: 0;
|
32
|
+
width: 150px;
|
33
|
+
}
|
data/site/index.html
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Lemon</title>
|
4
|
+
<link href="assets/styles/reset.css" rel="stylesheet" type="text/css"/>
|
5
|
+
<link href="assets/styles/class.css" rel="stylesheet" type="text/css"/>
|
6
|
+
<link href="assets/styles/site.css" rel="stylesheet" type="text/css"/>
|
7
|
+
<link href="assets/images/lemon.jpg" rel="shortcut icon"/>
|
8
|
+
|
9
|
+
<!-- syntax highlighing -->
|
10
|
+
<script src="http://rubyworks.github.com/assets/includes/shjs/sh_main.min.js"></script>
|
11
|
+
<script src="http://rubyworks.github.com/assets/includes/shjs/lang/sh_ruby.min.js"></script>
|
12
|
+
<script src="http://rubyworks.github.com/assets/includes/shjs/lang/sh_sh.min.js"></script>
|
13
|
+
<link href="http://rubyworks.github.com/assets/includes/shjs/css/sh_acid.min.css" rel="stylesheet" type="text/css" />
|
14
|
+
</head>
|
15
|
+
<body onload="sh_highlightDocument();">
|
16
|
+
|
17
|
+
<div id="forkme">
|
18
|
+
<a href="http://github.com/rubyworks/lemon"><img src="assets/images/forkme.png" /></a>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div id="header">
|
22
|
+
<div class="page">
|
23
|
+
<img src="assets/images/cut-lemon.png" height="200px" align="right" style="padding-top: 15px;"/>
|
24
|
+
<h1><img src="assets/images/title.png"/></h1>
|
25
|
+
<h2>Pucker-Strength Unit Testing</h2>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div id="main" class="bordered">
|
30
|
+
<div class="page">
|
31
|
+
|
32
|
+
<div id="nav">
|
33
|
+
<!-- <a href="guide/doc.en/index.html">English Manual</a> · -->
|
34
|
+
<a href="http://wiki.github.com/rubyworks/lemon">Wiki</a> <br/>
|
35
|
+
<a href="http://rubydoc.info/gems/lemon/frames">API</a> <br/>
|
36
|
+
<a href="http://googlegroups.com/group/rubyworks-mailinglist">Email</a> <br/>
|
37
|
+
<a href="http://github.com/rubyworks/lemon/issues">Issue</a> <br/>
|
38
|
+
<a href="http://github.com/rubyworks/lemon">Code</a>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<p>Lemon is a unit testing framework which enforces highly formal
|
42
|
+
case-to-class and unit-to-method test construction.
|
43
|
+
This strict approach is arguably a more proper technique for unit
|
44
|
+
testing because it helps focus concern on individual units of
|
45
|
+
behavior and thus helps promote good test coverage. This is unlike
|
46
|
+
functional and integration testing which rightly focus on more
|
47
|
+
holistic issues.</p>
|
48
|
+
|
49
|
+
<!--
|
50
|
+
<h3>Writing Tests</h3>
|
51
|
+
|
52
|
+
<p>Let's say we have a library that consists of the class <code>HelloWorld</code>
|
53
|
+
with method <code>#to_s</code>:<p>
|
54
|
+
|
55
|
+
<pre class="sh_ruby">
|
56
|
+
class HelloWorld
|
57
|
+
def to_s
|
58
|
+
"Hello, World!"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
</pre>
|
62
|
+
|
63
|
+
<p>We would write a Lemon test case along the following lines:</p>
|
64
|
+
|
65
|
+
<pre class="sh_ruby">
|
66
|
+
TestCase HelloWorld do
|
67
|
+
Concern "String output works as expected."
|
68
|
+
|
69
|
+
Unit :to_s => "returns a string" do
|
70
|
+
HelloWorld.new.to_s.assert.is_a?(String)
|
71
|
+
end
|
72
|
+
|
73
|
+
Unit :to_s => "returns the world famous phrase" do
|
74
|
+
HelloWorld.new.to_s.assert == "Hello, World!"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
</pre>
|
78
|
+
|
79
|
+
<p>Clearly an overly simplistic example, but it demonstrates well enough the overall design of Lemon
|
80
|
+
tests. Notice that the <code>#TestCase</code> method references a class (this can also be a module) and the units each
|
81
|
+
refer to a method of the class.</p>
|
82
|
+
|
83
|
+
<p>Lemon uses the <a href="http://rubyworks.github.com/ae">Assertive Expressive</a>
|
84
|
+
assertions framework. This is the same verstile framework used by <a href="http://rubyworks.github.com/qed">Q.E.D.</a>.
|
85
|
+
By default Lemon test support the standard <code>#assert</code> and <code>#expect</code> assertion methods.
|
86
|
+
If you wish to use subjunctive terms, either <code>#should</code> or <code>#must</code>, you can load these
|
87
|
+
via a helper script (eg. <code>require 'ae/should'</code>).</p>
|
88
|
+
|
89
|
+
<h3>Running Tests</h3>
|
90
|
+
|
91
|
+
<p>The <tt>lemon</tt> command-line tool is used to run tests. Simply provide the name of the test files as arguments:</p>
|
92
|
+
|
93
|
+
<pre class="sh_sh">
|
94
|
+
> lemon test/cases/*.rb
|
95
|
+
</pre>
|
96
|
+
|
97
|
+
<p>By default the <tt>lemon</tt> command outputs the traditional dot-progress format. The <tt>--verbose</tt>
|
98
|
+
or <tt>-v</tt> option provides additional information about each unit test and concern
|
99
|
+
as they are executed.</p>
|
100
|
+
|
101
|
+
<h3>Test Coverage</h3>
|
102
|
+
|
103
|
+
<p>The <tt>lemon</tt> command can also be used to check test coverage. For this use the <tt>--coverage</tt>
|
104
|
+
or <tt>-c</tt> option.</p>
|
105
|
+
|
106
|
+
<pre class="sh_sh">
|
107
|
+
> lemon -c test/cases/*.rb
|
108
|
+
</pre>
|
109
|
+
|
110
|
+
<p>To enusre only the code you are interested in is checked, you can either use <tt>-r</tt> to pre-require
|
111
|
+
support libraries you wish not to include in the output. Or more conveniently, supply specific namespaces
|
112
|
+
to include via the <tt>--namespace</tt> or <tt>-n</tt> option.
|
113
|
+
|
114
|
+
<pre class="sh_sh">
|
115
|
+
> lemon -c -n HelloWorld test/cases/*.rb
|
116
|
+
</pre>
|
117
|
+
|
118
|
+
<p>For more information on Lemon and how to use it please see the Lemon <a href="http://wiki.github.com/rubyworks/lemon">Wiki</a>.</p>
|
119
|
+
|
120
|
+
<h2>Development</h2>
|
121
|
+
|
122
|
+
<p>Lemon is a RubyWorks project. Development is hosted on GitHub at:</p>
|
123
|
+
|
124
|
+
<pre>
|
125
|
+
<a href="http://github.com/rubyworks/lemon">http://github.com/rubyworks/lemon</a>
|
126
|
+
</pre>
|
127
|
+
|
128
|
+
<h3>License</h3>
|
129
|
+
|
130
|
+
<p>Lemon is an open-source project licensed under the terms of <b>Lesser General Public License</b>.</p>
|
131
|
+
|
132
|
+
-->
|
133
|
+
</div>
|
134
|
+
</div>
|
135
|
+
|
136
|
+
<div>
|
137
|
+
<div class="page">
|
138
|
+
<h3>Example</h3>
|
139
|
+
|
140
|
+
<p>To give you a taste of what a lemon testcase looks like, let's say we have a library
|
141
|
+
that consists of the class <code>HelloWorld</code> with method <code>#to_s</code>:<p>
|
142
|
+
|
143
|
+
<pre class="sh_ruby">
|
144
|
+
class HelloWorld
|
145
|
+
def to_s
|
146
|
+
"Hello, World!"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
</pre>
|
150
|
+
|
151
|
+
<p>We would write a Lemon test case along the following lines:</p>
|
152
|
+
|
153
|
+
<pre class="sh_ruby">
|
154
|
+
TestCase HelloWorld do
|
155
|
+
Concern "String output works as expected."
|
156
|
+
|
157
|
+
Unit :to_s => "returns a string" do
|
158
|
+
HelloWorld.new.to_s.assert.is_a?(String)
|
159
|
+
end
|
160
|
+
|
161
|
+
Unit :to_s => "returns a 13 character phrase" do
|
162
|
+
HelloWorld.new.to_s.size.assert == 13
|
163
|
+
end
|
164
|
+
end
|
165
|
+
</pre>
|
166
|
+
|
167
|
+
<p>A silly example to be sure, but one we can all easily understand.</p>
|
168
|
+
|
169
|
+
</div>
|
170
|
+
</div>
|
171
|
+
|
172
|
+
<div id="footer" class="bordered">
|
173
|
+
<div class="page">
|
174
|
+
<script type="text/javascript"><!--
|
175
|
+
google_ad_client = "ca-pub-1126154564663472";
|
176
|
+
/* RUBYWORKS 09-10-02 728x90 */
|
177
|
+
google_ad_slot = "0788888658";
|
178
|
+
google_ad_width = 728;
|
179
|
+
google_ad_height = 90;
|
180
|
+
//-->
|
181
|
+
</script>
|
182
|
+
<script type="text/javascript"
|
183
|
+
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
184
|
+
</script>
|
185
|
+
|
186
|
+
<br/><br/><br/>
|
187
|
+
|
188
|
+
<div class="copyright" width="100%">
|
189
|
+
<a href="http://rubyworks.github.com/">
|
190
|
+
<img src="assets/images/ruby-logo.png" height="110px" align="left" style="margin: 0 5px; padding: 0 10px" />
|
191
|
+
</a>
|
192
|
+
<a href="http://www.apache.org/licenses/LICENSE-2.0.html">
|
193
|
+
<img src="assets/images/opensource.png" height="120px" align="left" style="padding: 0 10px;" />
|
194
|
+
</a>
|
195
|
+
<a href="github.com/rubyworks/lemon">
|
196
|
+
<img src="assets/images/github-logo.png" height="115px" align="left" style="margin: 0; padding: 0 10px;" />
|
197
|
+
</a>
|
198
|
+
<a href="http://testanything.org/wiki/index.php/Main_Page">
|
199
|
+
<img src="assets/images/tap.png" height="113px" align="left" style="margin: 0; padding: 0 20px;" />
|
200
|
+
</a>
|
201
|
+
<a href="">
|
202
|
+
<img src="assets/images/lemons-are-good.png" height="117px" align="left" style="margin: 0; padding: 0 10px;" />
|
203
|
+
</a>
|
204
|
+
</div>
|
205
|
+
|
206
|
+
<br style="clear: both;" />
|
207
|
+
|
208
|
+
<div style="margin-top: 30px;">
|
209
|
+
<b>Lemon</b>, Copyright © 2009 Thomas Sawyer ·
|
210
|
+
<b>Contact:</b> transfire @ gmail.com
|
211
|
+
</div>
|
212
|
+
</div>
|
213
|
+
</div>
|
214
|
+
|
215
|
+
</body>
|
216
|
+
</html>
|
217
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Lemon
|
2
|
+
module Command
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
# Lemon Command-line tool base class.
|
6
|
+
class Abstract
|
7
|
+
|
8
|
+
# Used to map command-line options to command classes.
|
9
|
+
# This must be overridden in subclasses, and return an
|
10
|
+
# array of of options, e.g. [ '-g', '--generate'].
|
11
|
+
def self.options
|
12
|
+
raise "not implemented"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Stores a list of command classes.
|
16
|
+
def self.commands
|
17
|
+
@commands ||= []
|
18
|
+
end
|
19
|
+
|
20
|
+
# When this class is inherited, it is registered to the commands list.
|
21
|
+
def self.inherited(command_class)
|
22
|
+
commands << command_class
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Lemon
|
2
|
+
module Command
|
3
|
+
require 'lemon/command/abstract'
|
4
|
+
|
5
|
+
# Lemon Coverage Command-line tool.
|
6
|
+
class Coverage < Abstract
|
7
|
+
require 'yaml'
|
8
|
+
require 'lemon/coverage'
|
9
|
+
|
10
|
+
def self.subcommand
|
11
|
+
'coverage' #['-c', '--coverage']
|
12
|
+
end
|
13
|
+
|
14
|
+
# Initialize and run.
|
15
|
+
def self.run
|
16
|
+
new.run
|
17
|
+
end
|
18
|
+
|
19
|
+
# New Command instance.
|
20
|
+
def initialize
|
21
|
+
@format = nil
|
22
|
+
@requires = []
|
23
|
+
@includes = []
|
24
|
+
@namespaces = []
|
25
|
+
@public_only = false
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
attr_accessor :format
|
30
|
+
|
31
|
+
#
|
32
|
+
attr_accessor :public_only
|
33
|
+
|
34
|
+
#
|
35
|
+
def public_only?
|
36
|
+
@public_only
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get or set librarires to pre-require.
|
40
|
+
def requires(*paths)
|
41
|
+
@requires.concat(paths) unless paths.empty?
|
42
|
+
@requires
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get or set paths to include in $LOAD_PATH.
|
46
|
+
def includes(*paths)
|
47
|
+
@includes.concat(paths) unless paths.empty?
|
48
|
+
@includes
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get or set paths to include in $LOAD_PATH.
|
52
|
+
def namespaces(*names)
|
53
|
+
@namespaces.concat(names) unless names.empty?
|
54
|
+
@namespaces
|
55
|
+
end
|
56
|
+
|
57
|
+
# Instance of OptionParser.
|
58
|
+
def parser
|
59
|
+
@parser ||= OptionParser.new do |opt|
|
60
|
+
opt.banner = "lemon coverage [OPTIONS]"
|
61
|
+
opt.separator("Produce test coverage report.")
|
62
|
+
opt.on('--verbose', '-v', "select verbose report format") do |type|
|
63
|
+
self.format = :verbose
|
64
|
+
end
|
65
|
+
#opt.on('--outline', '-o', "select outline report format") do |type|
|
66
|
+
# self.format = :outline
|
67
|
+
#end
|
68
|
+
#opt.on('--format', '-f [TYPE]', "select report format") do |type|
|
69
|
+
# self.format = type
|
70
|
+
#end
|
71
|
+
opt.on('--namespace', '-n [NAME]', "limit coverage to this namespace") do |name|
|
72
|
+
namespaces(name)
|
73
|
+
end
|
74
|
+
opt.on('--public', '-p', "only include public methods") do
|
75
|
+
self.public_only = true
|
76
|
+
end
|
77
|
+
opt.on("-r [FILES]" , 'library files to require') do |files|
|
78
|
+
files = files.split(/[:;]/)
|
79
|
+
requires(*files)
|
80
|
+
end
|
81
|
+
opt.on("-I [PATH]" , 'include in $LOAD_PATH') do |path|
|
82
|
+
path = path.split(/[:;]/)
|
83
|
+
includes(*path)
|
84
|
+
end
|
85
|
+
opt.on("--debug" , 'turn on debugging mode') do
|
86
|
+
$DEBUG = true
|
87
|
+
end
|
88
|
+
opt.on_tail('--help', '-h', 'show this help message') do
|
89
|
+
puts opt
|
90
|
+
exit
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
def run
|
97
|
+
parser.parse!
|
98
|
+
|
99
|
+
test_files = ARGV.dup
|
100
|
+
load_files = []
|
101
|
+
|
102
|
+
includes.each{ |path| $LOAD_PATH.unshift(path) }
|
103
|
+
requires.each{ |path| require(path) }
|
104
|
+
|
105
|
+
suite = Lemon::Test::Suite.new(test_files, :cover=>true)
|
106
|
+
coverage = Lemon::Coverage.new(suite, namespaces, :public=>public_only?)
|
107
|
+
|
108
|
+
coverage.format(format)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|