specdown 0.2.1 → 0.3.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.
- data/CHANGELOG.markdown +31 -0
- data/README.markdown +95 -29
- data/VERSION +1 -1
- data/features/command.feature +40 -28
- data/features/fixtures/multiple_codeblocks_per_section_example.markdown +11 -0
- data/features/fixtures/non_executing_example.markdown +29 -0
- data/features/fixtures/parser_example.markdown +10 -4
- data/features/parser.feature +111 -19
- data/features/report_summary.feature +10 -4
- data/features/runner.feature +21 -9
- data/features/specdown_examples/after_hooks/specdown/parser_example.markdown +11 -4
- data/features/specdown_examples/around_hooks/specdown/parser_example.markdown +3 -1
- data/features/specdown_examples/before_hooks/specdown/parser_example.markdown +9 -4
- data/features/specdown_examples/no_ruby/specdown/parser_example.markdown +9 -4
- data/features/specdown_examples/scoped_hooks/specdown/parser_example.markdown +12 -5
- data/features/specdown_examples/scoped_hooks/specdown/spec1.fun.markdown +3 -1
- data/features/specdown_examples/scoped_hooks/specdown/spec2.fun.markdown +3 -2
- data/features/specdown_examples/scoped_hooks/specdown/spec3.markdown +3 -2
- data/features/specdown_examples/with_ruby/specdown/parser_example.markdown +9 -4
- data/features/step_definitions/parser.rb +21 -1
- data/lib/specdown/parser.rb +2 -2
- metadata +14 -10
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,36 @@
|
|
1
1
|
## CHANGELOG
|
2
2
|
|
3
|
+
## 0.3.0
|
4
|
+
|
5
|
+
NOTICE: Non-backwards compatible release.
|
6
|
+
|
7
|
+
specdown now supports github-flavored fenced codeblocks!
|
8
|
+
|
9
|
+
If you want your codeblock executed in your tests, you must explicitly
|
10
|
+
mark it as a `ruby` codeblock:
|
11
|
+
|
12
|
+
# Example Markdown
|
13
|
+
|
14
|
+
Specdown will execute the following codeblock:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
I execute
|
18
|
+
```
|
19
|
+
|
20
|
+
Specdown will ignore the following codeblocks:
|
21
|
+
|
22
|
+
```javascript
|
23
|
+
console.log("hi");
|
24
|
+
```
|
25
|
+
|
26
|
+
indented code block
|
27
|
+
|
28
|
+
```
|
29
|
+
this code block is fenced, but not explicitly
|
30
|
+
tagged as ruby. therefore, specdown will not execute
|
31
|
+
it.
|
32
|
+
```
|
33
|
+
|
3
34
|
## 0.2.1
|
4
35
|
|
5
36
|
Bug fix: -f command line option was broken completely. FACE RED :D
|
data/README.markdown
CHANGED
@@ -6,17 +6,38 @@ Write your README in markdown, and execute it with specdown.
|
|
6
6
|
|
7
7
|
## Why?
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
When you write a README for a library, a class, a command, etc., you're
|
10
|
+
forced to stop and consider your user:
|
11
|
+
|
12
|
+
* how are they going to use it?
|
13
|
+
* what's the API
|
14
|
+
* how am I going to convince them to use my library?
|
15
|
+
|
16
|
+
What if you write the README first, before writing your code? This is the
|
17
|
+
premise of README Driven Development. See Tom Preston-Werner's [blog post](http://tom.preston-werner.com/2010/08/23/readme-driven-development.html)
|
18
|
+
on the topic for a quick introduction to all of its benefits.
|
19
|
+
|
20
|
+
### Duplication
|
21
|
+
|
22
|
+
One pain point I've encountered with README Driven Development is
|
23
|
+
duplication between my tests and my documentation. Quite often, I'll end up
|
24
|
+
spending a good deal of time translating most of my README's into executable tests in Cucumber or
|
25
|
+
RSpec. Not only does this lower my productivity, it also forces me to
|
26
|
+
maintain information about my code in two places: the documentation, and
|
27
|
+
the tests.
|
28
|
+
|
29
|
+
Wouldn't it be great if your documentation and your tests were one and
|
30
|
+
the same? For me, this was the promise of Cucumber, a tool I still use
|
31
|
+
and love. However, I find that the repetitive nature of Gherkin, along
|
32
|
+
with the hidden nature of the step definitions, mitigates against the
|
33
|
+
likelihood that my feature files will actually serve as the primary
|
34
|
+
documentation for my project. Readers will tune out when asked to read a page full of
|
35
|
+
repetitive "Given/When/Then" scenarios, or they'll be forced to look elsewhere for the
|
36
|
+
information they need because the step definitions hide the API.
|
16
37
|
|
17
38
|
## Installation
|
18
39
|
|
19
|
-
Right now, specdown only
|
40
|
+
Right now, specdown only supports Ruby. Next, I'll write a javascript implementation. Then, I don't know what language. Regardless, the goal is that you could use specdown with any programming language you desire.
|
20
41
|
|
21
42
|
To install the `specdown` ruby gem, simply:
|
22
43
|
|
@@ -26,15 +47,15 @@ It comes with a `specdown` command. Try running it. Doesn't matter where.
|
|
26
47
|
|
27
48
|
## Usage
|
28
49
|
|
29
|
-
Let's write a simple test in markdown, and execute it with specdown. Create a "specdown" directory, then save the following text into a file inside of it. I'll assume you're calling it "example.markdown":
|
50
|
+
Let's write a simple test in ([github-flavored](http://github.github.com/github-flavored-markdown/)) markdown, and execute it with specdown. Create a "specdown" directory, then save the following text into a file inside of it. I'll assume you're calling it "example.markdown":
|
30
51
|
|
31
|
-
|
32
|
-
# Our first test!
|
52
|
+
# Our first test!
|
33
53
|
|
34
|
-
This is our very first test. It's going to blow your mind.
|
54
|
+
This is our very first test. It's going to blow your mind.
|
35
55
|
|
56
|
+
```ruby
|
36
57
|
raise "WTF?" unless 1 == 1
|
37
|
-
```
|
58
|
+
```
|
38
59
|
|
39
60
|
Ok, if you've been following along, then `ls -R` should return the following directory structure:
|
40
61
|
|
@@ -54,6 +75,7 @@ Great. Now run the `specdown` command:
|
|
54
75
|
|
55
76
|
1 markdown
|
56
77
|
1 test
|
78
|
+
1 success
|
57
79
|
0 failures
|
58
80
|
```
|
59
81
|
|
@@ -65,31 +87,37 @@ Booya!
|
|
65
87
|
|
66
88
|
Let's update our README to help illustrate this:
|
67
89
|
|
68
|
-
|
69
|
-
# Our first test!
|
70
|
-
|
71
|
-
This is our very first test. It's going to blow your mind.
|
90
|
+
# Our first test!
|
72
91
|
|
92
|
+
This is our very first test. It's going to blow your mind.
|
93
|
+
|
94
|
+
```ruby
|
73
95
|
raise "WTF?" unless 1 == 1
|
96
|
+
```
|
74
97
|
|
75
|
-
## A Subsection
|
98
|
+
## A Subsection
|
76
99
|
|
77
|
-
In this section, we're going to create a variable.
|
100
|
+
In this section, we're going to create a variable.
|
78
101
|
|
102
|
+
```ruby
|
79
103
|
name = "moonmaster9000"
|
104
|
+
```
|
80
105
|
|
81
|
-
### A sub subsection
|
106
|
+
### A sub subsection
|
82
107
|
|
83
|
-
In this subsection, we have access to anything created or within scope in parent sections:
|
108
|
+
In this subsection, we have access to anything created or within scope in parent sections:
|
84
109
|
|
110
|
+
```ruby
|
85
111
|
raise "name not in scope" if !defined? name
|
112
|
+
```
|
86
113
|
|
87
|
-
## Another Subsection
|
88
|
-
|
89
|
-
In this subsection, we don't have access to the "name" variable. Think of your markdown as a tree.
|
114
|
+
## Another Subsection
|
90
115
|
|
116
|
+
In this subsection, we don't have access to the "name" variable. Think of your markdown as a tree.
|
117
|
+
|
118
|
+
```ruby
|
91
119
|
raise "name in scope" if defined? name
|
92
|
-
```
|
120
|
+
```
|
93
121
|
|
94
122
|
Read through that. I'm giving you some important scoping hints in it.
|
95
123
|
|
@@ -138,9 +166,46 @@ raise "WTF?" unless 1 == 1
|
|
138
166
|
raise "name in scope" if defined? name
|
139
167
|
```
|
140
168
|
|
169
|
+
## Non-executing code blocks
|
170
|
+
|
171
|
+
It's likely that in the process of writing your documentation tests, you'll want
|
172
|
+
to add some code into your markdown that you don't want executed.
|
173
|
+
Perhaps it's code in a different language, or perhaps you're showing off
|
174
|
+
some command line functionality.
|
175
|
+
|
176
|
+
Specdown only executes fenced codeblocks specifically flagged as `ruby`.
|
177
|
+
Thus, if you want to add some code to your markdown that shouldn't be
|
178
|
+
executed, then just don't specifically flag it as Ruby:
|
179
|
+
|
180
|
+
# Non-Executing Code Blocks Example
|
181
|
+
|
182
|
+
Here's an example of a non-executing code block:
|
183
|
+
|
184
|
+
$ cd /
|
185
|
+
|
186
|
+
Here's another example of a non-executing code block:
|
187
|
+
|
188
|
+
```javascript
|
189
|
+
console.log("I'm javascript, so I won't execute.");
|
190
|
+
```
|
191
|
+
|
192
|
+
A third example:
|
193
|
+
|
194
|
+
```
|
195
|
+
I'm not flagged as anything, so I won't execute.
|
196
|
+
```
|
197
|
+
|
198
|
+
## Executing codeblocks
|
199
|
+
|
200
|
+
The only way to make a code block execute is to specifically flag it as Ruby
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
puts "I execute!"
|
204
|
+
```
|
205
|
+
|
141
206
|
## Setting up your test environment
|
142
207
|
|
143
|
-
Similar to the cucumber testing framework:
|
208
|
+
Similar to the cucumber testing framework: if you put a ruby file somewhere inside your "specdown" directory, `specdown` will find it and load it.
|
144
209
|
|
145
210
|
### Configuring the Expectation / Assertion framework
|
146
211
|
|
@@ -228,7 +293,7 @@ If you want to run just a single file or a set of files, or a directory of files
|
|
228
293
|
|
229
294
|
```sh
|
230
295
|
$ specdown specdown/test.markdown
|
231
|
-
$ specdown specdown/unit_tests
|
296
|
+
$ specdown specdown/unit_tests specdown/simple.markdown specdown/integration_tests/
|
232
297
|
```
|
233
298
|
|
234
299
|
### Overriding the default root directory
|
@@ -247,7 +312,7 @@ By default, `specdown` will output colorized terminal output. If you'd rather th
|
|
247
312
|
$ specdown -n
|
248
313
|
```
|
249
314
|
|
250
|
-
You can also
|
315
|
+
You can also turn off colorization in your env.rb by setting the
|
251
316
|
reporter to `Specdown::TerminalReporter`:
|
252
317
|
|
253
318
|
```ruby
|
@@ -279,11 +344,12 @@ You can also configure this in your env.rb by setting
|
|
279
344
|
Specdown::Config.format = :condensed
|
280
345
|
```
|
281
346
|
|
282
|
-
The default
|
347
|
+
The default is `:short`.
|
283
348
|
|
284
349
|
## TODO
|
285
350
|
|
286
351
|
This library is still very new, but I am rapidly adding features to it. Here's what is on the immediate horizon:
|
287
352
|
|
353
|
+
* allow flagged text in the markdown to execute code, like a cucumber step definition
|
288
354
|
* offer the option of outputing the actual markdown while it executes, instead of "..F....FF......"
|
289
355
|
* Better stack traces / reporting
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/features/command.feature
CHANGED
@@ -18,27 +18,33 @@ Feature: `specdown` command
|
|
18
18
|
|
19
19
|
Given I have a specdown directory containing a single markdown file:
|
20
20
|
"""
|
21
|
-
|
21
|
+
# Specdown Example
|
22
22
|
|
23
|
-
|
23
|
+
This is an example specdown file.
|
24
24
|
|
25
|
-
|
25
|
+
## Child Node
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
This section is a child node. It contains some ruby code:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
"simple code".should_not be(nil)
|
31
|
+
```
|
30
32
|
|
31
|
-
|
33
|
+
### First Leaf
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
This section has a failure simulation:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
raise "specdown error simulation!"
|
39
|
+
```
|
36
40
|
|
37
|
-
|
41
|
+
## Last Leaf
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
43
|
+
This section is a leaf node. It contains some ruby code:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
1.should satisfy(&:odd?)
|
47
|
+
```
|
42
48
|
"""
|
43
49
|
|
44
50
|
When I run `specdown` with no arguments
|
@@ -56,27 +62,33 @@ Feature: `specdown` command
|
|
56
62
|
Scenario: `specdown` with no arguments, and a specdown directory containing a single ruby file and a single markdown file
|
57
63
|
Given I have a specdown directory containing a markdown file:
|
58
64
|
"""
|
59
|
-
|
65
|
+
# Specdown Example
|
66
|
+
|
67
|
+
This is an example specdown file.
|
60
68
|
|
61
|
-
|
69
|
+
## Child Node
|
62
70
|
|
63
|
-
|
71
|
+
This section is a child node. It contains some ruby code:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
"simple code".should_not be(nil)
|
75
|
+
```
|
64
76
|
|
65
|
-
|
66
|
-
|
67
|
-
"simple code".should_not be(nil)
|
77
|
+
### First Leaf
|
68
78
|
|
69
|
-
|
79
|
+
This section has a failure simulation:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
raise "specdown error simulation!"
|
83
|
+
```
|
70
84
|
|
71
|
-
|
72
|
-
|
73
|
-
raise "specdown error simulation!"
|
85
|
+
## Last Leaf
|
74
86
|
|
75
|
-
|
87
|
+
This section is a leaf node. It contains some ruby code:
|
76
88
|
|
77
|
-
|
78
|
-
|
79
|
-
|
89
|
+
```ruby
|
90
|
+
1.should satisfy(&:odd?)
|
91
|
+
```
|
80
92
|
"""
|
81
93
|
And a single ruby file:
|
82
94
|
"""
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Specdown Example
|
2
|
+
|
3
|
+
This is an example specdown file.
|
4
|
+
|
5
|
+
## Executing Code blocks
|
6
|
+
|
7
|
+
This section contains an executing code block:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
"simple code".should_not be(nil)
|
11
|
+
```
|
12
|
+
|
13
|
+
It also contains a non-executing code block:
|
14
|
+
|
15
|
+
raise "I should not execute!"
|
16
|
+
|
17
|
+
## More non executing code blocks
|
18
|
+
|
19
|
+
This section has two non-executing code blocks:
|
20
|
+
|
21
|
+
```javascript
|
22
|
+
console.log("I won't execute!");
|
23
|
+
```
|
24
|
+
|
25
|
+
and...
|
26
|
+
|
27
|
+
```
|
28
|
+
$ cd /
|
29
|
+
```
|
@@ -6,16 +6,22 @@ This is an example specdown file.
|
|
6
6
|
|
7
7
|
This section is a child node. It contains some ruby code:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
"simple code".should_not be(nil)
|
11
|
+
```
|
10
12
|
|
11
13
|
### First Leaf
|
12
14
|
|
13
15
|
This section has a failure simulation:
|
14
16
|
|
15
|
-
|
17
|
+
```ruby
|
18
|
+
raise "specdown error simulation!"
|
19
|
+
```
|
16
20
|
|
17
21
|
## Last Leaf
|
18
22
|
|
19
23
|
This section is a leaf node. It contains some ruby code:
|
20
|
-
|
21
|
-
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
1.should satisfy(&:odd?)
|
27
|
+
```
|
data/features/parser.feature
CHANGED
@@ -14,20 +14,26 @@ Feature: Specdown Parser
|
|
14
14
|
|
15
15
|
This section is a child node. It contains some ruby code:
|
16
16
|
|
17
|
-
|
17
|
+
```ruby
|
18
|
+
"simple code".should_not be(nil)
|
19
|
+
```
|
18
20
|
|
19
21
|
\### First Leaf
|
20
22
|
|
21
23
|
This section has a failure simulation:
|
22
24
|
|
23
|
-
|
25
|
+
```ruby
|
26
|
+
raise "specdown error simulation!"
|
27
|
+
```
|
24
28
|
|
25
29
|
\## Last Leaf
|
26
30
|
|
27
31
|
This section is a leaf node. It contains some ruby code:
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
1.should satisfy(&:odd?)
|
35
|
+
```
|
36
|
+
README
|
31
37
|
|
32
38
|
As you can see, this forms a tree, with "# Specdown Example" at the root of the tree, and "## Leaf 1" and "## Leaf 2" as the children / leafs.
|
33
39
|
|
@@ -55,27 +61,33 @@ Feature: Specdown Parser
|
|
55
61
|
|
56
62
|
Given the following specdown example file:
|
57
63
|
"""
|
58
|
-
|
64
|
+
# Specdown Example
|
59
65
|
|
60
|
-
|
66
|
+
This is an example specdown file.
|
61
67
|
|
62
|
-
|
68
|
+
## Child Node
|
63
69
|
|
64
|
-
|
65
|
-
|
66
|
-
|
70
|
+
This section is a child node. It contains some ruby code:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
"simple code".should_not be(nil)
|
74
|
+
```
|
67
75
|
|
68
|
-
|
76
|
+
### First Leaf
|
69
77
|
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
This section has a failure simulation:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
raise "specdown error simulation!"
|
82
|
+
```
|
73
83
|
|
74
|
-
|
84
|
+
## Last Leaf
|
75
85
|
|
76
|
-
|
77
|
-
|
78
|
-
|
86
|
+
This section is a leaf node. It contains some ruby code:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
1.should satisfy(&:odd?)
|
90
|
+
```
|
79
91
|
"""
|
80
92
|
|
81
93
|
When I parse it into a tree:
|
@@ -106,3 +118,83 @@ Feature: Specdown Parser
|
|
106
118
|
last_leaf.name.should == "Last Leaf"
|
107
119
|
last_leaf.code.should == "1.should satisfy(&:odd?)"
|
108
120
|
"""
|
121
|
+
|
122
|
+
|
123
|
+
Scenario: Parsing a specdown file
|
124
|
+
|
125
|
+
Given the following specdown example file containing non-executing codeblocks:
|
126
|
+
"""
|
127
|
+
# Specdown Example
|
128
|
+
|
129
|
+
This is an example specdown file.
|
130
|
+
|
131
|
+
## Executing Code blocks
|
132
|
+
|
133
|
+
This section contains an executing code block:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
"simple code".should_not be(nil)
|
137
|
+
```
|
138
|
+
|
139
|
+
It also contains a non-executing code block:
|
140
|
+
|
141
|
+
raise "I should not execute!"
|
142
|
+
|
143
|
+
## More non executing code blocks
|
144
|
+
|
145
|
+
This section has two non-executing code blocks:
|
146
|
+
|
147
|
+
```javascript
|
148
|
+
console.log("I won't execute!");
|
149
|
+
```
|
150
|
+
|
151
|
+
and...
|
152
|
+
|
153
|
+
```
|
154
|
+
$ cd /
|
155
|
+
```
|
156
|
+
"""
|
157
|
+
|
158
|
+
When I parse it into a tree:
|
159
|
+
"""
|
160
|
+
@tree = Specdown::Parser.parse @readme
|
161
|
+
"""
|
162
|
+
|
163
|
+
Then the first leaf should contain only the explicit ruby code:
|
164
|
+
"""
|
165
|
+
@tree.root.children.first.code.should == '"simple code".should_not be(nil)'
|
166
|
+
"""
|
167
|
+
|
168
|
+
And the second leaf should not contain any executable code:
|
169
|
+
"""
|
170
|
+
@tree.root.children.last.code.should be_empty
|
171
|
+
"""
|
172
|
+
|
173
|
+
|
174
|
+
@focus
|
175
|
+
Scenario: Multiple code blocks in a section should join together with newlines
|
176
|
+
|
177
|
+
Given the following specdown example file containing multiple executable codeblocks in a single section:
|
178
|
+
"""
|
179
|
+
# Specdown Example
|
180
|
+
|
181
|
+
This is an example specdown file.
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
hi = 'hello'
|
185
|
+
```
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
puts hi
|
189
|
+
```
|
190
|
+
"""
|
191
|
+
|
192
|
+
When I parse it into a tree:
|
193
|
+
"""
|
194
|
+
@tree = Specdown::Parser.parse @readme
|
195
|
+
"""
|
196
|
+
|
197
|
+
Then the code blocks should be joined together with newlines:
|
198
|
+
"""
|
199
|
+
@tree.root.code.should == "hi = 'hello'\nputs hi"
|
200
|
+
"""
|
@@ -22,19 +22,25 @@ Feature: Specdown::ReportSummary
|
|
22
22
|
|
23
23
|
This section is a child node. It contains some ruby code:
|
24
24
|
|
25
|
-
|
25
|
+
```ruby
|
26
|
+
"simple code".should_not be(nil)
|
27
|
+
```
|
26
28
|
|
27
29
|
### First Leaf
|
28
30
|
|
29
31
|
This section has a failure simulation:
|
30
32
|
|
31
|
-
|
33
|
+
```ruby
|
34
|
+
raise "specdown error simulation!"
|
35
|
+
```
|
32
36
|
|
33
37
|
## Last Leaf
|
34
38
|
|
35
39
|
This section is a leaf node. It contains some ruby code:
|
36
|
-
|
37
|
-
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
1.should satisfy(&:odd?)
|
43
|
+
```
|
38
44
|
"""
|
39
45
|
|
40
46
|
And the following runner:
|
data/features/runner.feature
CHANGED
@@ -12,19 +12,25 @@ Feature: Runner
|
|
12
12
|
|
13
13
|
This section is a child node. It contains some ruby code:
|
14
14
|
|
15
|
-
|
15
|
+
```ruby
|
16
|
+
"simple code".should_not be(nil)
|
17
|
+
```
|
16
18
|
|
17
19
|
\### First Leaf
|
18
20
|
|
19
21
|
This section has a failure simulation:
|
20
22
|
|
21
|
-
|
23
|
+
```ruby
|
24
|
+
raise "specdown error simulation!"
|
25
|
+
```
|
22
26
|
|
23
27
|
\## Last Leaf
|
24
28
|
|
25
29
|
This section is a leaf node. It contains some ruby code:
|
26
|
-
|
27
|
-
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
1.should satisfy(&:odd?)
|
33
|
+
```
|
28
34
|
|
29
35
|
We can generate a `Specdown::Runner` instance and run the tests in our markdown by simply passing the filename on instantiation:
|
30
36
|
|
@@ -42,7 +48,7 @@ Feature: Runner
|
|
42
48
|
|
43
49
|
Scenario: Running tests
|
44
50
|
|
45
|
-
Given the following specdown example file
|
51
|
+
Given the following specdown example file:
|
46
52
|
"""
|
47
53
|
# Specdown Example
|
48
54
|
|
@@ -52,19 +58,25 @@ Feature: Runner
|
|
52
58
|
|
53
59
|
This section is a child node. It contains some ruby code:
|
54
60
|
|
55
|
-
|
61
|
+
```ruby
|
62
|
+
"simple code".should_not be(nil)
|
63
|
+
```
|
56
64
|
|
57
65
|
### First Leaf
|
58
66
|
|
59
67
|
This section has a failure simulation:
|
60
68
|
|
61
|
-
|
69
|
+
```ruby
|
70
|
+
raise "specdown error simulation!"
|
71
|
+
```
|
62
72
|
|
63
73
|
## Last Leaf
|
64
74
|
|
65
75
|
This section is a leaf node. It contains some ruby code:
|
66
|
-
|
67
|
-
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
1.should satisfy(&:odd?)
|
79
|
+
```
|
68
80
|
"""
|
69
81
|
|
70
82
|
When I generate a `Specdown::Runner` instance from it:
|
@@ -6,16 +6,23 @@ This is an example specdown file.
|
|
6
6
|
|
7
7
|
This section is a child node. It contains some ruby code:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
"simple code".should_not be(nil)
|
11
|
+
```
|
10
12
|
|
11
13
|
## First Leaf
|
12
14
|
|
13
15
|
This section has a failure simulation:
|
14
16
|
|
15
|
-
|
17
|
+
```ruby
|
18
|
+
raise "specdown error simulation!"
|
19
|
+
```
|
16
20
|
|
17
21
|
## Last Leaf
|
18
22
|
|
19
23
|
This section is a leaf node. It contains some ruby code:
|
20
|
-
|
21
|
-
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
1.should satisfy(&:odd?)
|
27
|
+
```
|
28
|
+
|
@@ -6,17 +6,22 @@ This is an example specdown file.
|
|
6
6
|
|
7
7
|
This section is a child node. It contains some ruby code:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
"simple code".should_not be(nil)
|
11
|
+
```
|
10
12
|
|
11
13
|
### First Leaf
|
12
14
|
|
13
15
|
This section has a failure simulation:
|
14
16
|
|
15
|
-
|
17
|
+
```ruby
|
18
|
+
raise "specdown error simulation!"
|
19
|
+
```
|
16
20
|
|
17
21
|
## Last Leaf
|
18
22
|
|
19
23
|
This section is a leaf node. It contains some ruby code:
|
20
|
-
|
21
|
-
1.should satisfy(&:odd?)
|
22
24
|
|
25
|
+
```ruby
|
26
|
+
1.should satisfy(&:odd?)
|
27
|
+
```
|
@@ -6,17 +6,22 @@ This is an example specdown file.
|
|
6
6
|
|
7
7
|
This section is a child node. It contains some ruby code:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
"simple code".should_not be(nil)
|
11
|
+
```
|
10
12
|
|
11
13
|
### First Leaf
|
12
14
|
|
13
15
|
This section has a failure simulation:
|
14
16
|
|
15
|
-
|
17
|
+
```ruby
|
18
|
+
raise "specdown error simulation!"
|
19
|
+
```
|
16
20
|
|
17
21
|
## Last Leaf
|
18
22
|
|
19
23
|
This section is a leaf node. It contains some ruby code:
|
20
|
-
|
21
|
-
1.should satisfy(&:odd?)
|
22
24
|
|
25
|
+
```ruby
|
26
|
+
1.should satisfy(&:odd?)
|
27
|
+
```
|
@@ -6,16 +6,23 @@ This is an example specdown file.
|
|
6
6
|
|
7
7
|
This section is a child node. It contains some ruby code:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
"simple code".should_not be(nil)
|
11
|
+
```
|
10
12
|
|
11
|
-
|
13
|
+
### First Leaf
|
12
14
|
|
13
15
|
This section has a failure simulation:
|
14
16
|
|
15
|
-
|
17
|
+
```ruby
|
18
|
+
raise "specdown error simulation!"
|
19
|
+
```
|
16
20
|
|
17
21
|
## Last Leaf
|
18
22
|
|
19
23
|
This section is a leaf node. It contains some ruby code:
|
20
|
-
|
21
|
-
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
1.should satisfy(&:odd?)
|
27
|
+
```
|
28
|
+
|
@@ -6,17 +6,22 @@ This is an example specdown file.
|
|
6
6
|
|
7
7
|
This section is a child node. It contains some ruby code:
|
8
8
|
|
9
|
-
|
9
|
+
```ruby
|
10
|
+
"simple code".should_not be(nil)
|
11
|
+
```
|
10
12
|
|
11
13
|
### First Leaf
|
12
14
|
|
13
15
|
This section has a failure simulation:
|
14
16
|
|
15
|
-
|
17
|
+
```ruby
|
18
|
+
raise "specdown error simulation!"
|
19
|
+
```
|
16
20
|
|
17
21
|
## Last Leaf
|
18
22
|
|
19
23
|
This section is a leaf node. It contains some ruby code:
|
20
|
-
|
21
|
-
1.should satisfy(&:odd?)
|
22
24
|
|
25
|
+
```ruby
|
26
|
+
1.should satisfy(&:odd?)
|
27
|
+
```
|
@@ -1,7 +1,15 @@
|
|
1
|
-
Given /^the following specdown example file
|
1
|
+
Given /^the following specdown example file containing non\-executing codeblocks:$/ do |string|
|
2
|
+
@readme = File.read "features/fixtures/non_executing_example.markdown"
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^the following specdown example file:$/ do |string|
|
2
6
|
@readme = File.read "features/fixtures/parser_example.markdown"
|
3
7
|
end
|
4
8
|
|
9
|
+
Given /^the following specdown example file containing multiple executable codeblocks in a single section:$/ do |string|
|
10
|
+
@readme = File.read "features/fixtures/multiple_codeblocks_per_section_example.markdown"
|
11
|
+
end
|
12
|
+
|
5
13
|
When /^I parse it into a tree:$/ do |string|
|
6
14
|
eval string
|
7
15
|
end
|
@@ -13,3 +21,15 @@ end
|
|
13
21
|
Then /^the root should have two children:$/ do |string|
|
14
22
|
eval string
|
15
23
|
end
|
24
|
+
|
25
|
+
Then /^the first leaf should contain only the explicit ruby code:$/ do |string|
|
26
|
+
eval string
|
27
|
+
end
|
28
|
+
|
29
|
+
Then /^the second leaf should not contain any executable code:$/ do |string|
|
30
|
+
eval string
|
31
|
+
end
|
32
|
+
|
33
|
+
Then /^the code blocks should be joined together with newlines:$/ do |string|
|
34
|
+
eval string
|
35
|
+
end
|
data/lib/specdown/parser.rb
CHANGED
@@ -3,7 +3,7 @@ module Specdown
|
|
3
3
|
extend self
|
4
4
|
|
5
5
|
def parse(readme)
|
6
|
-
kramdown = Kramdown::Document.new readme, :input =>
|
6
|
+
kramdown = Kramdown::Document.new readme, :input => "GithubMarkdown"
|
7
7
|
build_tree kramdown.root.children
|
8
8
|
end
|
9
9
|
|
@@ -43,7 +43,7 @@ module Specdown
|
|
43
43
|
|
44
44
|
while !parsed_elements.empty? && parsed_elements.first.type != :header
|
45
45
|
element = parsed_elements.shift
|
46
|
-
node.code += element.value if element.type == :codeblock
|
46
|
+
node.code += "\n" + element.value.to_s.strip if element.type == :codeblock && element.options["language"] == "ruby"
|
47
47
|
node.contents += element.value.to_s + element.children.map(&:value).join
|
48
48
|
end
|
49
49
|
node
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: specdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matt Parker
|
@@ -15,22 +15,22 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-01-
|
18
|
+
date: 2012-01-16 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
21
|
+
name: gitdown
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
24
|
none: false
|
25
25
|
requirements:
|
26
26
|
- - ~>
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
hash:
|
28
|
+
hash: 27
|
29
29
|
segments:
|
30
30
|
- 0
|
31
|
-
-
|
32
|
-
-
|
33
|
-
version: 0.
|
31
|
+
- 0
|
32
|
+
- 2
|
33
|
+
version: 0.0.2
|
34
34
|
type: :runtime
|
35
35
|
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -127,6 +127,8 @@ files:
|
|
127
127
|
- features/config.feature
|
128
128
|
- features/event_server.feature
|
129
129
|
- features/exception_facade.feature
|
130
|
+
- features/fixtures/multiple_codeblocks_per_section_example.markdown
|
131
|
+
- features/fixtures/non_executing_example.markdown
|
130
132
|
- features/fixtures/parser_example.markdown
|
131
133
|
- features/hooks.feature
|
132
134
|
- features/parser.feature
|
@@ -208,6 +210,8 @@ test_files:
|
|
208
210
|
- features/config.feature
|
209
211
|
- features/event_server.feature
|
210
212
|
- features/exception_facade.feature
|
213
|
+
- features/fixtures/multiple_codeblocks_per_section_example.markdown
|
214
|
+
- features/fixtures/non_executing_example.markdown
|
211
215
|
- features/fixtures/parser_example.markdown
|
212
216
|
- features/hooks.feature
|
213
217
|
- features/parser.feature
|