docspec 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50f8d84c839b9b2c42002526d2a71b7ba77c3e4593e3bd11707b15437b8ff8fd
4
- data.tar.gz: 03b17f9c88a24ac31c405954aadd080b65b8c288ccb3f8b92d25b3ec45d03017
3
+ metadata.gz: ad249396cfc15361e8f19e3932b5c75ab565b5042ce3431204daf0a39d4f0a14
4
+ data.tar.gz: a0772e8fd3692466756215f0786709fae4c0772248d1715a0503810a7e0af719
5
5
  SHA512:
6
- metadata.gz: ad12b1aa05ab33e0fa3d506375c7f5de01edd4da59c3423d995af02b642ce56b6d08820fa0ea602998b6f895e4be8e2b0b2b5cbb4774f46cec4a1e19e7fb26ed
7
- data.tar.gz: ed148aa6718aaa0b9c624e9af55b0029a115a6cb48e710d55acb1029ebce895001e5ff77ae9af8c0ee3cdac39cb4972a994a94a2490040dcf1322dce59fab18f
6
+ metadata.gz: 4985a1fcb629b102bd560fc4a33bb24d18b0ef91368619cfbcc1f053ac2ac3fffa15426e81f1826de87bebeb5233ad4d416551f8eaad9c52f2513cd273d0b04f
7
+ data.tar.gz: cae6a31e132105853a6015d53d39a3d0ad13bbd99b94fd03e10bedada81e635d7409a2495940d98d9447ff51e9f8249de719e5bd8dfa1aec8a1c4af8dd2a52cc
data/README.md CHANGED
@@ -20,40 +20,49 @@ Installation
20
20
  Usage
21
21
  --------------------------------------------------
22
22
 
23
- Add ruby or shell code blocks to your `README.md` document, then run
24
- `docspec` to evaluate them.
23
+ Docspec expects one or more Markdown files with embedded code snippets to
24
+ test.
25
25
 
26
+ Code snippets should be enclosed in a `ruby` or `shell` code fence:
26
27
 
27
- Rules
28
- --------------------------------------------------
28
+ ```ruby
29
+ code_to_test = 'here'
30
+ #=> expected output
31
+ ```
32
+
33
+ This document itself serves as the test suite for this gem, so you can take a
34
+ look at its source.
29
35
 
30
- - Anything outside of a code fence is ignored.
31
- - Both `ruby` and `shell` code blocks are supported.
32
- - Inside a code block, any piece of code that we care about should print
33
- something.
34
- - Inside a code block, anything starting with `#=>` should define the
35
- expected output.
36
- - If a piece of code raises an error, the captured output will be the
37
- `#inspect` string of that exception.
38
- - If the first line of a code block includes the string `[:ignore_failure]`,
39
- the example will not be considered an error if it fails.
40
36
 
37
+ ### Testing with the `docspec` command line
41
38
 
42
- To test the `README.md` in the current folder, just run:
39
+ Test the examples in `./README.md`:
43
40
 
44
41
  $ docspec
45
42
 
46
- To test a different file, provide it as the first argument:
43
+ Test a different file:
47
44
 
48
45
  $ docspec TESTS.md
49
46
 
50
47
 
48
+ ### Testing from Ruby code
49
+
50
+ ```ruby
51
+ # Running from Ruby code
52
+ document = Docspec::Document.from_file 'sample.md'
53
+ document.test
54
+ #=> pass : Sample Test
55
+
56
+ puts document.success?
57
+ #=> true
58
+ ```
59
+
60
+
51
61
  Examples
52
62
  --------------------------------------------------
53
63
 
54
- These will be tested with `docspec`:
55
-
56
- ### Ruby
64
+ Code examples that you want to test, should output something to stdout.
65
+ Specify the expected output by prefixing it with `#=>`:
57
66
 
58
67
  ```ruby
59
68
  # The first line is an optional label
@@ -61,12 +70,17 @@ puts 'hello world'.upcase
61
70
  #=> HELLO WORLD
62
71
  ```
63
72
 
