testable_examples 0.0.1
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 +4 -0
- data/Gemfile +4 -0
- data/README.md +31 -0
- data/Rakefile +9 -0
- data/lib/testable_examples.rb +8 -0
- data/lib/testable_examples/matcher.rb +33 -0
- data/lib/testable_examples/runner.rb +70 -0
- data/lib/testable_examples/version.rb +3 -0
- data/test/test1.rb +11 -0
- data/testable_examples.gemspec +21 -0
- metadata +77 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Testable Examples
|
2
|
+
|
3
|
+
Run your rdoc examples like they are tests!
|
4
|
+
|
5
|
+
## How to
|
6
|
+
|
7
|
+
In your rdoc, you might have something like this
|
8
|
+
|
9
|
+
# Example:
|
10
|
+
# Test1.new.add(1, 2)
|
11
|
+
# => 3
|
12
|
+
# Test1.new.add(1, "something")
|
13
|
+
# => TypeError: String can't be coerced into Fixnum
|
14
|
+
def add(num1, num2)
|
15
|
+
num1 + num2
|
16
|
+
end
|
17
|
+
|
18
|
+
With testable examples, simply add this to your Rakefile
|
19
|
+
|
20
|
+
desc "test_examples"
|
21
|
+
task :test do
|
22
|
+
$: << 'lib'
|
23
|
+
require 'testable_examples'
|
24
|
+
TestableExamples::Runner.new(:dir => 'lib', :include_path => 'lib', :requires => 'test1').run_examples
|
25
|
+
end
|
26
|
+
|
27
|
+
And you will now be able to validate these!
|
28
|
+
|
29
|
+
## TODO
|
30
|
+
|
31
|
+
So much, this is really just a proof-of-concept.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module TestableExamples
|
2
|
+
class Matcher
|
3
|
+
def initialize(val)
|
4
|
+
@val = val
|
5
|
+
@literal_val = begin
|
6
|
+
eval(val)
|
7
|
+
rescue Exception
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def match(*args)
|
13
|
+
o = args.compact.first
|
14
|
+
if @literal_val
|
15
|
+
@literal_val === o
|
16
|
+
elsif @val[/^[A-Z][a-z0-9_]*$/]
|
17
|
+
Object.const_get(@val.to_sym)
|
18
|
+
elsif @val[/^([A-Z][a-zA-Z0-9_]*?):(.*)$/] and o.is_a?(Exception)
|
19
|
+
o.class.to_s === $1.strip && o.message == $2.strip
|
20
|
+
else
|
21
|
+
raise "Unable to understand val type #{@val.inspect}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def match_exception?
|
26
|
+
@val[/^[A-Z]/]
|
27
|
+
end
|
28
|
+
|
29
|
+
def assert(*args)
|
30
|
+
match(*args) or raise("Unable to match #{args.inspect} against #{@val.inspect}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module TestableExamples
|
2
|
+
class Runner
|
3
|
+
def initialize(opts)
|
4
|
+
@base = opts[:dir] || Dir.pwd
|
5
|
+
@name = opts[:task_name] || "test_examples"
|
6
|
+
@include_path = opts.key?(:include_path) ? opts[:include_path] : "lib"
|
7
|
+
@requires = opts.key?(:requires) ? opts[:requires] : opts[:requires]
|
8
|
+
end
|
9
|
+
|
10
|
+
def install
|
11
|
+
desc "Test your rdoc examples"
|
12
|
+
task @name do
|
13
|
+
run_examples
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def run_examples
|
18
|
+
$: << @include_path if @include_path
|
19
|
+
Array(@requires).each {|r| require r} if @requires
|
20
|
+
in_example = false
|
21
|
+
examples = []
|
22
|
+
STDOUT.sync = true
|
23
|
+
current_example = ''
|
24
|
+
matchers = []
|
25
|
+
rb_files = File.exist?(@base) ? [@base] : Dir[File.join(@base, 'lib/**/*.rb')]
|
26
|
+
puts "Scanning #{rb_files * ', '}"
|
27
|
+
rb_files.each do |file|
|
28
|
+
lines = File.read(file).split(/\n/)
|
29
|
+
lines.each do |line|
|
30
|
+
if line[/^\s*#(.*)/] # comment
|
31
|
+
line = $1.strip
|
32
|
+
case line
|
33
|
+
when /^example:/i then in_example = true
|
34
|
+
when /^(?:# )?=+> (.*)/
|
35
|
+
if in_example
|
36
|
+
expected = $1.strip
|
37
|
+
matchers << Matcher.new(expected)
|
38
|
+
if matchers.last.match_exception?
|
39
|
+
current_example << " rescue e = $!; nil"
|
40
|
+
end
|
41
|
+
current_example << "\nmatchers[#{matchers.size - 1}].match(__example_runner, $!)"
|
42
|
+
end
|
43
|
+
when ''
|
44
|
+
unless current_example.empty?
|
45
|
+
examples << current_example
|
46
|
+
current_example = ''
|
47
|
+
end
|
48
|
+
in_example = false
|
49
|
+
else
|
50
|
+
current_example << "\n__example_runner = (" << line << ")" if in_example
|
51
|
+
end
|
52
|
+
else
|
53
|
+
unless current_example.empty?
|
54
|
+
examples << current_example
|
55
|
+
current_example = ''
|
56
|
+
end
|
57
|
+
in_example = false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
print "Running #{examples.size} example#{'s' if examples.size != 1} "
|
62
|
+
examples.each do |example|
|
63
|
+
print "."
|
64
|
+
eval(example)
|
65
|
+
end
|
66
|
+
puts " ✔"
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/test/test1.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "testable_examples/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "testable_examples"
|
7
|
+
s.version = TestableExamples::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Joshua Hull"]
|
10
|
+
s.email = ["joshbuddy@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/joshbuddy/testable_examples"
|
12
|
+
s.summary = %q{Test your examples!}
|
13
|
+
s.description = %q{Test your examples!}
|
14
|
+
|
15
|
+
s.rubyforge_project = "testable_examples"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: testable_examples
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Joshua Hull
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-03-29 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Test your examples!
|
23
|
+
email:
|
24
|
+
- joshbuddy@gmail.com
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- Gemfile
|
34
|
+
- README.md
|
35
|
+
- Rakefile
|
36
|
+
- lib/testable_examples.rb
|
37
|
+
- lib/testable_examples/matcher.rb
|
38
|
+
- lib/testable_examples/runner.rb
|
39
|
+
- lib/testable_examples/version.rb
|
40
|
+
- test/test1.rb
|
41
|
+
- testable_examples.gemspec
|
42
|
+
has_rdoc: true
|
43
|
+
homepage: https://github.com/joshbuddy/testable_examples
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project: testable_examples
|
72
|
+
rubygems_version: 1.3.7
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Test your examples!
|
76
|
+
test_files:
|
77
|
+
- test/test1.rb
|