specdown 0.4.0.beta.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -9,11 +9,11 @@ Write your README in markdown, and execute it with specdown.
9
9
  When you write a README for a library, a class, a command, etc., you're
10
10
  forced to stop and consider your user:
11
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?
12
+ * How are they going to use it?
13
+ * What kind of API should I provide?
14
+ * How can I convince someone to use my library?
15
15
 
16
- What if you write the README first, before writing your code? This is the
16
+ What if you write the README first, before writing your tests or your code? This is the
17
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
18
  on the topic for a quick introduction to all of its benefits.
19
19
 
@@ -45,236 +45,217 @@ To install the `specdown` ruby gem, simply:
45
45
 
46
46
  It comes with a `specdown` command. Try running it. Doesn't matter where.
47
47
 
48
- ## Usage
48
+ ## Tutorial
49
49
 
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":
50
+ The quickest way to learn specdown is to develop a simple ruby library with it. This tutorial should take about 10 minutes. Feel free to skip to the specdown command line reference at the end of this README.
51
51
 
52
- # Our first test!
52
+ Let's develop a simple todo list library. We'll be using [github-flavored](http://github.github.com/github-flavored-markdown/) markdown for all of our specdown.
53
53
 
54
- This is our very first test. It's going to blow your mind.
54
+ We'll start by describing our library:
55
55
 
56
- ```ruby
57
- raise "WTF?" unless 1 == 1
58
- ```
56
+ Todo
57
+ ====================
59
58
 
60
- Ok, if you've been following along, then `ls -R` should return the following directory structure:
59
+ The `todo` gem provides a simple ruby DSL for managing your TO DO list via IRB.
61
60
 
62
- ```sh
63
- $ ls -R
64
-
65
- specdown/
66
- example.markdown
67
- ```
68
61
 
69
- Great. Now run the `specdown` command:
62
+ Why?
63
+ --------------------------
64
+
65
+ Most people would prefer to manage their TODO list through a website, mobile app, or desktop app.
66
+ But some geeks prefer doing everything in the terminal. If you're that kind of geek, read on.
70
67
 
71
- ```sh
72
- $ specdown
73
68
 
74
- .
69
+ Installation
70
+ --------------------------
75
71
 
76
- 1 markdown
77
- 1 test
78
- 1 success
79
- 0 failures
80
- ```
72
+ To get started, first install the "todo" gem:
81
73
 
82
- Booya!
74
+ $ gem install todo
75
+
76
+ Next, fire up IRB and load your gem:
83
77
 
84
- ### How does it work?
78
+ $ irb
79
+ > require 'rubygems'
80
+ > require 'todo'
81
+
82
+ You're now ready to start interacting with your TODO list via the IRB prompt.
85
83
 
86
- `specdown` loads any "markdown" files it can find inside the "specdown" directory, parses them into trees, then performs exhaustive depth-first searches on the trees to execute the code.
87
84
 
88
- Let's update our README to help illustrate this:
85
+ Our readme tells you what the library is, why you might want to use it, and how to get started.
89
86
 
90
- # Our first test!
87
+ We haven't written any real code yet, but let's go ahead and let specdown take a crack at executing it. Save your readme in your current working directory (I'm going to assume you call it "readme.markdown"), then run `specdown readme.markdown` at the command line.
91
88
 
92
- This is our very first test. It's going to blow your mind.
93
-
94
- ```ruby
95
- raise "WTF?" unless 1 == 1
96
- ```
89
+ $ specdown readme.markdown
90
+
91
+ readme.markdown: ..
97
92
 
98
- ## A Subsection
93
+ 1 markdown
94
+ 2 tests
95
+ 2 passing
96
+ 0 failures
99
97
 
100
- In this section, we're going to create a variable.
98
+ Interesting. Specdown found two tests inside our README, then executed them and found that they were passing. But what were those tests?
101
99
 
102
- ```ruby
103
- name = "moonmaster9000"
104
- ```
100
+ Specdown works by parsing a README into a tree, letting the header structure form the nodes of the tree. Here's what our tree looks like so far:
105
101
 
106
- ### A sub subsection
102
+ #Todo
103
+ / \
104
+ / \
105
+ / \
106
+ / \
107
+ / \
108
+ / \
109
+ / \
110
+ ##Why? ##Installation
107
111
 
108
- In this subsection, we have access to anything created or within scope in parent sections:
112
+ Specdown performs an exhaustive depth-first search on the tree from the root to each leaf, collecting `ruby` codeblocks along the way. Our two tests are thus:
109
113
 
110
- ```ruby
111
- raise "name not in scope" if !defined? name
112
- ```
114
+ * #Todo -> ##Why?
115
+ * #Todo -> ##Installation
113
116
 
114
- ## Another Subsection
117
+ However, at this point we have not yet written any `ruby` code blocks inside our markdown, so the tests are empty (and therefore passing by default). Let's change that. Add the following section to the end of your README:
118
+
119
+ Usage
120
+ -------------------
121
+
122
+ You'll use the `todo` method to interact with your list. For example, to see what's inside your list, simply call the `todo` method:
115
123
 
116
- In this subsection, we don't have access to the "name" variable. Think of your markdown as a tree.
117
-
118
124
  ```ruby
119
- raise "name in scope" if defined? name
125
+ todo #==> []
120
126
  ```
121
127
 
122
- Read through that. I'm giving you some important scoping hints in it.
123
128
 
124
- Save it, run it.
129
+ We've just created our first executable test. When we surrounded the `todo` code with a `ruby` backtick fence, we told specdown to execute that code. The "#==> []" is of course not executable - it's just a comment.
125
130
 
126
- ```sh
127
- $ specdown
131
+ Now if you run the specdown command, you'll get an exception report telling you that the "todo" constant is undefined:
128
132
 
129
- ..
130
-
131
- 1 markdown
132
- 2 tests
133
- 0 failures
134
- ```
133
+ $ specdown readme.markdown
134
+
135
+ readme.markdown: ..F
135
136
 
136
- Notice how the headers in your markdown form a tree?
137
+ ----------------------------
138
+ 1 markdown
139
+ 2 tests
140
+ 1 passing
141
+ 1 failing
142
+ ----------------------------
143
+
144
+ In readme.markdown: #<NameError>: (eval):2:in `execute_code': undefined local variable or method `todo'
137
145
 
138
- ```sh
139
- #Our first test!
140
- / \
141
- / \
142
- / \
143
- / \
144
- / \
145
- / \
146
- / \
147
- ##A Subection ##Another Subsection
148
- /
149
- /
150
- /
151
- ###A sub subsection
152
- ```
153
146
 
154
- Specdown turned that tree into two tests. The first test (#Our first test! --> ##A Subsection --> ###A sub subsection):
147
+ How can we rectify that?
148
+
149
+ Create a "todo.rb" file inside your current working directory, and add the following code to it:
155
150
 
156
151
  ```ruby
157
- raise "WTF?" unless 1 == 1
158
- name = "moonmaster9000"
159
- raise "name not in scope" if !defined? name
152
+ def todo
153
+ end
160
154
  ```
161
155
 
162
- Here's what the second test looked like (#Our first test! --> ##Another Subsection)
156
+ Then, create a "specdown" directory inside your current working directory and add another ruby file "specdown/env.rb" with the following code:
163
157
 
164
158
  ```ruby
165
- raise "WTF?" unless 1 == 1
166
- raise "name in scope" if defined? name
159
+ $LOAD_PATH.unshift "." # ruby 1.9+
160
+ require "todo"
167
161
  ```
168
162
 
169
- ## Non-executable code blocks
170
-
171
- As of version `0.3.0`, you must surround any codeblocks you
172
- want specdown to execute with a github-flavored backtick fence. This
173
- change is not backwards-compatible with previous versions; you'll need
174
- to update your tests if you want to upgrade to this version.
163
+ Run the specdown command again, and all tests should pass.
175
164
 
176
- I made this change because it's likely that in the process of writing your
177
- specdown, you'll want to add some code into your markdown that you don't want executed.
178
- Perhaps it's code in a different language, or perhaps you're showing off
179
- some command line functionality.
165
+ Next, let's show people how to add items to our `todo` list:
180
166
 
181
- Specdown only executes fenced codeblocks specifically flagged as `ruby`.
182
- Thus, if you want to add some code to your markdown that shouldn't be
183
- executed, then just don't specifically flag it as Ruby:
167
+
168
+ To add an item to your `todo` list, simply pass a string to the `todo!` method:
184
169
 
185
- # Non-Executable Code Blocks
186
-
187
- Here's an example of a non-executing code block:
188
-
189
- $ cd /
190
-
191
- Here's another example of a non-executing code block:
192
-
193
- ```javascript
194
- console.log("I'm javascript, so I won't execute.");
170
+ ```ruby
171
+ todo! 'buy groceries'
195
172
  ```
196
-
197
- A third example:
198
173
 
199
- ```
200
- I'm not flagged as anything, so I won't execute.
201
- ```
174
+ **"buy groceries" is now in your todo list.** Call the `todo` method again to confirm.
175
+
176
+ Lastly, to remove an item from your list, pass it to the `done!` method:
202
177
 
203
- ## Executable codeblocks
204
-
205
- The only way to make a code block execute is to specifically flag it as Ruby
206
-
207
178
  ```ruby
208
- puts "I execute!"
179
+ done! 'buy groceries'
209
180
  ```
181
+
182
+ **Your list should now be empty again**.
210
183
 
211
- ## Implicit Specs
184
+ Notice that we surrounded some assertions with double stars. Run the `specdown` command and it will report an undefined "implicit" assertion:
212
185
 
213
- **Note: This feature requires version 0.4.0.beta.1 or greater.**
186
+ $ specdown readme.markdown
187
+
188
+ readme.markdown: ..U
214
189
 
215
- In all of the examples so far, we've made all code that we want executed
216
- explicit within the markdown. Sometimes, however, it's advantageous to
217
- simply state a specification, and then map that to code
218
- behind-the-scenes. They're conceptually equivalent to cucumber step
219
- definitions.
190
+ ----------------------------
191
+ 1 markdown
192
+ 2 tests
193
+ 1 passing
194
+ 1 undefined
195
+ 0 failures
196
+ ----------------------------
220
197
 
221
- Imagine we've written the following markdown for an imaginary `Article`
222
- model:
223
198
 
224
- # Deleting an article from the database
225
-
226
- Imagine we create the following article:
227
-
228
- ```ruby
229
- article = Article.create :title => "Specdown"
230
- ```
199
+ Now add the following implicit spec definition to a file suffixed with ".specdown":
231
200
 
232
- We can delete the article by simply using the `delete!` method:
233
-
234
- ```ruby
235
- article.delete!
236
- ```
201
+ "buy groceries" is now in your todo list
202
+ ----------------------------------------
237
203
 
238
- **The article should now be deleted from the database.**
204
+ pending # replace this with the code you wish you had
239
205
 
240
- Notice the emphasis around the last sentence. If we execute this with
241
- `specdown`, we'll recieve the following result:
242
206
 
243
- $ specdown
207
+ Your list should now be empty again
208
+ -----------------------------------
244
209
 
245
- 1 markdown
246
- 1 test
247
- 0 passing
248
- 0 failing
249
- 1 undefined
210
+ pending # replace this with the code you wish you had
250
211
 
251
212
 
252
- Now add the following implicit spec definition to a file suffixed with ".specdown":
253
213
 
254
- The article should now be deleted from the database.
255
- ----------------------------------------------------
256
-
257
- pending # replace this with the code you want
214
+ Create a "specdown" directory inside your current working directory, then add markdown to it. (Note: "specdown" files simply contain markdown, but are interpreted by specdown as containing implicit specifications. If you've used cucumber before, you can think of these as something similar to a cucumber step definition.)
258
215
 
259
- If we do as it says and rerun the `specdown` command, we'll receive a
260
- notice that we now have a pending implicit spec. Thus, we could
261
- implement the pending spec like so (assuming we were using RSpec
262
- expectations):
216
+ If you rerun the `specdown` command, you'll get notified that your test is pending now. We can fill in the implicit specifications thusly. I'd like to use RSpec `should` expectations to fill out my tests; luckily, if specdown detects that the "rspec" gem is installed, it will make RSpec expectations available to your tests. Otherwise, it will default to `test/unit` assertions. We can ensure that "rspec" expectations are available in our tests by creating a Gemfile inside our current working directory with the following content:
263
217
 
264
- ```markdown
265
- The article should now be deleted from the database.
266
- ----------------------------------------------------
218
+ source "http://rubygems.org"
267
219
 
268
- Article.all.should be_empty
269
- ```
220
+ gem "rspec"
221
+ gem "specdown"
222
+
223
+ Now run `bundle` at the command line. Next, update your "readme.specdown" file and fill out the tests:
224
+
225
+ "buy groceries" is now in your todo list
226
+ ----------------------------------------
227
+
228
+ todo.should include("buy groceries")
229
+
230
+
231
+ Your list should now be empty again
232
+ -----------------------------------
233
+
234
+ todo.should be_empty
235
+
236
+ Great! Now run `bundle exec specdown readme.markdown` and watch your tests fail! Keep it up, implementing just enough code to get your all of your tests passing.
237
+
238
+ ### Implicit v. Explicit Assertions
270
239
 
271
- The ".specdown" file is simply a markdown file with a different
272
- extension. It should consist simply of headings (of any level) and code blocks. Any other elements within the file will simply be ignore by `specdown`. This allows you to organize the file and add extra comments into it in any way you desire.
240
+ Note that nothing requires us to create implicit assertions. We could have just as easily embedded these assertions in our main readme:
241
+
242
+ To add an item to your `todo` list, simply pass a string to the `todo` method:
243
+
244
+ ```ruby
245
+ todo! 'buy groceries'
246
+ todo.should include('buy groceries')
247
+ ```
248
+
249
+ Call the `todo` method yourself to confirm.
250
+
251
+ Lastly, to remove an item from your list, pass it to the `done!` method:
252
+
253
+ ```ruby
254
+ done! 'buy groceries'
255
+ todo.should be_empty
256
+ ```
273
257
 
274
- Also, Note that we didn't surround our code with a github-flavored backtick
275
- fence. Since ".specdown" files are solely used for defining implicit
276
- specifications, it's assumed that all code blocks (unless they're
277
- spefically marked as something other than ruby) will be executed.
258
+ However, we've sacrificied the readability (and utility) of our README by doing so.
278
259
 
279
260
 
280
261
  ## Setting up your test environment
@@ -397,7 +378,7 @@ The reporter defaults to `Specdown::ColorTerminalReporter`.
397
378
 
398
379
  ### Report format: short or condensed
399
380
 
400
- Currently, we offer two report formats: short, or condensed. Short
381
+ Currently, we offer two report formats: short and condensed. Short
401
382
  offers only the most basic information, whereas `condensed` will provide
402
383
  you with summary details per file.
403
384
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0.beta.3
1
+ 0.4.0
@@ -16,7 +16,7 @@ module Specdown
16
16
  run
17
17
  end
18
18
 
19
- exit(@readmes.count == @readmes.select {|readme| readme.exceptions.empty? && readme.undefined_implicits.empty?}.count)
19
+ exit exit_status
20
20
  end
21
21
 
22
22
  private
@@ -36,5 +36,9 @@ module Specdown
36
36
  @readmes.last.execute
37
37
  end
38
38
  end
39
+
40
+ def exit_status
41
+ @readmes.all? &:passing?
42
+ end
39
43
  end
40
44
  end
@@ -12,6 +12,10 @@ module Specdown
12
12
  build_tests
13
13
  end
14
14
 
15
+ def passing?
16
+ exceptions.empty? && pending_exceptions.empty? && undefined_implicits.empty?
17
+ end
18
+
15
19
  def exceptions
16
20
  @tests.collect(&:exception).compact
17
21
  end
metadata CHANGED
@@ -1,110 +1,80 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: specdown
3
- version: !ruby/object:Gem::Version
4
- hash: 3084443435
5
- prerelease: 6
6
- segments:
7
- - 0
8
- - 4
9
- - 0
10
- - beta
11
- - 3
12
- version: 0.4.0.beta.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ prerelease:
13
6
  platform: ruby
14
- authors:
7
+ authors:
15
8
  - Matt Parker
16
9
  autorequire:
17
10
  bindir: bin
18
11
  cert_chain: []
19
-
20
- date: 2012-01-30 00:00:00 Z
21
- dependencies:
22
- - !ruby/object:Gem::Dependency
12
+ date: 2012-05-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
23
15
  name: gitdown
24
- prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70337292991060 !ruby/object:Gem::Requirement
26
17
  none: false
27
- requirements:
18
+ requirements:
28
19
  - - ~>
29
- - !ruby/object:Gem::Version
30
- hash: 27
31
- segments:
32
- - 0
33
- - 0
34
- - 2
20
+ - !ruby/object:Gem::Version
35
21
  version: 0.0.2
36
22
  type: :runtime
37
- version_requirements: *id001
38
- - !ruby/object:Gem::Dependency
39
- name: term-ansicolor
40
23
  prerelease: false
41
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70337292991060
25
+ - !ruby/object:Gem::Dependency
26
+ name: term-ansicolor
27
+ requirement: &70337292990580 !ruby/object:Gem::Requirement
42
28
  none: false
43
- requirements:
29
+ requirements:
44
30
  - - ~>
45
- - !ruby/object:Gem::Version
46
- hash: 25
47
- segments:
48
- - 1
49
- - 0
50
- - 7
31
+ - !ruby/object:Gem::Version
51
32
  version: 1.0.7
52
33
  type: :runtime
53
- version_requirements: *id002
54
- - !ruby/object:Gem::Dependency
55
- name: hook
56
34
  prerelease: false
57
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70337292990580
36
+ - !ruby/object:Gem::Dependency
37
+ name: hook
38
+ requirement: &70337292990120 !ruby/object:Gem::Requirement
58
39
  none: false
59
- requirements:
40
+ requirements:
60
41
  - - ~>
61
- - !ruby/object:Gem::Version
62
- hash: 27
63
- segments:
64
- - 0
65
- - 0
66
- - 2
42
+ - !ruby/object:Gem::Version
67
43
  version: 0.0.2
68
44
  type: :runtime
69
- version_requirements: *id003
70
- - !ruby/object:Gem::Dependency
71
- name: cucumber
72
45
  prerelease: false
73
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70337292990120
47
+ - !ruby/object:Gem::Dependency
48
+ name: cucumber
49
+ requirement: &70337292989740 !ruby/object:Gem::Requirement
74
50
  none: false
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- hash: 3
79
- segments:
80
- - 0
81
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
82
55
  type: :development
83
- version_requirements: *id004
84
- - !ruby/object:Gem::Dependency
85
- name: rspec
86
56
  prerelease: false
87
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *70337292989740
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70337287099060 !ruby/object:Gem::Requirement
88
61
  none: false
89
- requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- hash: 3
93
- segments:
94
- - 0
95
- version: "0"
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
96
66
  type: :development
97
- version_requirements: *id005
67
+ prerelease: false
68
+ version_requirements: *70337287099060
98
69
  description:
99
70
  email: moonmaster9000@gmail.com
100
- executables:
71
+ executables:
101
72
  - specdown
102
73
  extensions: []
103
-
104
- extra_rdoc_files:
74
+ extra_rdoc_files:
105
75
  - CHANGELOG.markdown
106
76
  - README.markdown
107
- files:
77
+ files:
108
78
  - VERSION
109
79
  - lib/specdown/command/option_parser.rb
110
80
  - lib/specdown/command.rb
@@ -209,40 +179,29 @@ files:
209
179
  - features/test.feature
210
180
  homepage: http://github.com/moonmaster9000/specdown
211
181
  licenses: []
212
-
213
182
  post_install_message:
214
183
  rdoc_options: []
215
-
216
- require_paths:
184
+ require_paths:
217
185
  - lib
218
- required_ruby_version: !ruby/object:Gem::Requirement
186
+ required_ruby_version: !ruby/object:Gem::Requirement
219
187
  none: false
220
- requirements:
221
- - - ">="
222
- - !ruby/object:Gem::Version
223
- hash: 3
224
- segments:
225
- - 0
226
- version: "0"
227
- required_rubygems_version: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ! '>='
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ required_rubygems_version: !ruby/object:Gem::Requirement
228
193
  none: false
229
- requirements:
230
- - - ">"
231
- - !ruby/object:Gem::Version
232
- hash: 25
233
- segments:
234
- - 1
235
- - 3
236
- - 1
237
- version: 1.3.1
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
238
198
  requirements: []
239
-
240
199
  rubyforge_project:
241
- rubygems_version: 1.8.10
200
+ rubygems_version: 1.8.17
242
201
  signing_key:
243
202
  specification_version: 3
244
203
  summary: Write your specs as if they were a README, then EXECUTE them.
245
- test_files:
204
+ test_files:
246
205
  - features/command.feature
247
206
  - features/config.feature
248
207
  - features/event_server.feature