73
+ If an example raises an exception, the captured output will be the `#inspect`
74
+ string of that exception:
75
+
64
76
  ```ruby
65
77
  # Exceptions are captured
66
78
  raise ArgumentError, "Testing error raising"
67
79
  #=> #<ArgumentError: Testing error raising>
68
80
  ```
69
81
 
82
+ Your code and expected output can contain multiple lines of code:
83
+
70
84
  ```ruby
71
85
  # Multiple lines of code
72
86
  string = "hello"
@@ -78,6 +92,8 @@ end
78
92
  #=> hello
79
93
  ```
80
94
 
95
+ and you can alternate between code and expected output:
96
+
81
97
  ```ruby
82
98
  # Interleaving code and output
83
99
  puts 2 + 3
@@ -87,6 +103,13 @@ puts 2 - 3
87
103
  #=> -1
88
104
  ```
89
105
 
106
+ The first line of the example may contain specially formatted flags. Flags
107
+ are always formatted like this: `[:flag_name]`.
108
+
109
+ The `[:ignore_failure]` flag allows the example to fail. It will show the
110
+ failure in the output, but will not elevate the exit status to a failure
111
+ state:
112
+
90
113
  ```ruby
91
114
  # This example may fail [:ignore_failure]
92
115
  # Due to the :ignore_failure flag, it will show the failure diff, but will
@@ -95,26 +118,43 @@ puts 'hello world'.upcase
95
118
  #=> hello world
96
119
  ```
97
120
 
121
+ Another available flag, is the `[:skip]` flag, which will omit the example
122
+ from the test run:
123
+
98
124
  ```ruby
99
- # Code that does not generate any output will be executed before each
100
- # of the subsequent examples.
125
+ # [:skip]
126
+ this will not be executed
127
+ ```
128
+
129
+ Sometimes it is useful to build the example over several different code
130
+ blocks. To help achieve this, docspec will treat any example that does not
131
+ output anything as a code that needs to be executed before all subsequent
132
+ examples:
133
+
134
+ ```ruby
135
+ # Define a function for later use
101
136
  def create_caption(text)
102
137
  [text.upcase, ("=" * text.length)].join "\n"
103
138
  end
104
139
  ```
105
140
 
141
+ All the examples below this line, will have the above function available:
142
+
106
143
  ```ruby
107
- # Example that builds upon code that was defined earlier
144
+ # Use a previously defined function
108
145
  puts create_caption "tada!"
109
146
  #=> TADA!
110
147
  #=> =====
111
148
  ```
112
149
 
113
150
 
114
- ### Shell
151
+ Finally, examples marked with a `shell` code fence will be executed by the
152
+ shell, and not by ruby:
115
153
 
116
154
  ```shell
117
155
  # Shell commands
118
156
  echo hello world
119
157
  #=> hello world
120
158
  ```
159
+
160
+
data/bin/docspec CHANGED
@@ -8,16 +8,16 @@ include Colsole
8
8
 
9
9
  document = ARGV[0] || 'README.md'
10
10
  abort "File not found #{document}" unless File.exist? document
11
- tester = Docspec::Tester.new document
12
- success = tester.execute
11
+ document = Docspec::Document.from_file document
12
+ document.test
13
13
 
14
14
  say ''
15
15
 
16
- if success
17
- say "!txtgrn!#{tester.total} tests, #{tester.errors} failed\n"
16
+ if document.success?
17
+ say "!txtgrn!#{document.total_examples} tests, #{document.failed_examples} failed\n"
18
18
  exit 0
19
19
  else
20
- say "!txtred!#{tester.total} tests, #{tester.errors} failed\n"
20
+ say "!txtred!#{document.total_examples} tests, #{document.failed_examples} failed\n"
21
21
  exit 1
22
22
  end
23
23
 
@@ -1,13 +1,14 @@
1
1
  module Docspec
2
2
  class Document
3
- attr_reader :filename
3
+ include Testable
4
+ attr_reader :filename, :markdown
4
5
 
5
- def initialize(filename)
6
- @filename = filename
6
+ def self.from_file(filename)
7
+ new File.read(filename)
7
8
  end
8
9
 
