exemplor 2.2.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/.gitignore +1 -0
- data/README +152 -0
- data/Rakefile +16 -0
- data/TODO +6 -0
- data/VERSION +1 -0
- data/examples.rb +59 -0
- data/examples/an_error.rb +14 -0
- data/examples/assertion_failure.rb +13 -0
- data/examples/assertion_success.rb +11 -0
- data/examples/assertion_success_and_failure.rb +18 -0
- data/examples/check_with_disambiguation.rb +14 -0
- data/examples/helpers.rb +17 -0
- data/examples/no_checks.rb +9 -0
- data/examples/no_checks_non_string.rb +15 -0
- data/examples/oneliner.rb +7 -0
- data/examples/with_checks.rb +15 -0
- data/examples/with_setup.rb +20 -0
- data/exemplor.gemspec +66 -0
- data/lib/exemplor.rb +224 -0
- metadata +83 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/README
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
Examplor (the exemplar)
|
2
|
+
=======================
|
3
|
+
|
4
|
+
An example-based test framework inspired by [testy](http://github.com/ahoward/testy).
|
5
|
+
|
6
|
+
Simpler that BDD/TDD, fancier than a file with a bunch of print statements.
|
7
|
+
|
8
|
+
Very tiny api. Here it is
|
9
|
+
|
10
|
+
eg.helpers do
|
11
|
+
... your helpers ...
|
12
|
+
end
|
13
|
+
|
14
|
+
eg.setup { ... setup codez ... }
|
15
|
+
|
16
|
+
eg "an example" do
|
17
|
+
... example code ...
|
18
|
+
end
|
19
|
+
|
20
|
+
eg "another example" do
|
21
|
+
... etc ...
|
22
|
+
end
|
23
|
+
|
24
|
+
The output is both human readable and machine parsable, which means you can test your tests.
|
25
|
+
|
26
|
+
Writing Examples
|
27
|
+
----------------
|
28
|
+
|
29
|
+
See `examples.rb` and `/examples` for more examples.
|
30
|
+
|
31
|
+
The simplest possible example:
|
32
|
+
|
33
|
+
eg 'An example block without any checks prints the value of the block' do
|
34
|
+
"foo"
|
35
|
+
end
|
36
|
+
|
37
|
+
#=>
|
38
|
+
|
39
|
+
(i) An example block without any checks prints the value of the block: foo
|
40
|
+
|
41
|
+
The 'i' stands for 'info' which means the example ran without error.
|
42
|
+
|
43
|
+
Inspecting a few values, by default `Check` prints it's argument and the value of the argument:
|
44
|
+
|
45
|
+
eg 'Accessing different parts of an array' do
|
46
|
+
list = [1, 2, 3]
|
47
|
+
Check(list.first)
|
48
|
+
Check(list[1])
|
49
|
+
Check(list.last)
|
50
|
+
end
|
51
|
+
|
52
|
+
#=>
|
53
|
+
|
54
|
+
(I) Accessing different parts of an array:
|
55
|
+
(i) list.first: 1
|
56
|
+
(i) list[1]: 2
|
57
|
+
(i) list.last: 3
|
58
|
+
|
59
|
+
The capital 'I' means all checks were 'info' checks.
|
60
|
+
|
61
|
+
Call's to `Check` with the same argument can be disambiguated with `[]`:
|
62
|
+
|
63
|
+
eg 'Array appending' do
|
64
|
+
list = [1, 42]
|
65
|
+
Check(list.last)["before append"]
|
66
|
+
list << 2
|
67
|
+
Check(list.last)["after append"]
|
68
|
+
end
|
69
|
+
|
70
|
+
#=>
|
71
|
+
|
72
|
+
(I) Array appending:
|
73
|
+
(i) list.last before append: 42
|
74
|
+
(i) list.last after append: 2
|
75
|
+
|
76
|
+
Errors are caught and reported nicely:
|
77
|
+
|
78
|
+
eg 'Raising an error' do
|
79
|
+
raise "boom!"
|
80
|
+
end
|
81
|
+
|
82
|
+
#=>
|
83
|
+
|
84
|
+
(e) Raising an error:
|
85
|
+
class: RuntimeError
|
86
|
+
message: boom!
|
87
|
+
backtrace:
|
88
|
+
- examples/an_error.rb:4
|
89
|
+
# ... more backtrace lines
|
90
|
+
|
91
|
+
Once you're happy with how your code is running you can make some assertions about its behaviour by adding `is()` calls after your `Check()` statements:
|
92
|
+
|
93
|
+
|
94
|
+
eg 'Asserting first is first' do
|
95
|
+
list = [1, 2, 3]
|
96
|
+
Check(list.first).is(1)
|
97
|
+
end
|
98
|
+
|
99
|
+
#=>
|
100
|
+
|
101
|
+
(s) Asserting first is first:
|
102
|
+
(s) list.first: 1
|
103
|
+
|
104
|
+
's' stands for 'success' and 'f' for failure:
|
105
|
+
|
106
|
+
eg 'Assertion failure' do
|
107
|
+
list = [1, 2, 3]
|
108
|
+
Check(list.first).is(2)
|
109
|
+
end
|
110
|
+
|
111
|
+
#=>
|
112
|
+
|
113
|
+
(f) Assertion failure:
|
114
|
+
(f) list.first:
|
115
|
+
expected: 2
|
116
|
+
actual: 1
|
117
|
+
|
118
|
+
|
119
|
+
Running Examples
|
120
|
+
----------------
|
121
|
+
|
122
|
+
Running with `--list` or `-l` lists all examples:
|
123
|
+
|
124
|
+
$> ruby examples.rb -l
|
125
|
+
- errors are caught and nicely displayed
|
126
|
+
- check_output_matches_expected_for :no_checks
|
127
|
+
- check_output_matches_expected_for :oneliner
|
128
|
+
- check_output_matches_expected_for :no_checks_non_string
|
129
|
+
- check_output_matches_expected_for :with_checks
|
130
|
+
- check_output_matches_expected_for :check_with_disambiguation
|
131
|
+
- check_output_matches_expected_for :assertion_success
|
132
|
+
- check_output_matches_expected_for :assertion_failure
|
133
|
+
- check_output_matches_expected_for :assertion_success_and_failure
|
134
|
+
- check_output_matches_expected_for :helpers
|
135
|
+
- check_output_matches_expected_for :with_setup
|
136
|
+
- called with --list arg
|
137
|
+
- called with --l arg
|
138
|
+
- called with some other arg (always interpreted as a regex)
|
139
|
+
|
140
|
+
Otherwise the first argument is taken as a regex and only examples who's titles match are run:
|
141
|
+
|
142
|
+
$> ruby examples.rb called
|
143
|
+
(s) called with --list arg:
|
144
|
+
(s) list:
|
145
|
+
- Modified env
|
146
|
+
- Unmodified env
|
147
|
+
(s) called with --l arg:
|
148
|
+
(s) list:
|
149
|
+
- Modified env
|
150
|
+
- Unmodified env
|
151
|
+
(s) called with some other arg (always interpreted as a regex):
|
152
|
+
(s) tests_run: 1
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# require "mg"
|
2
|
+
# MG.new("exemplor.gemspec")
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gs|
|
7
|
+
gs.name = "exemplor"
|
8
|
+
gs.homepage = "http://github.com/quackingduck/exemplor"
|
9
|
+
gs.summary = "A light-weight, low-fi way to provide executable usage examples or your code."
|
10
|
+
gs.email = "myles@myles.id.au"
|
11
|
+
gs.authors = ["Myles Byrne"]
|
12
|
+
end
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
rescue LoadError
|
15
|
+
puts "Install jeweler to build gem"
|
16
|
+
end
|
data/TODO
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.0
|
data/examples.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# TODO: switch to gem version
|
2
|
+
require 'lib/exemplor'
|
3
|
+
|
4
|
+
# slow because each test runs in a subshell
|
5
|
+
|
6
|
+
eg.helpers do
|
7
|
+
|
8
|
+
def run_example(name, args = nil)
|
9
|
+
`ruby -Ilib examples/#{name}.rb#{' ' + args if args}`
|
10
|
+
end
|
11
|
+
|
12
|
+
def extract_expected(name)
|
13
|
+
File.read("examples/#{name}.rb").split('__END__').last
|
14
|
+
end
|
15
|
+
|
16
|
+
def expected_and_actual(example_name)
|
17
|
+
[extract_expected(example_name).strip, run_example(example_name).strip]
|
18
|
+
end
|
19
|
+
|
20
|
+
def check_output_matches_expected_for(example_name)
|
21
|
+
expected_output, output = expected_and_actual(example_name)
|
22
|
+
Check(output).is(expected_output)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
eg "errors are caught and nicely displayed" do
|
28
|
+
actual_yaml = YAML.load run_example(:an_error)
|
29
|
+
error_hash = actual_yaml[actual_yaml.keys.first]
|
30
|
+
# the rest of the bactrace is platform & exemplor version specific
|
31
|
+
error_hash['backtrace'] = error_hash['backtrace'][0...1]
|
32
|
+
Check(actual_yaml).is(YAML.load(extract_expected(:an_error)))
|
33
|
+
end
|
34
|
+
|
35
|
+
eg { check_output_matches_expected_for :no_checks }
|
36
|
+
eg { check_output_matches_expected_for :oneliner }
|
37
|
+
eg { check_output_matches_expected_for :no_checks_non_string }
|
38
|
+
eg { check_output_matches_expected_for :with_checks }
|
39
|
+
eg { check_output_matches_expected_for :check_with_disambiguation }
|
40
|
+
eg { check_output_matches_expected_for :assertion_success }
|
41
|
+
eg { check_output_matches_expected_for :assertion_failure }
|
42
|
+
eg { check_output_matches_expected_for :assertion_success_and_failure }
|
43
|
+
eg { check_output_matches_expected_for :helpers }
|
44
|
+
eg { check_output_matches_expected_for :with_setup }
|
45
|
+
|
46
|
+
eg "called with --list arg" do
|
47
|
+
list = YAML.load(run_example(:with_setup, '--list'))
|
48
|
+
Check(list).is(["Modified env", "Unmodified env"])
|
49
|
+
end
|
50
|
+
|
51
|
+
eg "called with --l arg" do
|
52
|
+
list = YAML.load(run_example(:with_setup, '--list'))
|
53
|
+
Check(list).is(["Modified env", "Unmodified env"])
|
54
|
+
end
|
55
|
+
|
56
|
+
eg "called with some other arg (always interpreted as a regex)" do
|
57
|
+
tests_run = YAML.load(run_example(:with_setup, 'Unmodified')).size
|
58
|
+
Check(tests_run).is(1)
|
59
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'exemplor'
|
2
|
+
|
3
|
+
eg 'Some successes, then a fail' do
|
4
|
+
list = [1, 2, 3]
|
5
|
+
Check(list.first).is(1)
|
6
|
+
Check(list[1]).is(2)
|
7
|
+
Check(list.last).is(1)
|
8
|
+
Check(list[2]).is(3) # would be successful but we never get here
|
9
|
+
end
|
10
|
+
|
11
|
+
__END__
|
12
|
+
|
13
|
+
(f) Some successes, then a fail:
|
14
|
+
(s) list.first: 1
|
15
|
+
(s) list[1]: 2
|
16
|
+
(f) list.last:
|
17
|
+
expected: 1
|
18
|
+
actual: 3
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'exemplor'
|
2
|
+
|
3
|
+
eg 'Array appending' do
|
4
|
+
list = [1, 42]
|
5
|
+
Check(list.last)["before append"]
|
6
|
+
list << 2
|
7
|
+
Check(list.last)["after append"]
|
8
|
+
end
|
9
|
+
|
10
|
+
__END__
|
11
|
+
|
12
|
+
(I) Array appending:
|
13
|
+
(i) list.last before append: 42
|
14
|
+
(i) list.last after append: 2
|
data/examples/helpers.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'exemplor'
|
2
|
+
|
3
|
+
eg 'Accessing different parts of an array' do
|
4
|
+
list = [1, 2, 3]
|
5
|
+
Check(list.first)
|
6
|
+
Check(list[1])
|
7
|
+
Check(list.last)
|
8
|
+
end
|
9
|
+
|
10
|
+
__END__
|
11
|
+
|
12
|
+
(I) Accessing different parts of an array:
|
13
|
+
(i) list.first: 1
|
14
|
+
(i) list[1]: 2
|
15
|
+
(i) list.last: 3
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'exemplor'
|
2
|
+
|
3
|
+
|
4
|
+
eg.setup { @str = "foo" }
|
5
|
+
|
6
|
+
eg 'Modified env' do
|
7
|
+
@str << " bar"
|
8
|
+
Check(@str).is("foo bar")
|
9
|
+
end
|
10
|
+
|
11
|
+
eg 'Unmodified env' do
|
12
|
+
Check(@str).is("foo")
|
13
|
+
end
|
14
|
+
|
15
|
+
__END__
|
16
|
+
|
17
|
+
(s) Modified env:
|
18
|
+
(s) @str: foo bar
|
19
|
+
(s) Unmodified env:
|
20
|
+
(s) @str: foo
|
data/exemplor.gemspec
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{exemplor}
|
8
|
+
s.version = "2.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Myles Byrne"]
|
12
|
+
s.date = %q{2009-10-12}
|
13
|
+
s.email = %q{myles@myles.id.au}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"README"
|
16
|
+
]
|
17
|
+
s.files = [
|
18
|
+
".gitignore",
|
19
|
+
"README",
|
20
|
+
"Rakefile",
|
21
|
+
"TODO",
|
22
|
+
"VERSION",
|
23
|
+
"examples.rb",
|
24
|
+
"examples/an_error.rb",
|
25
|
+
"examples/assertion_failure.rb",
|
26
|
+
"examples/assertion_success.rb",
|
27
|
+
"examples/assertion_success_and_failure.rb",
|
28
|
+
"examples/check_with_disambiguation.rb",
|
29
|
+
"examples/helpers.rb",
|
30
|
+
"examples/no_checks.rb",
|
31
|
+
"examples/no_checks_non_string.rb",
|
32
|
+
"examples/oneliner.rb",
|
33
|
+
"examples/with_checks.rb",
|
34
|
+
"examples/with_setup.rb",
|
35
|
+
"exemplor.gemspec",
|
36
|
+
"lib/exemplor.rb"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/quackingduck/exemplor}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.3.5}
|
42
|
+
s.summary = %q{A light-weight, low-fi way to provide executable usage examples or your code.}
|
43
|
+
s.test_files = [
|
44
|
+
"examples/an_error.rb",
|
45
|
+
"examples/assertion_failure.rb",
|
46
|
+
"examples/assertion_success.rb",
|
47
|
+
"examples/assertion_success_and_failure.rb",
|
48
|
+
"examples/check_with_disambiguation.rb",
|
49
|
+
"examples/helpers.rb",
|
50
|
+
"examples/no_checks.rb",
|
51
|
+
"examples/no_checks_non_string.rb",
|
52
|
+
"examples/oneliner.rb",
|
53
|
+
"examples/with_checks.rb",
|
54
|
+
"examples/with_setup.rb"
|
55
|
+
]
|
56
|
+
|
57
|
+
if s.respond_to? :specification_version then
|
58
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
59
|
+
s.specification_version = 3
|
60
|
+
|
61
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
62
|
+
else
|
63
|
+
end
|
64
|
+
else
|
65
|
+
end
|
66
|
+
end
|
data/lib/exemplor.rb
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'rubygems' # TODO: remove
|
2
|
+
require 'orderedhash'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Exemplor
|
6
|
+
|
7
|
+
class ExampleDefinitionError < StandardError ; end
|
8
|
+
|
9
|
+
class Check
|
10
|
+
|
11
|
+
attr_reader :expectation, :value
|
12
|
+
|
13
|
+
def initialize(name, value)
|
14
|
+
@name = name
|
15
|
+
@value = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](disambiguate)
|
19
|
+
@disambiguate = disambiguate
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@name + (@disambiguate ? " #{@disambiguate}" : '')
|
24
|
+
end
|
25
|
+
|
26
|
+
def is(expectation)
|
27
|
+
@expectation = expectation
|
28
|
+
end
|
29
|
+
|
30
|
+
def status
|
31
|
+
return :info if !@expectation
|
32
|
+
@value == @expectation ? :success : :failure
|
33
|
+
end
|
34
|
+
|
35
|
+
def success?
|
36
|
+
status == :success
|
37
|
+
end
|
38
|
+
|
39
|
+
def failure?
|
40
|
+
status == :failure
|
41
|
+
end
|
42
|
+
|
43
|
+
def info?
|
44
|
+
status == :info
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class Example
|
50
|
+
|
51
|
+
class << self
|
52
|
+
|
53
|
+
alias_method :helpers, :class_eval
|
54
|
+
attr_accessor :setup_block
|
55
|
+
|
56
|
+
def setup(&blk) self.setup_block = blk end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_accessor :_checks
|
61
|
+
|
62
|
+
def initialize
|
63
|
+
@_checks = []
|
64
|
+
end
|
65
|
+
|
66
|
+
# fragile. doesnt work with calls like
|
67
|
+
# Check(get('/'))
|
68
|
+
# Check foo
|
69
|
+
def Check(value)
|
70
|
+
file, line_number = caller.first.match(/^(.+):(\d+)/).captures
|
71
|
+
line = File.read(file).map[line_number.to_i - 1]
|
72
|
+
name = line[/Check\((.+?)\)/,1]
|
73
|
+
check = Check.new(name, value)
|
74
|
+
_checks << check
|
75
|
+
check
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
class Examples
|
81
|
+
|
82
|
+
attr_writer :setup_block
|
83
|
+
|
84
|
+
def initialize
|
85
|
+
@examples = OrderedHash.new
|
86
|
+
end
|
87
|
+
|
88
|
+
def add(name, &body)
|
89
|
+
@examples[name] = body
|
90
|
+
end
|
91
|
+
|
92
|
+
def run(patterns)
|
93
|
+
# unoffically supports multiple patterns
|
94
|
+
patterns = Regexp.new(patterns.join('|'))
|
95
|
+
@examples.each do |name, body|
|
96
|
+
if name =~ patterns
|
97
|
+
status, out = run_example(body)
|
98
|
+
print_yaml("#{status_icon(status)} #{name}" => out)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def list(patterns)
|
104
|
+
patterns = Regexp.new(patterns.join('|'))
|
105
|
+
list = @examples.keys.select { |name| name =~ patterns }
|
106
|
+
print_yaml list
|
107
|
+
end
|
108
|
+
|
109
|
+
def print_yaml(obj)
|
110
|
+
out = obj.to_yaml.match(/^--- \n/).post_match
|
111
|
+
out = colorize out if $stdout.tty?
|
112
|
+
print(out)
|
113
|
+
end
|
114
|
+
|
115
|
+
# hacky
|
116
|
+
def colorize(out)
|
117
|
+
require 'term/ansicolor'
|
118
|
+
out.split("\n").map do |line|
|
119
|
+
case line
|
120
|
+
when /^(?:\s{2})?(\(s\))/
|
121
|
+
start_color(line, :green)
|
122
|
+
when /^(?:\s{2})?(\(f\))/
|
123
|
+
start_color(line, :red)
|
124
|
+
when /^(?:\s{2})?(\(e\))/
|
125
|
+
start_color(line, :red)
|
126
|
+
when /^(?:\s{2})?(\(i\))/i
|
127
|
+
start_color(line, :blue)
|
128
|
+
else
|
129
|
+
line
|
130
|
+
end
|
131
|
+
end.join("\n") + "\n#{Term::ANSIColor.reset}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def start_color(line, color)
|
135
|
+
"#{Term::ANSIColor.reset}#{Term::ANSIColor.send(color)}#{line}"
|
136
|
+
end
|
137
|
+
|
138
|
+
def run_example(code)
|
139
|
+
status = :info
|
140
|
+
env = Example.new
|
141
|
+
out = begin
|
142
|
+
env.instance_eval(&Example.setup_block) if Example.setup_block
|
143
|
+
value = env.instance_eval(&code)
|
144
|
+
if env._checks.empty?
|
145
|
+
render_value(value)
|
146
|
+
else
|
147
|
+
status = :infos if env._checks.all? { |check| check.info? }
|
148
|
+
status = :success if env._checks.all? { |check| check.success? }
|
149
|
+
status = :fail if env._checks.any? { |check| check.failure? }
|
150
|
+
render_checks(env._checks)
|
151
|
+
end
|
152
|
+
rescue Object => error
|
153
|
+
status = :error
|
154
|
+
render_error(error)
|
155
|
+
end
|
156
|
+
[status, out]
|
157
|
+
end
|
158
|
+
|
159
|
+
def render_value(value)
|
160
|
+
out = case value
|
161
|
+
when String, Numeric : value
|
162
|
+
else ; value.inspect ; end
|
163
|
+
end
|
164
|
+
|
165
|
+
def render_checks(checks)
|
166
|
+
failure = nil
|
167
|
+
out = OrderedHash.new
|
168
|
+
checks.each do |check|
|
169
|
+
failure = check if check.failure?
|
170
|
+
break if failure
|
171
|
+
|
172
|
+
out["#{status_icon(check.status)} #{check.name}"] = check.value
|
173
|
+
end
|
174
|
+
if failure
|
175
|
+
fail_out = out["#{status_icon(failure.status)} #{failure.name}"] = OrderedHash.new
|
176
|
+
fail_out['expected'] = failure.expectation
|
177
|
+
fail_out['actual'] = failure.value
|
178
|
+
end
|
179
|
+
out
|
180
|
+
end
|
181
|
+
|
182
|
+
def render_error(error)
|
183
|
+
out = OrderedHash.new
|
184
|
+
out['class'] = error.class.name
|
185
|
+
out['message'] = error.message
|
186
|
+
out['backtrace'] = error.backtrace
|
187
|
+
out
|
188
|
+
end
|
189
|
+
|
190
|
+
def status_icon(status)
|
191
|
+
icon = status == :infos ? '(I)' : "(#{status.to_s.slice(0,1)})"
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
class << self
|
197
|
+
|
198
|
+
def examples
|
199
|
+
@examples ||= Examples.new
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
def eg(name = nil, &example)
|
207
|
+
return Exemplor::Example if name.nil? && example.nil?
|
208
|
+
if name.nil?
|
209
|
+
file, line_number = caller.first.match(/^(.+):(\d+)/).captures
|
210
|
+
line = File.read(file).map[line_number.to_i - 1]
|
211
|
+
name = line[/^\s*eg\s*\{\s*(.+?)\s*\}\s*$/,1] if name.nil?
|
212
|
+
raise Exemplor::ExampleDefinitionError, "example at #{caller.first} has no name so must be on one line" if name.nil?
|
213
|
+
end
|
214
|
+
Exemplor.examples.add(name, &example)
|
215
|
+
end
|
216
|
+
|
217
|
+
at_exit do
|
218
|
+
args = ARGV.dup
|
219
|
+
if args.delete('--list') || args.delete('-l')
|
220
|
+
Exemplor.examples.list(args)
|
221
|
+
else
|
222
|
+
Exemplor.examples.run(args)
|
223
|
+
end
|
224
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: exemplor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Myles Byrne
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-12 00:00:00 +11:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: myles@myles.id.au
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- README
|
27
|
+
- Rakefile
|
28
|
+
- TODO
|
29
|
+
- VERSION
|
30
|
+
- examples.rb
|
31
|
+
- examples/an_error.rb
|
32
|
+
- examples/assertion_failure.rb
|
33
|
+
- examples/assertion_success.rb
|
34
|
+
- examples/assertion_success_and_failure.rb
|
35
|
+
- examples/check_with_disambiguation.rb
|
36
|
+
- examples/helpers.rb
|
37
|
+
- examples/no_checks.rb
|
38
|
+
- examples/no_checks_non_string.rb
|
39
|
+
- examples/oneliner.rb
|
40
|
+
- examples/with_checks.rb
|
41
|
+
- examples/with_setup.rb
|
42
|
+
- exemplor.gemspec
|
43
|
+
- lib/exemplor.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://github.com/quackingduck/exemplor
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options:
|
50
|
+
- --charset=UTF-8
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.5
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: A light-weight, low-fi way to provide executable usage examples or your code.
|
72
|
+
test_files:
|
73
|
+
- examples/an_error.rb
|
74
|
+
- examples/assertion_failure.rb
|
75
|
+
- examples/assertion_success.rb
|
76
|
+
- examples/assertion_success_and_failure.rb
|
77
|
+
- examples/check_with_disambiguation.rb
|
78
|
+
- examples/helpers.rb
|
79
|
+
- examples/no_checks.rb
|
80
|
+
- examples/no_checks_non_string.rb
|
81
|
+
- examples/oneliner.rb
|
82
|
+
- examples/with_checks.rb
|
83
|
+
- examples/with_setup.rb
|