lemon 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. data/.ruby +23 -14
  2. data/.yardopts +6 -0
  3. data/Config.rb +14 -0
  4. data/{HISTORY.rdoc → HISTORY.md} +26 -11
  5. data/LICENSE.txt +27 -0
  6. data/README.md +42 -28
  7. data/SPECSHEET.md +314 -0
  8. data/bin/{lemonade → lemons} +0 -0
  9. data/lib/lemon.yml +23 -14
  10. data/lib/lemon/cli.rb +19 -8
  11. data/lib/lemon/cli/base.rb +50 -20
  12. data/lib/lemon/cli/generate.rb +51 -16
  13. data/lib/lemon/cli/lemon.ascii +84 -0
  14. data/lib/lemon/cli/obrother.rb +35 -0
  15. data/lib/lemon/cli/scaffold.rb +116 -0
  16. data/lib/lemon/core_ext.rb +2 -2
  17. data/lib/lemon/core_ext/module.rb +9 -0
  18. data/lib/lemon/coverage/analyzer.rb +76 -5
  19. data/lib/lemon/coverage/cover_unit.rb +38 -14
  20. data/lib/lemon/coverage/formats/verbose.rb +1 -1
  21. data/lib/lemon/coverage/generator.rb +196 -0
  22. data/lib/lemon/coverage/snapshot.rb +16 -16
  23. data/lib/lemon/coverage/source_parser.rb +103 -37
  24. data/lib/lemon/ignore_callers.rb +19 -0
  25. data/lib/lemon/test_case.rb +135 -26
  26. data/lib/lemon/test_class.rb +16 -3
  27. data/lib/lemon/test_class_method.rb +58 -0
  28. data/lib/lemon/test_method.rb +57 -68
  29. data/lib/lemon/test_module.rb +47 -44
  30. data/lib/lemon/test_proc.rb +28 -2
  31. data/lib/lemon/test_scope.rb +14 -0
  32. data/lib/lemon/test_setup.rb +1 -1
  33. data/lib/lemon/test_world.rb +7 -0
  34. data/{work/deprecated/features/support → spec/applique}/ae.rb +0 -0
  35. data/spec/coverage/{01_complete.rdoc → 01_complete.md} +3 -3
  36. data/spec/coverage/{02_incomplete.rdoc → 02_incomplete.md} +2 -2
  37. data/spec/coverage/{03_extensions.rdoc → 03_extensions.md} +2 -2
  38. data/try/case_scope.rb +19 -0
  39. metadata +50 -102
  40. data/.gemspec +0 -152
  41. data/.gitignore +0 -8
  42. data/.reap/digest +0 -678
  43. data/.reap/test.reap +0 -7
  44. data/Assembly +0 -37
  45. data/COPYING.rdoc +0 -33
  46. data/MANIFEST +0 -55
  47. data/PROFILE +0 -30
  48. data/Rakefile +0 -23
  49. data/VERSION +0 -1
  50. data/lib/lemon/core_ext/omission.rb +0 -18
  51. data/lib/lemon/generator.rb +0 -149
  52. data/notes/2010-05-05-coverage.rdoc +0 -47
  53. data/notes/2010-05-06-files-not-classes.rdoc +0 -19
  54. data/notes/2010-07-11-acid-testing.rdoc +0 -52
  55. data/notes/2010-08-02-enforcing-the-unit.md +0 -68
  56. data/notes/2010-08-03-new-api.md +0 -37
  57. data/notes/2011-07-07-nailing-down-the-nomenclature.md +0 -6
  58. data/site/.rsync-filter +0 -8
  59. data/site/assets/images/cut-lemon.png +0 -0
  60. data/site/assets/images/forkme.png +0 -0
  61. data/site/assets/images/github-logo.png +0 -0
  62. data/site/assets/images/lemon.jpg +0 -0
  63. data/site/assets/images/lemon.svg +0 -39
  64. data/site/assets/images/lemons-are-good.png +0 -0
  65. data/site/assets/images/opensource.png +0 -0
  66. data/site/assets/images/ruby-logo.png +0 -0
  67. data/site/assets/images/skin.jpg +0 -0
  68. data/site/assets/images/skin1.jpg +0 -0
  69. data/site/assets/images/tap.png +0 -0
  70. data/site/assets/images/title.png +0 -0
  71. data/site/assets/styles/class.css +0 -6
  72. data/site/assets/styles/reset.css +0 -17
  73. data/site/assets/styles/site.css +0 -33
  74. data/site/index.html +0 -218
  75. data/work/deprecated/command/abstract.rb +0 -29
  76. data/work/deprecated/command/coverage.rb +0 -115
  77. data/work/deprecated/command/generate.rb +0 -124
  78. data/work/deprecated/command/test.rb +0 -112
  79. data/work/deprecated/cucumber.yml +0 -3
  80. data/work/deprecated/features/coverage.feature +0 -65
  81. data/work/deprecated/features/generate.feature +0 -66
  82. data/work/deprecated/features/step_definitions/coverage_steps.rb +0 -1
  83. data/work/deprecated/features/support/aruba.rb +0 -1
  84. data/work/deprecated/features/test.feature +0 -67
  85. data/work/deprecated/model/dsl/advice.rb +0 -78
  86. data/work/deprecated/model/dsl/subject.rb +0 -40
  87. data/work/deprecated/model/main.rb +0 -87
  88. data/work/deprecated/model/test.rb +0 -54
  89. data/work/deprecated/model/test_base_dsl.rb +0 -88
  90. data/work/deprecated/model/test_clause.rb +0 -112
  91. data/work/deprecated/model/test_context.rb +0 -90
  92. data/work/deprecated/model/test_feature.rb +0 -128
  93. data/work/deprecated/model/test_scenario.rb +0 -137
  94. data/work/deprecated/model/test_suite.rb +0 -297
  95. data/work/deprecated/rake.rb +0 -103
  96. data/work/deprecated/test/case_coverage_analyzer.rb +0 -25
  97. data/work/deprecated/test/case_test_case_dsl.rb +0 -46
  98. data/work/deprecated/test/fixtures/case_complete.rb +0 -25
  99. data/work/deprecated/test/fixtures/case_inclusion.rb +0 -18
  100. data/work/deprecated/test/fixtures/case_incomplete.rb +0 -12
  101. data/work/deprecated/test/fixtures/example.rb +0 -13
  102. data/work/deprecated/test/fixtures/helper.rb +0 -13
  103. data/work/deprecated/test/runner +0 -2
  104. data/work/old-tests/case_example.rb +0 -15
  105. data/work/old-tests/feature_example.rb +0 -40
  106. data/work/reference/dsl2.rb +0 -140
  107. data/work/reference/dynamic_constant_lookup.rb +0 -76