9
- def markdown
10
- @markdown ||= File.read filename
10
+ def initialize(markdown)
11
+ @markdown = markdown
11
12
  end
12
13
 
13
14
  def examples
@@ -19,7 +20,8 @@ module Docspec
19
20
  def examples!
20
21
  result = []
21
22
  markdown.scan(/```(ruby|shell)\s*\n(.*?)```/m) do |type, code|
22
- result << Example.new(code, type)
23
+ example = Example.new(code, type)
24
+ result << example unless example.skip?
23
25
  end
24
26
  result
25
27
  end
@@ -48,6 +48,10 @@ module Docspec
48
48
  @full_code = "#{codes}\n#{@full_code}"
49
49
  end
50
50
 
51
+ def skip?
52
+ flags.include? :skip
53
+ end
54
+
51
55
  def success?
52
56
  actual == expected
53
57
  end
@@ -0,0 +1,57 @@
1
+ require 'colsole'
2
+
3
+ module Docspec
4
+ module Testable
5
+ include Colsole
6
+ attr_reader :failed_examples, :total_examples
7
+
8
+ def before_codes
9
+ @before_codes ||= []
10
+ end
11
+
12
+ def success?
13
+ failed_examples == 0
14
+ end
15
+
16
+ def each_example
17
+ reset_counters
18
+
19
+ examples.each do |example|
20
+ if example.empty?
21
+ before_codes << example.code
22
+ else
23
+ @total_examples += 1
24
+ example.prepend before_codes
25
+ @failed_examples += 1 unless example.success? or example.ignore_failure?
26
+ end
27
+
28
+ yield example
29
+ end
30
+ end
31
+
32
+ def test
33
+ each_example do |example|
34
+ if example.empty?
35
+ say "!txtpur!void :!txtrst! #{example.label}"
36
+ elsif example.success?
37
+ say "!txtgrn!pass :!txtrst! #{example.label}"
38
+ else
39
+ say "!txtred!FAIL : #{example.label}"
40
+ say "---"
41
+ puts example.diff
42
+ say "---"
43
+ end
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def reset_counters
50
+ @before_codes = nil
51
+ @failed_examples = 0
52
+ @total_examples = 0
53
+ end
54
+
55
+ end
56
+ end
57
+
@@ -1,3 +1,3 @@
1
1
  module Docspec
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/docspec.rb CHANGED
@@ -2,5 +2,5 @@ require 'byebug' if ENV['BYEBUG']
2
2
 
3
3
  require 'docspec/output_capturer'
4
4
  require 'docspec/example'
5
- require 'docspec/tester'
5
+ require 'docspec/testable'
6
6
  require 'docspec/document'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
@@ -65,7 +65,7 @@ files:
65
65
  - lib/docspec/document.rb
66
66
  - lib/docspec/example.rb
67
67
  - lib/docspec/output_capturer.rb
68
- - lib/docspec/tester.rb
68
+ - lib/docspec/testable.rb
69
69
  - lib/docspec/version.rb
70
70
  homepage: https://github.com/dannyben/docspec
71
71
  licenses:
@@ -1,45 +0,0 @@
1
- require 'colsole'
2
-
3
- module Docspec
4
- class Tester
5
- include Colsole
6
- attr_reader :document, :errors, :total
7
-
8
- def initialize(document)
9
- document = Document.new document unless document.is_a? Document
10
- @document = document
11
- @errors = 0
12
- @total = 0
13
- end
14
-
15
- def before_codes
16
- @before_codes ||= []
17
- end
18
-
19
- def execute
20
- document.examples.each do |example|
21
- if example.empty?
22
- before_codes << example.code
23
- next
24
- end
25
-
26
- @total += 1
27
-
28
- example.prepend before_codes
29
-
30
- if example.success?
31
- say "!txtgrn!PASS: #{example.label}"
32
- else
33
- @errors += 1 unless example.ignore_failure?
34
- say "!txtred!FAIL: #{example.label}"
35
- say "---"
36
- puts example.diff
37
- say "---"
38
- end
39
- end
40
-
41
- errors == 0
42
- end
43
- end
44
- end
45
-