qed 2.9.2 → 3.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9e530292395f42320e28980726cf658819f4686d
4
- data.tar.gz: 9e5c260cc8e20d143b0acd43c1869a0a15b0cbdd
2
+ SHA256:
3
+ metadata.gz: 0641d46bfe700cfdd8b44f9e6e50242fa08dd47950ead38b785b1c8bd2d99008
4
+ data.tar.gz: 658fbcd892cbed202703946fb8745fcbd7b3a06b938bdaf62c525961418e7cc3
5
5
  SHA512:
6
- metadata.gz: fdab04bf50e170ba6e3b85f102e83e43764d342406004756760f8a378545dc940e6db7c05c8a80340fb50f4e3e63db02772c661bc60a7e928d17fd8f29df6ba1
7
- data.tar.gz: 7821741e5709f7aa68f8cd60c75c2e1264fab196912e36a51731bd70bb3b7de536865741cccfc7c9b9d7309ee2d8667528cb3cb4bb2cf7db65324b8f0086e168
6
+ metadata.gz: 9a65c7101c15ed6d98ccd4353a388497f6dacb45bb96f71bf8ed03002ce6e8f1c9acc9b5b4cbe7a5bce9b182507ac2715332ae67ce0b270271c8ddbc0bec7885
7
+ data.tar.gz: 6a37486a0384159148eef66931d25fba51e57ce7352d8f88b73d506f0fd7fe363da709cb247b6d3b56ad2654693d5e8b0a6d70a15384cdf08dad8a356ce176c4
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/HISTORY.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # RELEASE HISTORY
2
2
 
3
+ ## 3.0.0 | 2026-03-31
4
+
5
+ Major modernization release after a long hiatus.
6
+
7
+ Breaking Changes:
8
+
9
+ * Requires Ruby 3.1 or later (dropped Ruby 1.8/1.9/2.x support).
10
+ * Removed Indexer gemspec system; uses standard gemspec.
11
+ * Removed Detroit Assembly; uses standard Rakefile.
12
+
13
+ New Features:
14
+
15
+ * Fenced code block support in parser (#23).
16
+ Bare and ```ruby blocks are executed; other languages are skipped.
17
+ * Restored and modernized HTML reporter with --html flag (#13).
18
+ * GitHub Actions CI replacing Travis CI.
19
+ * Website moved from gh-pages branch to docs/ directory.
20
+
21
+ Bug Fixes:
22
+
23
+ * Fix --version crash due to VERSION not being loaded (#26).
24
+ * Fix --help crash from undefined `settings` in cli_parse (#22, #26).
25
+ * Fix --copyright showing wrong license (Apache 2.0 -> BSD-2-Clause) (#26).
26
+ * Fix --rooted flag not actually running from project root (#21).
27
+ * Fix TapY reporter crash referencing `assertion` instead of `exception` (#24).
28
+
29
+ Dependencies:
30
+
31
+ * Switch markdown processing from rdiscount to kramdown (#20).
32
+ * Remove instance_exec polyfill for Ruby 1.8.
33
+ * Remove old RubyGems compatibility checks from gemspec.
34
+ * Drop rulebow, RC, and Facets dependencies.
35
+ * Require ansi ~> 1.6, brass ~> 1.3, ae ~> 1.9 (dev).
36
+
37
+
3
38
  ## 2.9.2 | 2014-02-24
4
39
 
5
40
  This release removes the dependency on Facets. There were only two important
data/README.md CHANGED
@@ -1,12 +1,9 @@
1
1
  # Ruby Q.E.D.
2
2
 
3
- [Homepage](http://rubyworks.github.com/qed) /
4
- [Documentation](http://rubydoc.info/gems/qed/frames) /
5
- [Report Issue](http://github.com/rubyworks/qed/issues) /
6
- [Development](http://github.com/rubyworks/qed) /
7
- [Mailing list](http://groups.google.com/group/rubyworks-mailinglist)    
8
- [![Build Status](https://secure.travis-ci.org/rubyworks/qed.png)](http://travis-ci.org/rubyworks/qed)
9
- [![Gem Version](https://badge.fury.io/rb/qed.png)](http://badge.fury.io/rb/qed)
3
+ [Homepage](https://rubyworks.github.io/qed) /
4
+ [Documentation](https://rubydoc.info/gems/qed/frames) /
5
+ [Report Issue](https://github.com/rubyworks/qed/issues) /
6
+ [Development](https://github.com/rubyworks/qed)
10
7
 
11
8
 
12
9
  ## Introduction
@@ -15,12 +12,12 @@ Q.E.D. is an abbreviation for the well known Latin phrase "Quod Erat Demonstrand
15
12
  literally "which was to be demonstrated", which is oft written in its abbreviated
16
13
  form at the end of a mathematical proof or philosophical argument to signify
17
14
  a successful conclusion. And so it is too for Ruby Q.E.D., though it might as easily
18
- be taken to stand for "Quality Ensured Documentation".
15
+ be taken to stand for "Quality Ensured Documentation".
19
16
 
20
17
  QED is in fact both a test framework and a documentation system for Ruby
21
18
  developers. QED sits somewhere between lower-level testing tools like Test::Unit
22
19
  and grandiose requirement specifications systems like Cucumber. In practice it
23
- works exceptionally well for <i>API-Driven Design</i>, which is especially
20
+ works exceptionally well for *API-Driven Design*, which is especially
24
21
  useful when designing reusable libraries, but it can be used to test code at
25
22
  any level of abstraction, from unit test to systems tests.
26
23
 
@@ -28,10 +25,12 @@ any level of abstraction, from unit test to systems tests.
28
25
  ## Features
29
26
 
30
27
  * Write tests and documentation in the same breath!
31
- * Demos can be RDoc, Markdown or any other conforming text format.
32
- * Can use any BRASS compliant assertion framework, such as the the excellent AE (Assertive Expressive) library.
33
- * Data and Table macros allows large sets of data to be tested by the same code.
34
- * Documentation tool provides nice output with jQuery-based TOC.
28
+ * Demos can be Markdown or RDoc format.
29
+ * Supports fenced code blocks non-Ruby blocks (e.g. ` ```elixir `) are automatically skipped.
30
+ * Can use any BRASS compliant assertion framework, such as the excellent AE (Assertive Expressive) library.
31
+ * Data and Table macros allow large sets of data to be tested by the same code.
32
+ * HTML report generation via `--html` flag.
33
+ * Documentation tool (`qedoc`) generates browsable HTML from demos.
35
34
 
