erudite 0.1.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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MmMyNDJiNGZhYjc3YmY5NDJmNjA1ZWY2OWZmNDRkMDdiYjAwMzA0MQ==
5
+ data.tar.gz: !binary |-
6
+ NjA3YjdkZWY3OTVjMDM2OTI2NTUzZWU2YzRhNTViMjI5NmE4NjkxOQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjllZjIyNjdkMWE2YjQwNGJmNmUxZTQyYTA5ODFhNmI5OGIxYTllYTU4NDNh
10
+ OWM5M2Y2N2ZhMWM0YzIxNzI4NzdjOTI3MTQ0YTFlNjdlNzU2ZjhhMjNmZDE4
11
+ ZDhhMWU1NTc5NzUwY2Q0ZWIxYzVmNDEzZjQzOGE1OWMxNzY4OTU=
12
+ data.tar.gz: !binary |-
13
+ MThjNzM2YTllMTY2NzBkNGY4ZjYwZTRmODljMGE1YTkzOGNmYmMzYzQzMDg4
14
+ N2Y1YzIwY2I4Y2JiMmJmNGVmMTBiMWQwMTY4YjIzZDcxMzk5NmJmZWQ4ZDFh
15
+ YjhlMGMyOTBmMjVkOTYyYzZkZTI3YTY1NWU1MDI4YzRlMGY2NzY=
@@ -0,0 +1 @@
1
+ # Changelog
@@ -0,0 +1,7 @@
1
+ # Contributing
2
+
3
+ 1. **Fork** the repository.
4
+ 2. Create a **branch** for your feature (`git checkout -b feature`).
5
+ 3. **Commit** your changes (`git commit -a -m 'Feature'`).
6
+ 4. **Push** to your branch (`git push origin feature`).
7
+ 5. Create a **pull request**.
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2014 Taylor Fausak <taylor@fausak.me>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ # [Erudite][1]
2
+
3
+ Executable documentation.
4
+
5
+ ``` rb
6
+ examples = Erudite::Parser.parse(<<-'RUBY')
7
+ >> 1 + 2
8
+ => 3
9
+
10
+ >> Object.new
11
+ => #<Object:0x...>
12
+
13
+ >> gets
14
+ => nil
15
+
16
+ >> puts 'hello world'
17
+ hello world
18
+ => nil
19
+
20
+ >> warn 'oh noes'
21
+ oh noes
22
+ => nil
23
+
24
+ >> fail 'catastrophe!'
25
+ RuntimeError: catastrophe!
26
+
27
+ >> puts 'chunky
28
+ .. bacon'
29
+ chunky
30
+ bacon
31
+ => nil
32
+
33
+ >> def double(n)
34
+ .. 2 * n
35
+ .. end
36
+ >> double(3)
37
+ => 6
38
+ RUBY
39
+
40
+ examples.each do |example|
41
+ if example.pass?
42
+ puts 'PASS'
43
+ else
44
+ puts 'FAIL'
45
+ puts " expected : #{example.expected.result.inspect}"
46
+ puts " : #{example.expected.output.inspect}"
47
+ puts " actual : #{example.actual.result.inspect}"
48
+ puts " : #{example.actual.output.inspect}"
49
+ end
50
+ end
51
+ ```
52
+
53
+ [1]: https://github.com/tfausak/erudite
@@ -0,0 +1,9 @@
1
+ # coding: utf-8
2
+
3
+ require 'erudite/example'
4
+ require 'erudite/outcome'
5
+ require 'erudite/parser'
6
+
7
+ # Executable documentation.
8
+ module Erudite
9
+ end
@@ -0,0 +1,79 @@
1
+ # coding: utf-8
2
+
3
+ require 'stringio'
4
+
5
+ module Erudite
6
+ # Code to be run and compared against its expected outcome.
7
+ class Example
8
+ attr_reader :source
9
+ attr_reader :expected
10
+ attr_writer :binding
11
+
12
+ def initialize(source, result = nil, output = nil)
13
+ @source = source
14
+ @expected = Outcome.new(result, output)
15
+ end
16
+
17
+ def binding
18
+ @binding ||= TOPLEVEL_BINDING.dup
19
+ end
20
+
21
+ def run!
22
+ binding.eval(source, __FILE__, __LINE__)
23
+ end
24
+
25
+ def run
26
+ [run!, nil]
27
+ rescue Exception => exception # rubocop:disable Lint/RescueException
28
+ [nil, exception]
29
+ end
30
+
31
+ def self.without_stdio
32
+ stdin, stdout, stderr = $stdin, $stdout, $stderr
33
+ $stdin = $stdout = $stderr = io = StringIO.new
34
+ [yield, io]
35
+ ensure
36
+ $stdin, $stdout, $stderr = stdin, stdout, stderr
37
+ end
38
+
39
+ def self.format_exception(exception)
40
+ "#{exception.class.name}: #{exception.message}"
41
+ end
42
+
43
+ def actual
44
+ return @actual if defined?(@actual)
45
+
46
+ result, io = self.class.without_stdio do
47
+ result, exception = run
48
+ warn(self.class.format_exception(exception)) if exception
49
+ result.inspect
50
+ end
51
+
52
+ @actual = Outcome.new(result, io.string)
53
+ end
54
+
55
+ def self.pattern(string)
56
+ Regexp.new(Regexp.escape(string).gsub('\.\.\.', '.*?'))
57
+ end
58
+
59
+ def valid_result?
60
+ return true unless expected.result
61
+ self.class.pattern(expected.result).match(actual.result)
62
+ end
63
+
64
+ def valid_output?
65
+ return true unless expected.output
66
+ self.class.pattern(expected.output).match(actual.output)
67
+ end
68
+
69
+ def pass?
70
+ actual
71
+ valid_result? && valid_output?
72
+ end
73
+
74
+ def ==(other)
75
+ source == other.source &&
76
+ expected == other.expected
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ module Erudite
4
+ # Information about an expected or actual outcome.
5
+ class Outcome
6
+ attr_reader :result
7
+ attr_reader :output
8
+
9
+ def initialize(result, output)
10
+ @result = result
11
+ @output = output
12
+ end
13
+
14
+ def ==(other)
15
+ result == other.result &&
16
+ output == other.output
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,54 @@
1
+ # coding: utf-8
2
+
3
+ module Erudite
4
+ # Parses IRB output into examples.
5
+ class Parser
6
+ def self.parse(string)
7
+ group(string).map { |lines| exemplify(lines) }
8
+ end
9
+
10
+ def self.group(string)
11
+ buffer = []
12
+
13
+ groups = string.each_line.each_with_object([]) do |line, array|
14
+ if line.start_with?('>> ') && !buffer.empty?
15
+ array.push(buffer)
16
+ buffer = []
17
+ end
18
+
19
+ buffer.push(line)
20
+ end
21
+
22
+ buffer.empty? ? groups : groups.push(buffer)
23
+ end
24
+
25
+ def self.exemplify(lines)
26
+ source = extract_source(lines)
27
+ result = extract_result(lines)
28
+ output = extract_output(lines)
29
+
30
+ Example.new(source, result, output)
31
+ end
32
+
33
+ def self.extract_source(lines)
34
+ source = lines
35
+ .select { |line| line.start_with?('>> ', '.. ') }
36
+ .map { |line| line[3..-1].chomp }
37
+ source.join("\n") unless source.empty?
38
+ end
39
+
40
+ def self.extract_result(lines)
41
+ result = lines
42
+ .select { |line| line.start_with?('=> ') }
43
+ .map { |line| line[3..-1].chomp }
44
+ result.join("\n") unless result.empty?
45
+ end
46
+
47
+ def self.extract_output(lines)
48
+ output = lines
49
+ .reject { |line| line.start_with?('>> ', '.. ', '=> ') }
50
+ .map { |line| line.chomp }
51
+ output.join("\n") unless output.empty?
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,352 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Erudite::Example do
6
+ it 'requires some source' do
7
+ expect { described_class.new }.to raise_error(ArgumentError)
8
+ end
9
+
10
+ it 'can be initialized' do
11
+ expect(described_class.new(nil)).to be_a(described_class)
12
+ end
13
+
14
+ it 'sets the source' do
15
+ source = double
16
+ example = described_class.new(source)
17
+ expect(example.source).to eql(source)
18
+ end
19
+
20
+ it 'uses the default expected outcome' do
21
+ example = described_class.new(nil)
22
+ expect(example.expected).to be_an(Erudite::Outcome)
23
+ expect(example.expected.result).to be(nil)
24
+ expect(example.expected.output).to be(nil)
25
+ end
26
+
27
+ it 'sets the expected result' do
28
+ result = double
29
+ example = described_class.new(nil, result)
30
+ expect(example.expected.result).to eql(result)
31
+ end
32
+
33
+ it 'sets the expected output' do
34
+ output = double
35
+ example = described_class.new(nil, nil, output)
36
+ expect(example.expected.output).to eql(output)
37
+ end
38
+
39
+ describe '#binding' do
40
+ it 'uses the default binding' do
41
+ example = described_class.new(nil)
42
+ expect(example.binding).to be_a(Binding)
43
+ expect(example.binding.eval('self')).to be(TOPLEVEL_BINDING.eval('self'))
44
+ expect(example.binding).to_not be(TOPLEVEL_BINDING)
45
+ end
46
+
47
+ it 'memoizes the binding' do
48
+ example = described_class.new(nil)
49
+ binding = example.binding
50
+ expect(example.binding).to be(binding)
51
+ end
52
+
53
+ it 'sets the binding' do
54
+ example = described_class.new(nil)
55
+ binding = TOPLEVEL_BINDING.dup
56
+ example.binding = binding
57
+ expect(example.binding).to be(binding)
58
+ end
59
+ end
60
+
61
+ describe '#run!' do
62
+ it 'evaluates the source' do
63
+ source = ':something'
64
+ example = described_class.new(source)
65
+ expect(example.run!).to eql(TOPLEVEL_BINDING.eval(source))
66
+ end
67
+
68
+ it 'evaluates the source in the binding' do
69
+ source = 'variable'
70
+ example = described_class.new(source)
71
+ example.binding.eval('variable = :something')
72
+ expect(example.run!).to eql(example.binding.eval(source))
73
+ end
74
+
75
+ it 'sets the file name' do
76
+ example = described_class.new('fail')
77
+ begin
78
+ example.run!
79
+ rescue => error
80
+ expect(error.backtrace.first).to_not start_with('<main>:')
81
+ end
82
+ end
83
+
84
+ it 'sets the line number' do
85
+ example = described_class.new('fail')
86
+ begin
87
+ example.run!
88
+ rescue => error
89
+ expect(error.backtrace.first).to_not end_with(":1:in `<main>'")
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '#run' do
95
+ it 'returns the result' do
96
+ source = ':something'
97
+ example = described_class.new(source)
98
+ expect(example.run.first).to eql(TOPLEVEL_BINDING.eval(source))
99
+ expect(example.run.last).to be(nil)
100
+ end
101
+
102
+ it 'returns the exception' do
103
+ source = 'fail'
104
+ example = described_class.new(source)
105
+ expect(example.run.first).to be(nil)
106
+ expect(example.run.last).to be_a(StandardError)
107
+ end
108
+ end
109
+
110
+ describe '.without_stdio' do
111
+ it 'requires a block' do
112
+ expect { described_class.without_stdio }.to raise_error(LocalJumpError)
113
+ end
114
+
115
+ it 'calls the block' do
116
+ result = double
117
+ expect(described_class.without_stdio { result }.first).to eql(result)
118
+ end
119
+
120
+ it 'redirects STDIN' do
121
+ stdin = $stdin
122
+ expect(described_class.without_stdio { $stdin }).to_not eq(stdin)
123
+ end
124
+
125
+ it 'redirects STDOUT' do
126
+ stdout = $stdout
127
+ expect(described_class.without_stdio { $stdout }).to_not eq(stdout)
128
+ end
129
+
130
+ it 'redirects STDERR' do
131
+ stderr = $stderr
132
+ expect(described_class.without_stdio { $stderr }).to_not eq(stderr)
133
+ end
134
+
135
+ it 'reconnects STDIN' do
136
+ stdin = $stdin
137
+ begin
138
+ described_class.without_stdio { fail }
139
+ rescue
140
+ nil
141
+ end
142
+ expect($stdin).to eq(stdin)
143
+ end
144
+
145
+ it 'reconnects STDOUT' do
146
+ stdout = $stdout
147
+ begin
148
+ described_class.without_stdio { fail }
149
+ rescue
150
+ nil
151
+ end
152
+ expect($stdout).to eq(stdout)
153
+ end
154
+
155
+ it 'reconnects STDERR' do
156
+ stderr = $stderr
157
+ begin
158
+ described_class.without_stdio { fail }
159
+ rescue
160
+ nil
161
+ end
162
+ expect($stderr).to eq(stderr)
163
+ end
164
+
165
+ it 'returns the redirected IO' do
166
+ expect(described_class.without_stdio {}.last).to be_a(StringIO)
167
+ end
168
+
169
+ it 'handles STDIN' do
170
+ result, _ = described_class.without_stdio { gets }
171
+ expect(result).to be(nil)
172
+ end
173
+
174
+ it 'handles STDOUT' do
175
+ _, io = described_class.without_stdio { puts 'something' }
176
+ expect(io.string).to eql("something\n")
177
+ end
178
+
179
+ it 'handles STDERR' do
180
+ _, io = described_class.without_stdio { warn 'something' }
181
+ expect(io.string).to eql("something\n")
182
+ end
183
+ end
184
+
185
+ describe '.format_exception' do
186
+ it 'formats the exception' do
187
+ exception = StandardError.new('something')
188
+ expect(described_class.format_exception(exception))
189
+ .to eql("#{exception.class.name}: #{exception.message}")
190
+ end
191
+ end
192
+
193
+ describe '#actual' do
194
+ it 'sets the result' do
195
+ example = described_class.new('"something"')
196
+ expect(example.actual.result).to eql('"something"')
197
+ expect(example.actual.output).to eql('')
198
+ end
199
+
200
+ it 'handles STDIN' do
201
+ example = described_class.new('gets')
202
+ expect(example.actual.result).to eql('nil')
203
+ expect(example.actual.output).to eql('')
204
+ end
205
+
206
+ it 'handles STDOUT' do
207
+ example = described_class.new('puts "something"')
208
+ expect(example.actual.result).to eql('nil')
209
+ expect(example.actual.output).to eql("something\n")
210
+ end
211
+
212
+ it 'handles STDERR' do
213
+ example = described_class.new('warn "something"')
214
+ expect(example.actual.result).to eql('nil')
215
+ expect(example.actual.output).to eql("something\n")
216
+ end
217
+
218
+ it 'handles exceptions' do
219
+ example = described_class.new('fail StandardError, "something"')
220
+ expect(example.actual.result).to eql('nil')
221
+ expect(example.actual.output).to eql("StandardError: something\n")
222
+ end
223
+
224
+ it 'memoizes the result' do
225
+ example = described_class.new('')
226
+ actual = example.actual
227
+ expect(example.actual).to be(actual)
228
+ end
229
+ end
230
+
231
+ describe '.pattern' do
232
+ it 'returns a Regexp' do
233
+ pattern = described_class.pattern('something')
234
+ expect(pattern).to be_a(Regexp)
235
+ end
236
+
237
+ it 'escapes meta characters' do
238
+ pattern = described_class.pattern('some.thing')
239
+ expect(pattern).to eql(/some\.thing/)
240
+ end
241
+
242
+ it 'replaces "..."' do
243
+ pattern = described_class.pattern('some...thing')
244
+ expect(pattern).to eql(/some.*?thing/)
245
+ end
246
+ end
247
+
248
+ describe '#valid_result?' do
249
+ it 'returns true without an expected result' do
250
+ example = described_class.new(nil, nil)
251
+ expect(example).to be_valid_result
252
+ end
253
+
254
+ it 'returns true when the results match' do
255
+ example = described_class.new('"something"', '"something"')
256
+ expect(example).to be_valid_result
257
+ end
258
+
259
+ it "returns false when the results don't match" do
260
+ example = described_class.new('"something"', '"something else"')
261
+ expect(example).to_not be_valid_result
262
+ end
263
+
264
+ it 'allows wildcards' do
265
+ example = described_class.new('Object.new', '#<Object:0x...>')
266
+ expect(example).to be_valid_result
267
+ end
268
+ end
269
+
270
+ describe '#valid_output?' do
271
+ it 'returns true without expected output' do
272
+ example = described_class.new(nil, nil)
273
+ expect(example).to be_valid_output
274
+ end
275
+
276
+ it 'returns true when the output matches' do
277
+ example = described_class.new('puts "something"', nil, 'something')
278
+ expect(example).to be_valid_output
279
+ end
280
+
281
+ it "returns false when the output doesn't match" do
282
+ example = described_class.new('puts "something"', nil, 'something else')
283
+ expect(example).to_not be_valid_output
284
+ end
285
+
286
+ it 'allows wildcards' do
287
+ example = described_class.new('puts Object.new', nil, '#<Object:0x...>')
288
+ expect(example).to be_valid_output
289
+ end
290
+ end
291
+
292
+ describe '#pass?' do
293
+ it 'realizes the actual outcome' do
294
+ example = described_class.new('x = 1')
295
+ example.pass?
296
+ expect(example.binding.eval('x')).to eql(1)
297
+ end
298
+
299
+ it 'returns true if both the result and output match' do
300
+ example = described_class
301
+ .new('p "something"', '"something"', '"something"')
302
+ expect(example).to be_pass
303
+ end
304
+
305
+ it "returns false if the result doesn't match" do
306
+ example = described_class
307
+ .new('p "something"', '"something else"', '"something"')
308
+ expect(example).to_not be_pass
309
+ end
310
+
311
+ it "returns false if the output doesn't match" do
312
+ example = described_class
313
+ .new('p "something"', '"something"', '"something else"')
314
+ expect(example).to_not be_pass
315
+ end
316
+ end
317
+
318
+ describe '#==' do
319
+ it 'returns true when they have the same source, result, and output' do
320
+ source = 'x'
321
+ result = 'y'
322
+ output = 'z'
323
+ a = described_class.new(source, result, output)
324
+ b = described_class.new(source, result, output)
325
+ expect(a).to eq(b)
326
+ end
327
+
328
+ it "returns false when they don't have the same source" do
329
+ result = 'y'
330
+ output = 'z'
331
+ a = described_class.new('a', result, output)
332
+ b = described_class.new('b', result, output)
333
+ expect(a).to_not eq(b)
334
+ end
335
+
336
+ it "returns false when they don't have the same result" do
337
+ source = 'x'
338
+ output = 'z'
339
+ a = described_class.new(source, 'a', output)
340
+ b = described_class.new(source, 'b', output)
341
+ expect(a).to_not eq(b)
342
+ end
343
+
344
+ it "returns false when they don't have the same output" do
345
+ source = 'x'
346
+ result = 'y'
347
+ a = described_class.new(source, result, 'a')
348
+ b = described_class.new(source, result, 'b')
349
+ expect(a).to_not eq(b)
350
+ end
351
+ end
352
+ end
@@ -0,0 +1,53 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Erudite::Outcome do
6
+ it 'requires a result' do
7
+ expect { described_class.new }.to raise_error(ArgumentError)
8
+ end
9
+
10
+ it 'requires some output' do
11
+ expect { described_class.new(nil) }.to raise_error(ArgumentError)
12
+ end
13
+
14
+ it 'can be initialized' do
15
+ expect(described_class.new(nil, nil)).to be_a(described_class)
16
+ end
17
+
18
+ it 'sets the result' do
19
+ result = double
20
+ outcome = described_class.new(result, nil)
21
+ expect(outcome.result).to eql(result)
22
+ end
23
+
24
+ it 'sets the output' do
25
+ output = double
26
+ outcome = described_class.new(nil, output)
27
+ expect(outcome.output).to eql(output)
28
+ end
29
+
30
+ describe '#==' do
31
+ it 'returns true if they have the same result and output' do
32
+ result = 'some'
33
+ output = 'thing'
34
+ a = described_class.new(result, output)
35
+ b = described_class.new(result, output)
36
+ expect(a).to eq(b)
37
+ end
38
+
39
+ it "returns false if they don't have the same result" do
40
+ output = 'something'
41
+ a = described_class.new('a', output)
42
+ b = described_class.new('b', output)
43
+ expect(a).to_not eq(b)
44
+ end
45
+
46
+ it "returns false if they don't have the same output" do
47
+ result = 'something'
48
+ a = described_class.new(result, 'a')
49
+ b = described_class.new(result, 'b')
50
+ expect(a).to_not eq(b)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,104 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ # Monkey patch String to add ability to strip leading whitespace.
6
+ class String
7
+ def dedent
8
+ gsub(/^#{self[/\A\s*/]}/, '')
9
+ end
10
+ end
11
+
12
+ describe Erudite::Parser do
13
+ describe '.parse' do
14
+ it 'parses an example without output or a result' do
15
+ examples = described_class.parse(<<-'RUBY'.dedent)
16
+ >> :something
17
+ RUBY
18
+ expect(examples).to eq([
19
+ Erudite::Example.new(':something')])
20
+ end
21
+
22
+ it 'parses an example with a result' do
23
+ examples = described_class.parse(<<-'RUBY'.dedent)
24
+ >> :something
25
+ => :something
26
+ RUBY
27
+ expect(examples).to eq([
28
+ Erudite::Example.new(':something', ':something')])
29
+ end
30
+
31
+ it 'parses an example with output' do
32
+ examples = described_class.parse(<<-'RUBY'.dedent)
33
+ >> puts :something
34
+ something
35
+ RUBY
36
+ expect(examples).to eq([
37
+ Erudite::Example.new('puts :something', nil, 'something')])
38
+ end
39
+
40
+ it 'handles STDIN' do
41
+ examples = described_class.parse(<<-'RUBY'.dedent)
42
+ >> gets
43
+ => nil
44
+ RUBY
45
+ expect(examples).to eq([
46
+ Erudite::Example.new('gets', 'nil')])
47
+ end
48
+
49
+ it 'handles STDOUT' do
50
+ examples = described_class.parse(<<-'RUBY'.dedent)
51
+ >> puts :something
52
+ something
53
+ => nil
54
+ RUBY
55
+ expect(examples).to eq([
56
+ Erudite::Example.new('puts :something', 'nil', 'something')])
57
+ end
58
+
59
+ it 'handles STDERR' do
60
+ examples = described_class.parse(<<-'RUBY'.dedent)
61
+ >> warn :something
62
+ something
63
+ => nil
64
+ RUBY
65
+ expect(examples).to eq([
66
+ Erudite::Example.new('warn :something', 'nil', 'something')])
67
+ end
68
+
69
+ it 'handles exceptions' do
70
+ examples = described_class.parse(<<-'RUBY'.dedent)
71
+ >> fail 'something'
72
+ RuntimeError: something
73
+ RUBY
74
+ expect(examples).to eq([
75
+ Erudite::Example.new(
76
+ "fail 'something'", nil, 'RuntimeError: something')])
77
+ end
78
+
79
+ it 'handles multi-line source and output' do
80
+ examples = described_class.parse(<<-'RUBY'.dedent)
81
+ >> puts 'some
82
+ .. thing'
83
+ some
84
+ thing
85
+ => nil
86
+ RUBY
87
+ expect(examples).to eq([
88
+ Erudite::Example.new("puts 'some\nthing'", 'nil', "some\nthing")])
89
+ end
90
+
91
+ it 'handles multiple examples' do
92
+ examples = described_class.parse(<<-'RUBY'.dedent)
93
+ >> def some
94
+ .. :thing
95
+ .. end
96
+ >> some
97
+ => :thing
98
+ RUBY
99
+ expect(examples).to eq([
100
+ Erudite::Example.new("def some\n :thing\nend"),
101
+ Erudite::Example.new('some', ':thing')])
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Erudite do
6
+ pending
7
+ end
@@ -0,0 +1,3 @@
1
+ # coding: utf-8
2
+
3
+ require 'erudite'
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erudite
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Taylor Fausak
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 10.3.2
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 10.3.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.25.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.25.0
55
+ description: Executable documentation.
56
+ email: taylor@fausak.me
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - CHANGELOG.md
62
+ - CONTRIBUTING.md
63
+ - LICENSE.md
64
+ - README.md
65
+ - lib/erudite.rb
66
+ - lib/erudite/example.rb
67
+ - lib/erudite/outcome.rb
68
+ - lib/erudite/parser.rb
69
+ - spec/erudite/example_spec.rb
70
+ - spec/erudite/outcome_spec.rb
71
+ - spec/erudite/parser_spec.rb
72
+ - spec/erudite_spec.rb
73
+ - spec/spec_helper.rb
74
+ homepage: https://github.com/tfausak/erudite
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: 1.9.3
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.4.1
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Executable documentation.
98
+ test_files:
99
+ - spec/erudite/example_spec.rb
100
+ - spec/erudite/outcome_spec.rb
101
+ - spec/erudite/parser_spec.rb
102
+ - spec/erudite_spec.rb
103
+ - spec/spec_helper.rb