specdown 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|