36
35
 
37
36
  ## Synopsis
@@ -40,7 +39,7 @@ any level of abstraction, from unit test to systems tests.
40
39
 
41
40
  QED can use any BRASS compliant assertions framework. Simply require the library in
42
41
  ones applique (see below). Traditionally this has been the AE (Assertive Expressive) library,
43
- which provides an elegant means to make assertions. To give a quick overview, assertion
42
+ which provides an elegant means to make assertions. To give a quick overview, assertions
44
43
  can be written as:
45
44
 
46
45
  4.assert == 5
@@ -49,16 +48,16 @@ In this example, because 4 != 5, this expression will raise an Assertion
49
48
  exception. QED's Runner class is thus just a means of running and capturing
50
49
  code blocks containing such assertions.
51
50
 
52
- You can learn more about BRASS and AE at http://rubyworks.github.com/brass and
53
- http://rubyworks.github.com/ae, repectively.
51
+ You can learn more about BRASS and AE at https://github.com/rubyworks/brass and
52
+ https://github.com/rubyworks/ae, respectively.
54
53
 
55
54
  ### Document Structure
56
55
 
57
56
  QED documents are simply text files called *demonstrandum* (demos for short).
58
57
  Because they largely consist of free-form descriptive text, they are a practice
59
- pure Literate Programming. For example:
58
+ of pure Literate Programming. For example:
60
59
 
61
- = Example
60
+ # Example
62
61
 
63
62
  Shows that the number 5 does not equal 4.
64
63
 
@@ -68,18 +67,24 @@ pure Literate Programming. For example:
68
67
 
69
68
  5.assert == 5
70
69
 
71
- In this example RDoc was chosen for the document format. However, almost any
72
- text format can be used. The only necessary distinction is that description text
73
- align to the left margin and all code be indented, although QED does recognize
74
- RDoc and Markdown single-line style headers, so any format that supports
75
- those (which covers many markup formats in use today) will have mildly
76
- improved console output. In any case, the essential take away here is that
77
- QED *demonstrandum* are simply descriptive documents with interspersed
78
- blocks of example code.
70
+ Description text aligns to the left margin and all code is indented. QED also
71
+ supports fenced code blocks:
79
72
 
80
- Give this design some thought. It should become clear that this approach is
81
- especially fruitful in that it allows *documentation* and *specification*
82
- to seamlessly merge into a unified *demonstration*.
73
+ ```ruby
74
+ 5.assert == 5
75
+ ```
76
+
77
+ Blocks tagged with a non-Ruby language are skipped during execution, which is
78
+ useful for multi-language documentation:
79
+
80
+ ```javascript
81
+ // This is not executed
82
+ console.log("hello");
83
+ ```
84
+
85
+ QED recognizes Markdown and RDoc headers for improved console output. The
86
+ essential take away is that QED *demonstrandum* are simply descriptive
87
+ documents with interspersed blocks of example code.
83
88
 
84
89
  ### Running Demonstrations
85
90
 
@@ -87,22 +92,22 @@ If we were to run the above document through QED in verbatim mode the output
87
92
  would be identical (assuming we did not make a typo and the assertions passed).
88
93
  If there were errors or failures, we would see information detailing each.
89
94
 
90
- To run a document through QED, simply use the +qed+ command.
95
+ To run a document through QED, simply use the `qed` command.
91
96
 
92
- $ qed -v demo/01_example.rdoc
97
+ $ qed -v demo/01_example.md
93
98
 
94
- The `-v` option specifies verbatim mode, which outputs the entire
95
- document.
99
+ The `-v` option specifies verbatim mode, which outputs the entire document.
96
100
 
97
101
  Notice we placed the QED document in a `demo/` directory. This is the
98
- canonical location, but there is no place that demonstrations have to go. They
99
- can be placed anywhere that is preferred. However, the `qed` command
100
- will look for `qed/`, `demo/`, `demos/` and `spec/`, in that order, if no
101
- path is given.
102
+ canonical location, but demonstrations can be placed anywhere. The `qed`
103
+ command will look for `qed/`, `demo/`, `demos/` and `spec/`, in that order,
104
+ if no path is given.
105
+
106
+ The `01_` prefix helps order documents when generating QED documentation.
107
+
108
+ To generate an HTML test report:
102
109
 
103
- Also notice the use of ``01_`` prefix in front of the file name.
104
- While this is not strictly necessary, QED sorts the documents, so it helps order
105
- the documents nicely, in particular when generating QED documentation ("QEDocs").
110
+ $ qed --html > report.html
106
111
 
107
112
  ### Utilizing Applique
108
113
 
@@ -110,9 +115,9 @@ QED demonstrandum descriptive text is not strictly passive explanation. Using
110
115
  pattern matching techniques, document phrases can trigger underlying actions.
111
116
  These actions provide a support structure for running tests called the *applique*.
112
117
 
113
- Creating an applique is easy. Along with your QED scripts, to which the
118
+ Creating an applique is easy. Along with your QED scripts, to which the
114
119
  applique will apply, create an `applique/` directory. In this