@@ -1,68 +0,0 @@
1
- 2010-08-02 | Enforcing the Unit
2
-
3
- The current API for creating a Lemon unit testcase looks like this:
4
-
5
- covers 'someclass'
6
-
7
- testcase SomeClass do
8
-
9
- unit :some_method => "does something or another" do
10
- # ...
11
- end
12
-
13
- end
14
-
15
- As it currentlt standa the current design is little more than a means of
16
- organization, orienting the developer to think in terms of test units.
17
- What is does not do is enforce the actual testing the the unit referenced.
18
- We could put any old mess in the unit block and as long as it did not raise
19
- an exception, it would get a *pass*.
20
-
21
- Taking some time to consider this in depth, I've concieved of a way in which
22
- that use of the method could in fact be enforced.
23
-
24
- covers 'someclass'
25
-
26
- testcase SomeClass do
27
-
28
- setup do
29
- SomeClass.new
30
- end
31
-
32
- unit :some_method => "does something or another" do |unit|
33
- unit.object # object from setup
34
- unit.call(...) # calls #some_method on unit.object
35
- end
36
-
37
- end
38
-
39
- What is intersting about this, beyond that fact that it enforces the use of
40
- the class or module and method involved, but that it also does so in
41
- a way naturally suited to mocking --the `unit` delegator could even have
42
- mocking methods built-in.
43
-
44
- unit :some_method => "does something or another" do |unit|
45
- unit.receives.foo(:bar) # object from setup would receive this call
46
- unit.returns(:baz) # the subsequent #call will return this
47
- unit.call(...) # calls #some_method on unit.object
48
- end
49
-
50
- On the downside this approach limits what can be done in the unit block.
51
- One _has_ to utilize the object as defined in `setup` and one _has_ to invoke
52
- the unit method via the `#call` interface. Though, I suppose one could argue
53
- that these limitations are a good thing, as they help the unit stay narrowly
54
- focused on that goal at hand.
55
-
56
- I think this approach is worth considering for a possible furture version.
57
- Perhaps a "Lemon 2.0". For the time being I believe we can enforce the unit
58
- without resorting this major API change.
59
-
60
- The next release of Lemon will temporarily override the unit method on the
61
- target class for each unit execution. If the unit method gets called within
62
- the unit block, then it will be noted by the overridden method before passing
63
- off to the original definition. The approach is perhaps a bit draconian, and
64
- is certainly only possible thanks to the remarkable dynamicism of Ruby, but
65
- it should work perfectly well. So now, if the target method is not called within
66
- the taget block, the unit will raise a Pending exception, regardless of the
67
- code in the block. Unit Enforced!
68
-
@@ -1,37 +0,0 @@
1
- # 2010-08-03 | A New API
2
-
3
- Simplified API. There is one main method.
4
-
5
- unit_test SomeClass, :some_method, "description" do
6
- # test ...
7
- end
8
-
9
- It will be a global method. The block notations would still work, but
10
- they would simple become wrappers for the main method.
11
-
12
- testcase SomeClass do
13
-
14
- unit :some_method, "description" do
15
-
16
- end
17
-
18
- end
19
-
20
- If I can make it backward compatible, I may also allow something like:
21
-
22
- testcase SomeClass do
23
-
24
- unit :some_method do
25
-
26
- concern "description" do
27
-
28
- end
29
-
30
- end
31
-
32
- end
33
-
34
- By using this global method, I should be able to simplify the underlying
35
- implementation a great deal, which has been major concern about Lemon
36
- as of late.
37
-
@@ -1,6 +0,0 @@
1
- # 2011-07-07 | Nailing Down the Nomenclature
2
-
3
- I have finally settled on `test_class` and `test_module` as thew new toplevel method for defining Lemon test cases. I decided against reusing `test_case` from Citron b/c I determined it is best that these types of test cases not be mixed together, but rather stay cleanly separated.
4
-
5
- I also decided against the original KO inspired nomenclature of `Test.case`. Though it looks very cool at first glance, in the end it goes against the grain. For instance, would one design an RSpec-stlye nomenclature as `Test.describe`, or a Cucumber-style nomenclature using `Test.feature`? While one could do so, it's completely uneccessry.
6
-
@@ -1,8 +0,0 @@
1
- - .svn
2
- - .gitignore
3
- P usage
4
- P statcvs
5
- P statsvn
6
- P robot.txt
7
- P robots.txt
8
- P wiki
Binary file
@@ -1,39 +0,0 @@
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
@@ -1,6 +0,0 @@
1
- .page { width: 730px; margin: 0 auto; }
2
-
3
- .bordered { border-top: 2px solid yellow; border-bottom: 2px solid yellow; }
4
-
5
- .copyright { padding: 0; text-align: left; }
6
- .copyright td { font-size: 10px; color: #444; }
@@ -1,17 +0,0 @@
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; }
@@ -1,33 +0,0 @@
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
- }
@@ -1,218 +0,0 @@
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> &nbsp;&middot;&nbsp; -->
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 do
70
- Test "returns a string" do
71
- HelloWorld.new.to_s.assert.is_a?(String)
72
- end
73
- Test "returns the world famous phrase" do
74
- HelloWorld.new.to_s.assert == "Hello, World!"
75
- end
76
- end
77
- end
78
- </pre>
79
-
80
- <p>Clearly an overly simplistic example, but it demonstrates well enough the overall design of Lemon
81
- tests. Notice that the <code>#TestCase</code> method references a class (this can also be a module) and the units each
82
- refer to a method of the class.</p>
83
-
84
- <p>Lemon uses the <a href="http://rubyworks.github.com/ae">Assertive Expressive</a>
85
- assertions framework. This is the same verstile framework used by <a href="http://rubyworks.github.com/qed">Q.E.D.</a>.
86
- By default Lemon test support the standard <code>#assert</code> and <code>#expect</code> assertion methods.
87
- If you wish to use subjunctive terms, either <code>#should</code> or <code>#must</code>, you can load these
88
- via a helper script (eg. <code>require 'ae/should'</code>).</p>
89
-
90
- <h3>Running Tests</h3>
91
-
92
- <p>The <tt>lemon</tt> command-line tool is used to run tests. Simply provide the name of the test files as arguments:</p>
93
-
94
- <pre class="sh_sh">
95
- > lemon test/cases/*.rb
96
- </pre>
97
-
98
- <p>By default the <tt>lemon</tt> command outputs the traditional dot-progress format. The <tt>--verbose</tt>
99
- or <tt>-v</tt> option provides additional information about each unit test and concern
100
- as they are executed.</p>
101
-
102
- <h3>Test Coverage</h3>
103
-
104
- <p>The <tt>lemon</tt> command can also be used to check test coverage. For this use the <tt>--coverage</tt>
105
- or <tt>-c</tt> option.</p>
106
-
107
- <pre class="sh_sh">
108
- > lemon -c test/cases/*.rb
109
- </pre>
110
-
111
- <p>To enusre only the code you are interested in is checked, you can either use <tt>-r</tt> to pre-require
112
- support libraries you wish not to include in the output. Or more conveniently, supply specific namespaces
113
- to include via the <tt>--namespace</tt> or <tt>-n</tt> option.
114
-
115
- <pre class="sh_sh">
116
- > lemon -c -n HelloWorld test/cases/*.rb
117
- </pre>
118
-
119
- <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>
120
-
121
- <h2>Development</h2>
122
-
123
- <p>Lemon is a RubyWorks project. Development is hosted on GitHub at:</p>
124
-
125
- <pre>
126
- <a href="http://github.com/rubyworks/lemon">http://github.com/rubyworks/lemon</a>
127
- </pre>
128
-
129
- <h3>License</h3>
130
-
131
- <p>Lemon is an open-source project licensed under the terms of <b>Lesser General Public License</b>.</p>
132
-
133
- -->
134
- </div>
135
- </div>
136
-
137
- <div>
138
- <div class="page">
139
- <h3>Example</h3>
140
-
141
- <p>To give you a taste of what a lemon testcase looks like, let's say we have a library
142
- that consists of the class <code>HelloWorld</code> with method <code>#to_s</code>:<p>
143
-
144
- <pre class="sh_ruby">
145
- class HelloWorld
146
- def to_s
147
- "Hello, World!"
148
- end
149
- end
150
- </pre>
151
-
152
- <p>We would write a Lemon test case along the following lines:</p>
153
-
154
- <pre class="sh_ruby">
155
- TestCase HelloWorld do
156
- Concern "String output works as expected."
157
-
158
- Unit :to_s => "returns a string" do
159
- HelloWorld.new.to_s.assert.is_a?(String)
160
- end
161
-
162
- Unit :to_s => "returns a 13 character phrase" do
163
- HelloWorld.new.to_s.size.assert == 13
164
- end
165
- end
166
- </pre>
167
-
168
- <p>A silly example to be sure, but one we can all easily understand.</p>
169
-
170
- </div>
171
- </div>
172
-
173
- <div id="footer" class="bordered">
174
- <div class="page">
175
- <script type="text/javascript"><!--
176
- google_ad_client = "ca-pub-1126154564663472";
177
- /* RUBYWORKS 09-10-02 728x90 */
178
- google_ad_slot = "0788888658";
179
- google_ad_width = 728;
180
- google_ad_height = 90;
181
- //-->
182
- </script>
183
- <script type="text/javascript"
184
- src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
185
- </script>
186
-
187
- <br/><br/><br/>
188
-
189
- <div class="copyright" width="100%">
190
- <a href="http://rubyworks.github.com/">
191
- <img src="assets/images/ruby-logo.png" height="110px" align="left" style="margin: 0 5px; padding: 0 10px" />
192
- </a>
193
- <a href="http://www.apache.org/licenses/LICENSE-2.0.html">
194
- <img src="assets/images/opensource.png" height="120px" align="left" style="padding: 0 10px;" />
195
- </a>
196
- <a href="github.com/rubyworks/lemon">
197
- <img src="assets/images/github-logo.png" height="115px" align="left" style="margin: 0; padding: 0 10px;" />
198
- </a>
199
- <a href="http://testanything.org/wiki/index.php/Main_Page">
200
- <img src="assets/images/tap.png" height="113px" align="left" style="margin: 0; padding: 0 20px;" />
201
- </a>
202
- <a href="">
203
- <img src="assets/images/lemons-are-good.png" height="117px" align="left" style="margin: 0; padding: 0 10px;" />
204
- </a>
205
- </div>
206
-
207
- <br style="clear: both;" />
208
-
209
- <div style="margin-top: 30px;">
210
- <b>Lemon</b>, Copyright &copy; 2009 Thomas Sawyer &middot;
211
- <b>Contact:</b> transfire @ gmail.com
212
- </div>
213
- </div>
214
- </div>
215
-
216
- </body>
217
- </html>
218
-