115
- directory add Ruby scripts. When you run your demos every Ruby script in
120
+ directory add Ruby scripts. When you run your demos every Ruby script in
116
121
  the directory will be automatically loaded.
117
122
 
118
123
  Within these applique scripts *advice* can be defined. Advice can be
@@ -126,11 +131,11 @@ phrases in the QED demos. An example would be:
126
131
  end
127
132
 
128
133
  So that whenever the phrase "a new round is started" appears in a demo,
129
- the @round instance variable with be reset to an empty array.
134
+ the @round instance variable will be reset to an empty array.
130
135
 
131
- It is rather amazing what can be accomplished with such a system,
132
- be sure to look at QED's own demonstrandum to get a better notion of
133
- how you can put the the system to use.
136
+ It is rather amazing what can be accomplished with such a system.
137
+ Be sure to look at QED's own demonstrandum to get a better notion of
138
+ how you can put the system to use.
134
139
 
135
140
  ### Configuration
136
141
 
@@ -154,63 +159,53 @@ Or by setting the `profile` environment variable.
154
159
 
155
160
  $ profile=coverage qed
156
161
 
157
- QED can also use the [RC](http://rubyworks.github.com/rc) gem to handle
158
- configuration. Be sure to `gem install rc` and then add this to `.rubyrc`
159
- or `Config.rb` file of the same effect as given above.
160
-
161
- config :qed, :profile=>:coverage do
162
- require 'simplecov'
163
- SimpleCov.start do
164
- coverage_dir 'log/coverage'
165
- end
166
- end
167
-
168
162
  ### Generating Documentation
169
163
 
170
- To generate documentation from QED documents, use the +qedoc+ command.
164
+ To generate documentation from QED documents, use the `qedoc` command.
171
165
 
172
- $ qedoc --output doc/qedoc --title "Example" demo/*.rdoc
166
+ $ qedoc --output doc/demo.html --title "Example" demo/
173
167
 
174
- When documenting, QED recognizes the format by the file extension and
175
- treats it accordingly. An extension of `.qed` is treated the same
176
- as `.rdoc`.
168
+ When documenting, QED recognizes the format by the file extension and
169
+ treats it accordingly.
177
170
 
178
- Use the `--help` options on each command to get more information
171
+ Use the `--help` option on each command to get more information
179
172
  on the use of these commands.
180
173
 
181
174
 
182
175
  ## Requirements
183
176
 
184
- QED depends on the following external libraries:
177
+ QED depends on the following libraries:
178
+
179
+ * [BRASS](https://github.com/rubyworks/brass) - Assertions System
180
+ * [ANSI](https://github.com/rubyworks/ansi) - ANSI Color Codes
181
+ * [kramdown](https://kramdown.gettalong.org/) - Markdown Processing
185
182
 
186
- * [BRASS](http://rubyworks.github.com/brass) - Assertions System
187
- * [ANSI](http://rubyworks.github.com/ansi) - ANSI Color Codes
188
- * [RC](http://rubyworks.github.com/rc) - Runtime Configuration
189
- * [Facets](http://rubyworks.github.com/facets) - Core Extensions
183
+ These will be automatically installed when installing QED via RubyGems.
190
184
 
191
- These will be automatically installed when installing QED via RubyGems,
192
- if they are not already installed.
185
+ Optional libraries that are generally useful with QED:
193
186
 
194
- Optional libraries that are generally useful with QED.
187
+ * [AE](https://github.com/rubyworks/ae) - Assertions Framework
195
188
 
196
- * [AE](http://rubyworks.github.com/ae) - Assertions Framework
189
+ Install AE and require it in your applique to use.
197
190
 
198
- Install these individually and require them in your applique to use.
191
+ Requires Ruby 3.1 or later.
199
192
 
200
193
 
201
194
  ## Development
202
195
 
203
196
  ### Testing
204
197
 
205
- QED uses itself for testing, which can be a bit tricky. But works fine for
206
- the most part. In the future we may add some addition tests via another
207
- test framework to ensure full coverage. But for now QED is proving sufficient.
198
+ QED uses itself for testing. To run the tests:
208
199
 
209
- To run the tests, use `qed` command line tool --ideally use `$ ruby -Ilib bin/qed`
210
- to ensure the current version of QED is being used.
200
+ $ rake demo
211
201
 
212
- For convenience, use `$ fire spec` to run the test specifications. To also
213
- generate a test coverage report use `$ fire spec:cov`.
202
+ Or directly:
203
+
204
+ $ ruby -Ilib bin/qed
205
+
206
+ To generate a test coverage report:
207
+
208
+ $ rake demo:cov
214
209
 
215
210
 
216
211
  ## Copyrights
@@ -220,4 +215,3 @@ generate a test coverage report use `$ fire spec:cov`.
220
215
  Copyright (c) 2009 Rubyworks. All rights reserved.
221
216
 
222
217
  See LICENSE.txt for details.
223
-
@@ -0,0 +1,60 @@
1
+ # Fenced Code Blocks
2
+
3
+ QED supports fenced code blocks using triple backticks in addition
4
+ to the traditional indented code blocks.
5
+
6
+ ## Bare fenced blocks
7
+
8
+ A bare fenced block (no language tag) is treated as Ruby.
9
+
10
+ ```
11
+ x = 1 + 1
12
+ x.assert == 2
13
+ ```
14
+
15
+ ## Ruby-tagged fenced blocks
16
+
17
+ A block explicitly tagged as `ruby` is also executed.
18
+
19
+ ```ruby
20
+ y = "hello"
21
+ y.assert == "hello"
22
+ ```
23
+
24
+ ## Foreign language blocks are skipped
25
+
26
+ Code blocks tagged with any language other than Ruby are ignored.
27
+ This is useful for documentation that includes examples in other
28
+ languages.
29
+
30
+ ```elixir
31
+ # This Elixir code is NOT executed.
32
+ # If it were, QED would raise an error.
33
+ IO.puts "hello from elixir"
34
+ ```
35
+
36
+ ```javascript
37
+ // This JavaScript is also skipped.
38
+ console.log("hello from js");
39
+ ```
40
+
41
+ We can verify that Ruby execution continues normally after
42
+ skipping foreign blocks.
43
+
44
+ z = 42
45
+ z.assert == 42
46
+
47
+ ## Mixed usage
48
+
49
+ Traditional indented blocks and fenced blocks can be used
50
+ together in the same document.
51
+
52
+ a = 10
53
+
54
+ ```ruby
55
+ b = 20
56
+ ```
57
+
58
+ And the results carry across.
59
+
60
+ (a + b).assert == 30
data/lib/qed/cli/qed.rb CHANGED
@@ -10,9 +10,9 @@ module QED
10
10
  #
11
11
  # Session settings are passed to `Session.new`.
12
12
  #
13
- #def self.settings
14
- # @settings ||= Settings.new
15
- #end
13
+ def self.settings
14
+ @settings ||= Settings.new
15
+ end
16
16
 
17
17
  #
18
18
  # Command line interface for running demos.
@@ -56,8 +56,8 @@ module QED
56
56
 
57
57
  options = cli_parse(argv)
58
58
 
59
- settings = Settings.new(options)
60
- session = Session.new(settings)
59
+ @settings = Settings.new(options)
60
+ session = Session.new(@settings)
61
61
  success = session.run
62
62
 
63
63
  exit -1 unless success
@@ -86,9 +86,9 @@ module QED
86
86
  #opt.on('--bullet', '-b', "use bullet-point reporter") do
87
87
  # options[:format] = :bullet
88
88
  #end
89
- #opt.on('--html', '-h', "use underlying HTML reporter") do
90
- # options[:format] = :html
91
- #end
89
+ opt.on('--html', "generate HTML report") do
90
+ options[:format] = :html
91
+ end
92
92
  #opt.on('--script', "psuedo-reporter") do
93
93
  # options[:format] = :script # psuedo-reporter
94
94
  #end
@@ -134,7 +134,7 @@ module QED
134
134
  exit
135
135
  end
136
136
  opt.on_tail('--copyright', "display copyrights") do
137
- puts "Copyright (c) 2008 Thomas Sawyer, Apache 2.0 License"
137
+ puts "Copyright (c) 2008 Thomas Sawyer, BSD-2-Clause License"
138
138
  exit
139
139
  end
140
140
  opt.on_tail('--help', '-h', "display this help message") do
@@ -142,8 +142,7 @@ module QED
142
142
 
143
143
  unless settings.profiles.empty?
144
144
  puts "Available Profiles:"
145
- #require 'confection'
146
- QED.profiles.each do |name|
145
+ settings.profiles.each do |name|
147
146
  next if name.strip == ''
148
147
  puts " -p #{name}"
149
148
  end
data/lib/qed/cli.rb CHANGED
@@ -1,10 +1,5 @@
1
- if RUBY_VERSION < '1.9'
2
- require 'qed/configure'
3
- require 'qed/cli/qed'
4
- require 'qed/cli/qedoc'
5
- else
6
- require_relative 'configure'
7
- require_relative 'cli/qed'
8
- require_relative 'cli/qedoc'
9
- end
1
+ require_relative 'version'
2
+ require_relative 'configure'
3
+ require_relative 'cli/qed'
4
+ require_relative 'cli/qedoc'
10
5
 
data/lib/qed/core_ext.rb CHANGED
@@ -2,38 +2,6 @@ require 'brass'
2
2
 
3
3
  class Object
4
4
 
5
- unless method_defined?(:instance_exec) # 1.9
6
- require 'thread'
7
-
8
- module InstanceExecMethods #:nodoc:
9
- end
10
-
11
- include InstanceExecMethods
12
-
13
- # Evaluate the block with the given arguments within the context of
14
- # this object, so self is set to the method receiver.
15
- #
16
- # From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
17
- #
18
- # This version has been borrowed from Rails for compatibility sake.
19
- def instance_exec(*args, &block)
20
- begin
21
- old_critical, Thread.critical = Thread.critical, true
22
- n = 0
23
- n += 1 while respond_to?(method_name = "__instance_exec#{n}")
24
- InstanceExecMethods.module_eval { define_method(method_name, &block) }
25
- ensure
26
- Thread.critical = old_critical
27
- end
28
-
29
- begin
30
- send(method_name, *args)
31
- ensure
32
- InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
33
- end
34
- end
35
- end
36
-
37
5
  #
38
6
  # This is used by the `#=>` notation.
39
7
  #
data/lib/qed/document.rb CHANGED
@@ -147,10 +147,9 @@ module QED
147
147
  text << txt
148
148
  end
149
149
  when '.md', '.markdown'
150
- require_rdiscount
150
+ require_kramdown
151
151
  if html?
152
- markdown = RDiscount.new(txt)
153
- text << markdown.to_html
152
+ text << Kramdown::Document.new(txt).to_html
154
153
  else
155
154
  text << txt
156
155
  end
@@ -251,9 +250,9 @@ module QED
251
250
  end
252
251
 
253
252
  #
254
- def require_rdiscount
255
- @require_rdiscount ||= (
256
- require 'rdiscount'
253
+ def require_kramdown
254
+ @require_kramdown ||= (
255
+ require 'kramdown'
257
256
  true
258
257
  )
259
258
  end
data/lib/qed/parser.rb CHANGED
@@ -101,30 +101,61 @@ module QED
101
101
  steps = []
102
102
  blank = false
103
103
  indented = false
104
+ fenced = false # inside a ``` ruby/bare code fence
105
+ foreign = false # inside a ``` non-ruby code fence
104
106
  explain = []
105
107
  example = [] #Step.new(file)
106
108
 
107
109
  lines.each do |lineno, line|
108
110
  case line
109
- when /^\s*$/ # blank line
110
- blank = true
111
- if indented
112
- example << [lineno, line]
111
+ when /\A```ruby\s*$/ # ```ruby opens a ruby fence
112
+ fenced = true
113
+ foreign = false
114
+ next
115
+ when /\A```\s*$/ # bare ``` either opens or closes a fence
116
+ if fenced || foreign
117
+ fenced = false
118
+ foreign = false
119
+ next
113
120
  else
114
- explain << [lineno, line]
121
+ fenced = true # bare ``` opens a ruby fence
122
+ next
115
123
  end
116
- when /\A\s+/ #/\A(\t|\ \ +)/ # indented
124
+ when /\A```\S/ # ```<language> opens a foreign fence
125
+ foreign = true
126
+ next
127
+ else
128
+ # skip lines inside foreign code fences
129
+ next if foreign
130
+ end
131
+
132
+ if fenced
133
+ # lines inside a ruby fence are treated as example code
117
134
  indented = true
118
135
  blank = false
119
136
  example << [lineno, line]
120
137
  else
121
- if indented or blank
122
- steps << Step.new(demo, explain, example, steps.last)
123
- explain, example = [], [] #Step.new(file)
138
+ case line
139
+ when /^\s*$/ # blank line
140
+ blank = true
141
+ if indented
142
+ example << [lineno, line]
143
+ else
144
+ explain << [lineno, line]
145
+ end
146
+ when /\A\s+/ # indented
147
+ indented = true
148
+ blank = false
149
+ example << [lineno, line]
150
+ else
151
+ if indented or blank
152
+ steps << Step.new(demo, explain, example, steps.last)
153
+ explain, example = [], []
154
+ end
155
+ indented = false
156
+ blank = false
157
+ explain << [lineno, line]
124
158
  end
125
- indented = false
126
- blank = false
127
- explain << [lineno, line]
128
159
  end
129
160
  end
130
161
  steps << Step.new(demo, explain, example, steps.last)
@@ -1,160 +1,167 @@
1
- # encoding: UTF-8
1
+ require 'erb'
2
+ require 'kramdown'
3
+ require 'qed/reporter/abstract'
2
4
 
3
5
  module QED
4
6
  module Reporter
5
7
 
6
- require 'qed/reporter/abstract'
7
-
8
8
  # = Html Reporter
9
9
  #
10
- # NOTE: This must be completely redesigned since we moved back
11
- # to text based evaluation --which makes generting HTML with
12
- # modifications from the evaluation tricky. But I've come up
13
- # with a farily clever way to handle this. Take the original
14
- # and use Tilt to translate it into HTML, then take the
15
- # evaluation results for code steps and use it to search
16
- # the HTML for "the closest match". Find the \<pre> tag
17
- # associated with the text and add class and color style.
18
- # Of course the tricky part is the matching, but if we
19
- # run the text snippet through Tilt as well we should be
20
- # able to get an exact match. It won't be fast, but it should
21
- # work.
22
-
10
+ # Generates a self-contained HTML report of a QED session,
11
+ # with color-coded pass/fail/error results.
12
+ #
23
13
  class Html < Abstract
24
14
 
25
- #
26
- def initialize(*args)
27
- require 'erb'
28
-
29
- begin
30
- require 'rubygems'
31
- gem 'rdoc'
32
- require 'rdoc'
33
- rescue
34
- end
35
-
36
- super(*args)
37
- end
38
-
39
- #
40
15
  def before_session(session)
41
- io.puts <<-END
42
- <html>
43
- <head>
44
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
45
- <title>QED Report</title>
46
- <style>
47
- body{width:800px; margin:0 auto;}
48
- pre{font-family: courier,monospace;}
49
- .pass{color: #020;}
50
- .pass pre{color: green;}
51
- .fail{color: #200; background: pink;}
52
- .fail pre{color: green;}
53
- .error{color: #200; background: pink;}
54
- .error pre{color: red;}
55
- </style>
56
- </head>
57
- <body>
58
- END
16
+ super(session)
17
+ io.puts HTML_HEAD
59
18
  end
60
19
 
61
- #
62
20
  def before_demo(demo)
63
- io.puts <<-END
64
- <h2>#{localize_file(demo.file)}</h2>
65
- END
21
+ super(demo)
22
+ io.puts %[<div class="demo">]
23
+ io.puts %[<h2 class="demo-file">#{escape(localize_file(demo.file))}</h2>]
66
24
  end
67
25
 
68
26
  def step(step)
69
27
  @_explain = step.explain.dup
70
28
  end
71
29
 
72
- #
73
30
  def match(step, md)
74
- #@match = md
75
31
  unless md[0].empty?
76
- @_explain.sub!(md[0], "<b>#{md[0]}</b>")
32
+ @_explain.sub!(md[0], "<mark>#{escape(md[0])}</mark>")
77
33
  end
78
34
  end
79
35
 
80
- #
81
36
  def pass(step)
82
- io.puts <<-END
83
- <div class="test pass">
84
- #{render(@_explain)}
85
-
86
- <pre>#{step.example}</pre>
87
- </div>
88
- END
37
+ super(step)
38
+ io.puts %[<div class="step pass">]
39
+ io.puts render(@_explain)
40
+ if step.has_example?
41
+ io.puts %[<pre class="code pass">#{escape(step.example)}</pre>]
42
+ end
43
+ io.puts %[</div>]
89
44
  end
90
45
 
91
- #
92
46
  def fail(step, assertion)
93
- io.puts ERB.new(<<-END).result(binding)
94
- <div class="test fail">
95
- #{render(@_explain)}
96
-
97
- <pre>#{step.example}</pre>
98
-
99
- <div class="assertion">
100
- <p>#{assertion.class} - #{assertion.message}</p>
101
- <ol>
102
- <% assertion.backtrace.each do |bt| %>
103
- <li><%= bt %></li>
104
- <% end %>
105
- </ol>
106
- </div>
107
- </div>
108
- END
47
+ super(step, assertion)
48
+ io.puts %[<div class="step fail">]
49
+ io.puts render(@_explain)
50
+ if step.has_example?
51
+ io.puts %[<pre class="code fail">#{escape(step.example)}</pre>]
52
+ end
53
+ io.puts %[<div class="details">]
54
+ io.puts %[<p class="message">FAIL: #{escape(assertion.message)}</p>]
55
+ io.puts %[<pre class="backtrace">#{escape(sane_backtrace(assertion).join("\n"))}</pre>]
56
+ io.puts %[</div>]
57
+ io.puts %[</div>]
109
58
  end
110
59
 
111
- #
112
60
  def error(step, exception)
113
- io.puts ERB.new(<<-END).result(binding)
114
- <div class="test error">
115
- #{render(@_explain)}
116
-
117
- <pre>#{step.example}</pre>
118
-
119
- <div class="exception">
120
- <p>#{exception.class} - #{exception.message}</p>
121
- <ol>
122
- <% exception.backtrace.each do |bt| %>
123
- <li><%= bt %></li>
124
- <% end %>
125
- </ol>
126
- </div>
127
- </div>
128
- END
61
+ super(step, exception)
62
+ io.puts %[<div class="step error">]
63
+ io.puts render(@_explain)
64
+ if step.has_example?
65
+ io.puts %[<pre class="code error">#{escape(step.example)}</pre>]
66
+ end
67
+ io.puts %[<div class="details">]
68
+ io.puts %[<p class="message">ERROR: #{escape(exception.class.to_s)} - #{escape(exception.message)}</p>]
69
+ io.puts %[<pre class="backtrace">#{escape(sane_backtrace(exception).join("\n"))}</pre>]
70
+ io.puts %[</div>]
71
+ io.puts %[</div>]
129
72
  end
130
73
 
131
- #
132
74
  def after_demo(demo)
75
+ super(demo)
76
+ io.puts %[</div>]
133
77
  end
134
78
 
135
- #
136
79
  def after_session(session)
137
- io.puts <<-END
138
- </body>
139
- </html>
140
- END
80
+ super(session)
81
+
82
+ pass_count = passes.size
83
+ fail_count = fails.size
84
+ error_count = errors.size
85
+ total = steps.size
86
+
87
+ status = (fail_count + error_count) == 0 ? 'pass' : 'fail'
88
+
89
+ io.puts %[<div class="summary #{status}">]
90
+ io.puts %[<p>#{demos.size} demos, #{total} steps: #{fail_count} failures, #{error_count} errors</p>]
91
+ io.puts %[<p class="time">Finished in %.5f seconds</p>] % [Time.now - @start_time]
92
+ io.puts %[</div>]
93
+ io.puts HTML_FOOT
141
94
  end
142
95
 
143
96
  private
144
97
 
145
98
  def render(str)
146
- rdoc.convert(str.strip)
99
+ Kramdown::Document.new(str.strip).to_html
147
100
  end
148
101
 
149
- def rdoc
150
- @rdoc ||= RDoc::Markup::ToHtml.new
102
+ def escape(str)
103
+ ERB::Util.html_escape(str.to_s)
151
104
  end
152
105
 
153
- #def h(str)
154
- # ERB::Util.html_escape(str)
155
- #end
156
- end
106
+ HTML_HEAD = <<~'HTML'
107
+ <!DOCTYPE html>
108
+ <html>
109
+ <head>
110
+ <meta charset="utf-8">
111
+ <title>QED Report</title>
112
+ <style>
113
+ * { box-sizing: border-box; margin: 0; padding: 0; }
114
+ body {
115
+ max-width: 860px; margin: 2em auto; padding: 0 1em;
116
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
117
+ font-size: 15px; line-height: 1.6; color: #24292e; background: #fff;
118
+ }
119
+ h1 { font-size: 1.6em; margin: 0 0 1em; padding-bottom: 0.3em; border-bottom: 1px solid #eaecef; }
120
+ h2.demo-file {
121
+ font-size: 1.1em; margin: 1.5em 0 0.5em; padding: 0.4em 0.6em;
122
+ background: #f1f3f5; border-radius: 4px; font-family: monospace;
123
+ }
124
+ .step { margin: 0.5em 0; padding: 0.6em 0.8em; border-left: 3px solid #ddd; }
125
+ .step.pass { border-left-color: #28a745; }
126
+ .step.fail { border-left-color: #d73a49; background: #ffeef0; }
127
+ .step.error { border-left-color: #b31d28; background: #ffeef0; }
128
+ .step p { margin: 0.3em 0; }
129
+ .step h1, .step h2, .step h3 { margin: 0.3em 0; font-size: 1.1em; }
130
+ pre.code {
131
+ margin: 0.4em 0; padding: 0.6em 0.8em;
132
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
133
+ font-size: 13px; line-height: 1.45;
134
+ background: #f6f8fa; border-radius: 4px; overflow-x: auto;
135
+ }
136
+ pre.code.pass { background: #f0fff0; color: #22863a; }
137
+ pre.code.fail { background: #fff0f0; color: #b31d28; }
138
+ pre.code.error { background: #fff0f0; color: #b31d28; }
139
+ .details { margin: 0.4em 0; }
140
+ .details .message { font-weight: 600; color: #d73a49; margin: 0.3em 0; }
141
+ .details .backtrace {
142
+ font-size: 12px; color: #6a737d; background: #fafbfc;
143
+ padding: 0.5em; border-radius: 4px; white-space: pre-wrap;
144
+ }
145
+ .summary {
146
+ margin: 2em 0 1em; padding: 0.8em 1em;
147
+ border-radius: 4px; font-weight: 600;
148
+ }
149
+ .summary.pass { background: #dcffe4; color: #165c26; }
150
+ .summary.fail { background: #ffeef0; color: #b31d28; }
151
+ .summary .time { font-weight: normal; font-size: 0.9em; color: #586069; }
152
+ mark { background: #fff3cd; padding: 0 2px; border-radius: 2px; }
153
+ </style>
154
+ </head>
155
+ <body>
156
+ <h1>QED Report</h1>
157
+ HTML
158
+
159
+ HTML_FOOT = <<~'HTML'
160
+ </body>
161
+ </html>
162
+ HTML
157
163
 
158
- end#module Reporter
159
- end#module QED
164
+ end
160
165
 
166
+ end
167
+ end
@@ -148,8 +148,8 @@ module Reporter #:nodoc:
148
148
  #'expected' => nil,
149
149
  'time' => time_since_start,
150
150
  'exception' => {
151
- 'message' => assertion.message, #unansi
152
- 'class' => assertion.class.name,
151
+ 'message' => exception.message, #unansi
152
+ 'class' => exception.class.name,
153
153
  'file' => file,
154
154
  'line' => line,
155
155
  'source' => source,
data/lib/qed/session.rb CHANGED
@@ -84,7 +84,7 @@ module QED
84
84
 
85
85
  #
86
86
  def directory
87
- settings.tmpdir
87
+ rooted ? settings.root_directory : settings.tmpdir
88
88
  end
89
89
 
90
90
  # Top-level configuration.
@@ -160,7 +160,7 @@ module QED
160
160
 
161
161
  # Clear temporary testing directory.
162
162
  def clear_directory
163
- settings.clear_directory
163
+ settings.clear_directory unless rooted
164
164
  end
165
165
 
166
166
  # Set $ASSERTION_COUNTS to zero point.
@@ -0,0 +1,3 @@
1
+ module QED
2
+ VERSION = '3.0.0'
3
+ end
data/lib/qed.rb CHANGED
@@ -1,24 +1,6 @@
1
- module QED
1
+ require_relative 'qed/version'
2
2
 
3
- # Access to project metadata.
4
- def self.metadata
5
- @metadata ||= (
6
- require 'yaml'
7
- YAML.load(File.new(File.dirname(__FILE__) + '/qed.yml')) rescue {}
8
- )
9
- end
10
-
11
- # Access to project metadata as constants.
12
- def self.const_missing(name)
13
- key = name.to_s.downcase
14
- metadata[key] || super(name)
15
- end
16
-
17
- # TODO: Only b/c of Ruby 1.8.x bug.
18
- VERSION = metadata['version']
19
-
20
- end
3
+ module QED; end
21
4
 
22
5
  require 'qed/session'
23
6
  require 'qed/document'
24
-
metadata CHANGED
@@ -1,86 +1,84 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qed
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - trans
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2015-03-01 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: ansi
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - '>='
16
+ - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '0'
18
+ version: '1.6'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
- - - '>='
23
+ - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: '0'
25
+ version: '1.6'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: brass
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - '>='
30
+ - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '0'
32
+ version: '1.3'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
- - - '>='
37
+ - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '0'
39
+ version: '1.3'
41
40
  - !ruby/object:Gem::Dependency
42
- name: ae
41
+ name: kramdown
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
- - - '>='
44
+ - - "~>"
46
45
  - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
46
+ version: '2.4'
47
+ type: :runtime
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
- - - '>='
51
+ - - "~>"
53
52
  - !ruby/object:Gem::Version
54
- version: '0'
53
+ version: '2.4'
55
54
  - !ruby/object:Gem::Dependency
56
- name: rulebow
55
+ name: ae
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - '>='
58
+ - - "~>"
60
59
  - !ruby/object:Gem::Version
61
- version: '0'
60
+ version: '1.9'
62
61
  type: :development
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
- - - '>='
65
+ - - "~>"
67
66
  - !ruby/object:Gem::Version
68
- version: '0'
67
+ version: '1.9'
69
68
  description: QED (Quality Ensured Demonstrations) is a TDD/BDD framework utilizing
70
69
  Literate Programming techniques.
71
70
  email:
72
71
  - transfire@gmail.com
73
72
  executables:
74
- - qedoc
75
73
  - qed
74
+ - qedoc
76
75
  extensions: []
77
- extra_rdoc_files:
76
+ extra_rdoc_files: []
77
+ files:
78
+ - Gemfile
79
+ - HISTORY.md
78
80
  - LICENSE.txt
79
81
  - README.md
80
- - HISTORY.md
81
- files:
82
- - .index
83
- - .yardopts
84
82
  - bin/qed
85
83
  - bin/qedoc
86
84
  - demo/01_demos.md
@@ -93,6 +91,7 @@ files:
93
91
  - demo/09_cross_script.md
94
92
  - demo/10_constant_lookup.md
95
93
  - demo/11_embedded_rules.md
94
+ - demo/13_fenced_code_blocks.md
96
95
  - demo/99_issues/02_topcode.md
97
96
  - demo/applique/ae.rb
98
97
  - demo/applique/constant.rb
@@ -105,17 +104,18 @@ files:
105
104
  - demo/helpers/toplevel.rb
106
105
  - demo/samples/data.txt
107
106
  - demo/samples/table.yml
107
+ - lib/qed.rb
108
108
  - lib/qed/applique.rb
109
+ - lib/qed/cli.rb
109
110
  - lib/qed/cli/qed.rb
110
111
  - lib/qed/cli/qedoc.rb
111
- - lib/qed/cli.rb
112
112
  - lib/qed/configure.rb
113
113
  - lib/qed/core_ext.rb
114
114
  - lib/qed/demo.rb
115
+ - lib/qed/document.rb
115
116
  - lib/qed/document/jquery.js
116
117
  - lib/qed/document/markup.rb
117
118
  - lib/qed/document/template.rhtml
118
- - lib/qed/document.rb
119
119
  - lib/qed/evaluator.rb
120
120
  - lib/qed/helpers/file_fixtures.rb
121
121
  - lib/qed/helpers/shell_session.rb
@@ -132,34 +132,26 @@ files:
132
132
  - lib/qed/settings.rb
133
133
  - lib/qed/step.rb
134
134
  - lib/qed/utils.rb
135
- - lib/qed.rb
136
- - lib/qed.yml
137
- - LICENSE.txt
138
- - HISTORY.md
139
- - README.md
140
- homepage: http://rubyworks.github.com/qed
135
+ - lib/qed/version.rb
136
+ homepage: https://github.com/rubyworks/qed
141
137
  licenses:
142
138
  - BSD-2-Clause
143
139
  metadata: {}
144
- post_install_message:
145
140
  rdoc_options: []
146
141
  require_paths:
147
142
  - lib
148
143
  required_ruby_version: !ruby/object:Gem::Requirement
149
144
  requirements:
150
- - - '>='
145
+ - - ">="
151
146
  - !ruby/object:Gem::Version
152
- version: '0'
147
+ version: '3.1'
153
148
  required_rubygems_version: !ruby/object:Gem::Requirement
154
149
  requirements:
155
- - - '>='
150
+ - - ">="
156
151
  - !ruby/object:Gem::Version
157
152
  version: '0'
158
153
  requirements: []
159
- rubyforge_project:
160
- rubygems_version: 2.0.3
161
- signing_key:
154
+ rubygems_version: 3.6.9
162
155
  specification_version: 4
163
156
  summary: Quod Erat Demonstrandum
164
157
  test_files: []
165
- has_rdoc:
data/.index DELETED
@@ -1,54 +0,0 @@
1
- ---
2
- revision: 2013
3
- type: ruby
4
- sources:
5
- - Indexfile
6
- authors:
7
- - name: trans
8
- email: transfire@gmail.com
9
- organizations: []
10
- requirements:
11
- - name: ansi
12
- - name: brass
13
- - groups:
14
- - test
15
- development: true
16
- name: ae
17
- - groups:
18
- - build
19
- development: true
20
- name: rulebow
21
- conflicts: []
22
- alternatives: []
23
- resources:
24
- - type: home
25
- uri: http://rubyworks.github.com/qed
26
- label: Homepage
27
- - type: code
28
- uri: http://github.com/rubyworks/qed
29
- label: Source Code
30
- - type: bugs
31
- uri: http://github.com/rubyworks/qed/issues
32
- label: Issue Tracker
33
- repositories:
34
- - name: upstream
35
- scm: git
36
- uri: git://github.com/rubyworks/qed.git
37
- categories: []
38
- copyrights:
39
- - holder: Rubyworks
40
- year: '2006'
41
- license: BSD-2-Clause
42
- customs: []
43
- paths:
44
- lib:
45
- - lib
46
- name: qed
47
- title: QED
48
- version: 2.9.2
49
- summary: Quod Erat Demonstrandum
50
- description: QED (Quality Ensured Demonstrations) is a TDD/BDD framework utilizing
51
- Literate Programming techniques.
52
- created: '2009-06-16'
53
- webcvs: http://github.com/rubyworks/qed/blob/master/
54
- date: '2015-03-01'
data/.yardopts DELETED
@@ -1,10 +0,0 @@
1
- --plugin qed
2
- --output-dir doc
3
- --readme README.md
4
- --title "Q.E.D."
5
- --protected
6
- --private
7
- lib
8
- -
9
- *.md
10
- *.txt
data/lib/qed.yml DELETED
@@ -1,54 +0,0 @@
1
- ---
2
- revision: 2013
3
- type: ruby
4
- sources:
5
- - Indexfile
6
- authors:
7
- - name: trans
8
- email: transfire@gmail.com
9
- organizations: []
10
- requirements:
11
- - name: ansi
12
- - name: brass
13
- - groups:
14
- - test
15
- development: true
16
- name: ae
17
- - groups:
18
- - build
19
- development: true
20
- name: rulebow
21
- conflicts: []
22
- alternatives: []
23
- resources:
24
- - type: home
25
- uri: http://rubyworks.github.com/qed
26
- label: Homepage
27
- - type: code
28
- uri: http://github.com/rubyworks/qed
29
- label: Source Code
30
- - type: bugs
31
- uri: http://github.com/rubyworks/qed/issues
32
- label: Issue Tracker
33
- repositories:
34
- - name: upstream
35
- scm: git
36
- uri: git://github.com/rubyworks/qed.git
37
- categories: []
38
- copyrights:
39
- - holder: Rubyworks
40
- year: '2006'
41
- license: BSD-2-Clause
42
- customs: []
43
- paths:
44
- lib:
45
- - lib
46
- name: qed
47
- title: QED
48
- version: 2.9.2
49
- summary: Quod Erat Demonstrandum
50
- description: QED (Quality Ensured Demonstrations) is a TDD/BDD framework utilizing
51
- Literate Programming techniques.
52
- created: '2009-06-16'
53
- webcvs: http://github.com/rubyworks/qed/blob/master/
54
- date: '2015-03-01'