proof 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/proof/core_ext/object.rb +26 -0
- data/lib/proof/core_ext.rb +1 -0
- data/lib/proof/description.rb +7 -0
- data/lib/proof/error.rb +37 -0
- data/lib/proof/execution.rb +23 -0
- data/lib/proof/extend.rb +45 -0
- data/lib/proof/namespace.rb +11 -0
- data/lib/proof/output.rb +86 -0
- data/lib/proof/proof.rb +34 -24
- data/lib/proof/result.rb +19 -0
- data/lib/proof/runner.rb +2 -0
- data/lib/proof/suite.rb +82 -0
- data/lib/proof/summary.rb +61 -0
- data/lib/proof.rb +17 -1
- metadata +18 -7
- data/lib/proof/version.rb +0 -3
@@ -0,0 +1,26 @@
|
|
1
|
+
module Proof
|
2
|
+
module CoreExt
|
3
|
+
module Object
|
4
|
+
module Methods
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def define_prove
|
8
|
+
::Object.class_eval do
|
9
|
+
def prove(&blk)
|
10
|
+
obj_under_test = self
|
11
|
+
Proof::Extend.into obj_under_test
|
12
|
+
result = Proof::Execution.run Description.current, obj_under_test, blk
|
13
|
+
result.write
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def undefine_prove
|
19
|
+
::Object.class_eval do
|
20
|
+
undef :prove
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'proof/core_ext/object'
|
data/lib/proof/error.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Proof
|
2
|
+
class Error
|
3
|
+
include Initializer
|
4
|
+
|
5
|
+
initializer :error
|
6
|
+
|
7
|
+
|
8
|
+
def self.output(error)
|
9
|
+
instance = new error
|
10
|
+
instance.output
|
11
|
+
end
|
12
|
+
|
13
|
+
def backtrace
|
14
|
+
@backtrace ||= @error.backtrace.extend Backtrace
|
15
|
+
end
|
16
|
+
|
17
|
+
def output
|
18
|
+
backtrace.remove_proof_framework_frames!
|
19
|
+
Output.error error_message
|
20
|
+
Output.backtrace " #{backtrace.join("\n ")}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def error_message
|
24
|
+
"(#{error.class}) \"#{error.message}\" at #{backtrace.first_frame}"
|
25
|
+
end
|
26
|
+
|
27
|
+
module Backtrace
|
28
|
+
def first_frame
|
29
|
+
first.gsub(/.*\/proofs\/proof\/(.*\.rb.*)/,'\1')
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_proof_framework_frames!
|
33
|
+
reject! {|backtrace_line| backtrace_line =~ /proof\/lib\/proof/ }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Proof
|
2
|
+
class Execution
|
3
|
+
include Initializer
|
4
|
+
|
5
|
+
initializer :description, :obj_under_test, :blk
|
6
|
+
|
7
|
+
def self.run(description, obj_under_test, blk)
|
8
|
+
instance = new description, obj_under_test, blk
|
9
|
+
instance.run
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
error = nil
|
14
|
+
begin
|
15
|
+
result = obj_under_test.instance_eval &blk
|
16
|
+
status = result ? :pass : :fail
|
17
|
+
rescue => error
|
18
|
+
status = :error
|
19
|
+
end
|
20
|
+
Proof::Result.new description, status, error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/proof/extend.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Proof
|
2
|
+
class Extend
|
3
|
+
include Initializer
|
4
|
+
|
5
|
+
initializer :obj_under_test
|
6
|
+
|
7
|
+
def self.into(obj_under_test)
|
8
|
+
instance = new obj_under_test
|
9
|
+
instance.extend_obj
|
10
|
+
end
|
11
|
+
|
12
|
+
def mod
|
13
|
+
@mod ||= ([Module, Class].include?(obj_under_test.class) ? obj_under_test : obj_under_test.class)
|
14
|
+
end
|
15
|
+
|
16
|
+
def extend_obj
|
17
|
+
if extension.nil?
|
18
|
+
Output.details "#{mod.name} not extended by #{extension_name}"
|
19
|
+
return obj_under_test
|
20
|
+
end
|
21
|
+
|
22
|
+
Output.details "Extending #{extension_name} into #{mod.name}"
|
23
|
+
obj_under_test.extend extension
|
24
|
+
end
|
25
|
+
|
26
|
+
def extension
|
27
|
+
return @extension if @extension
|
28
|
+
|
29
|
+
Output.details "#{mod.name} has #{defined ? '' : 'no '}inner Proof"
|
30
|
+
|
31
|
+
return nil unless defined
|
32
|
+
|
33
|
+
Output.details "Getting constant #{mod.name}::Proof"
|
34
|
+
@extension ||= mod.const_get :Proof, search_ancestors=false
|
35
|
+
end
|
36
|
+
|
37
|
+
def defined
|
38
|
+
@defined ||= mod.const_defined? :Proof, search_ancestors=false
|
39
|
+
end
|
40
|
+
|
41
|
+
def extension_name
|
42
|
+
"#{mod.name}::Proof"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/proof/output.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Proof
|
4
|
+
class Output
|
5
|
+
include Single
|
6
|
+
include Setter::Settings
|
7
|
+
include ::Output
|
8
|
+
|
9
|
+
level :info
|
10
|
+
|
11
|
+
writer :h1, :level => :info do |text|
|
12
|
+
prefix :h1, text.upcase
|
13
|
+
end
|
14
|
+
|
15
|
+
writer :h2, :level => :info do |text|
|
16
|
+
prefix :h2, text
|
17
|
+
end
|
18
|
+
|
19
|
+
writer :pass, :level => :info do |text|
|
20
|
+
prefix :pass, "Pass: #{text}"
|
21
|
+
end
|
22
|
+
|
23
|
+
writer :fail, :level => :info do |text|
|
24
|
+
prefix :fail, "-> Fail: #{text}"
|
25
|
+
end
|
26
|
+
|
27
|
+
writer :error, :level => :warn do |text|
|
28
|
+
prefix :error, "Error: #{text}"
|
29
|
+
end
|
30
|
+
|
31
|
+
writer :backtrace, :level => :error do |text|
|
32
|
+
prefix :backtrace, text
|
33
|
+
end
|
34
|
+
|
35
|
+
writer :details, :level => :debug do |text|
|
36
|
+
prefix :details, "! #{text}"
|
37
|
+
end
|
38
|
+
|
39
|
+
writer :note, :level => :info do |text|
|
40
|
+
prefix :note, "* #{text}"
|
41
|
+
end
|
42
|
+
|
43
|
+
writer :info, :level => :info do |text|
|
44
|
+
prefix :info, text
|
45
|
+
end
|
46
|
+
|
47
|
+
writer :summary, :level => :info do |text|
|
48
|
+
prefix :summary, text.upcase
|
49
|
+
end
|
50
|
+
|
51
|
+
def prefix(method, text)
|
52
|
+
lines = lines(method)
|
53
|
+
"#{lines}#{text}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def lines(method)
|
57
|
+
if [:h1, :summary].include? method
|
58
|
+
lines = 2
|
59
|
+
elsif [:h2, :details, :note, :info].include? method
|
60
|
+
lines = 1
|
61
|
+
elsif [:pass, :fail].include? method
|
62
|
+
if last_method? :h1, :h2, :error, :backtrace
|
63
|
+
lines = 1
|
64
|
+
else
|
65
|
+
lines = 0
|
66
|
+
end
|
67
|
+
elsif method == :error
|
68
|
+
lines = 1
|
69
|
+
elsif method == :backtrace
|
70
|
+
unless last_method? :error
|
71
|
+
lines = 1
|
72
|
+
else
|
73
|
+
lines = 0
|
74
|
+
end
|
75
|
+
else
|
76
|
+
lines = 1
|
77
|
+
end
|
78
|
+
|
79
|
+
new_line lines
|
80
|
+
end
|
81
|
+
|
82
|
+
def new_line(num=1)
|
83
|
+
"\n" * num
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/proof/proof.rb
CHANGED
@@ -1,32 +1,42 @@
|
|
1
|
-
|
1
|
+
module Proof
|
2
|
+
def proof(description=nil, &block)
|
3
|
+
Proof::Description.current = description
|
4
|
+
Proof.begin
|
5
|
+
yield
|
6
|
+
Proof.end
|
7
|
+
Proof::Description.current = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def desc(description)
|
11
|
+
Proof::Description.current = description
|
12
|
+
end
|
2
13
|
|
3
|
-
|
4
|
-
|
5
|
-
|
14
|
+
def title(title)
|
15
|
+
Proof::Output.h1 title
|
16
|
+
end
|
17
|
+
|
18
|
+
def heading(heading)
|
19
|
+
Proof::Output.h2 heading
|
6
20
|
if block_given?
|
7
21
|
yield
|
8
|
-
undef_prove
|
9
22
|
end
|
10
23
|
end
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def prove(&blk)
|
16
|
-
proof_module = self.class.const_get :Proof
|
17
|
-
mixin proof_module
|
18
|
-
proof = instance_eval &blk
|
19
|
-
unmix proof_module
|
20
|
-
proof
|
21
|
-
end
|
22
|
-
end
|
24
|
+
|
25
|
+
def section(heading=nil)
|
26
|
+
Proof::Output.h2 heading if heading
|
27
|
+
yield if block_given?
|
23
28
|
end
|
24
|
-
|
25
|
-
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
alias :block :section
|
30
|
+
|
31
|
+
def comment(comment)
|
32
|
+
Proof::Output.note comment
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.begin
|
36
|
+
CoreExt::Object::Methods.define_prove
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.end
|
40
|
+
CoreExt::Object::Methods.undefine_prove
|
30
41
|
end
|
31
|
-
module_function :undef_prove
|
32
42
|
end
|
data/lib/proof/result.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Proof
|
2
|
+
class Result
|
3
|
+
include Initializer
|
4
|
+
|
5
|
+
initializer :description, :status, :error
|
6
|
+
|
7
|
+
def write
|
8
|
+
Output.write output_method, description
|
9
|
+
Error.output error if status == :error
|
10
|
+
end
|
11
|
+
|
12
|
+
def output_method
|
13
|
+
if status == :error
|
14
|
+
return :fail
|
15
|
+
end
|
16
|
+
return status
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/proof/runner.rb
ADDED
data/lib/proof/suite.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Proof
|
5
|
+
class Suite
|
6
|
+
attr_reader :files
|
7
|
+
|
8
|
+
def device
|
9
|
+
@device ||= self.class.default_device
|
10
|
+
end
|
11
|
+
|
12
|
+
def output
|
13
|
+
@output ||= self.class.default_output
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(files, device = nil, output = nil)
|
17
|
+
@files = files
|
18
|
+
@device = device
|
19
|
+
@output = output
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.default_device
|
23
|
+
Output::Devices.build_device(:string_io, :name => :suite_results)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.default_output
|
27
|
+
Proof::Output.instance
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.run(*args)
|
31
|
+
device = default_device
|
32
|
+
output = default_output
|
33
|
+
|
34
|
+
if args.last.is_a? Hash
|
35
|
+
opts = args.pop
|
36
|
+
device = opts[:device] || device
|
37
|
+
output = opts[:output] || output
|
38
|
+
end
|
39
|
+
|
40
|
+
base_dir = File.expand_path(File.dirname(caller[0]))
|
41
|
+
file_patterns = flatten(args)
|
42
|
+
files = glob(file_patterns, base_dir)
|
43
|
+
|
44
|
+
if files.empty?
|
45
|
+
output.summary "!! Suite has no files"
|
46
|
+
return :failure
|
47
|
+
end
|
48
|
+
|
49
|
+
instance = new files, device, output
|
50
|
+
results = instance.run
|
51
|
+
|
52
|
+
Summary.output(results, output)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.glob(patterns, base_dir)
|
56
|
+
files = []
|
57
|
+
patterns.each do |pattern|
|
58
|
+
pattern = Pathname.new(pattern).absolute? ? pattern : File.join(base_dir, pattern)
|
59
|
+
files.concat Dir.glob(pattern)
|
60
|
+
end
|
61
|
+
files
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.flatten(args)
|
65
|
+
files = []
|
66
|
+
args.each do |pattern|
|
67
|
+
files.concat pattern.is_a?(Array) ? pattern : [pattern]
|
68
|
+
end
|
69
|
+
files
|
70
|
+
end
|
71
|
+
|
72
|
+
def run
|
73
|
+
output.push_device(device) do
|
74
|
+
files.each do |file|
|
75
|
+
load file
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
device.readlines
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Proof
|
2
|
+
class Summary
|
3
|
+
include Initializer
|
4
|
+
|
5
|
+
PASS_PATTERN = /Pass:.*$/
|
6
|
+
FAIL_PATTERN = /-> Fail:.*$/
|
7
|
+
ERROR_PATTERN = /Error:.*$/
|
8
|
+
|
9
|
+
initializer :results, :the_output
|
10
|
+
|
11
|
+
def self.output(results, output)
|
12
|
+
instance = new results, output
|
13
|
+
instance.output
|
14
|
+
instance.status
|
15
|
+
end
|
16
|
+
|
17
|
+
def passes
|
18
|
+
results.grep PASS_PATTERN
|
19
|
+
end
|
20
|
+
|
21
|
+
def fails
|
22
|
+
results.grep FAIL_PATTERN
|
23
|
+
end
|
24
|
+
|
25
|
+
def errors
|
26
|
+
results.grep ERROR_PATTERN
|
27
|
+
end
|
28
|
+
|
29
|
+
def status
|
30
|
+
if no_results? or any_failures?
|
31
|
+
@status = :failure
|
32
|
+
else any_successes?
|
33
|
+
@status = :success
|
34
|
+
end
|
35
|
+
|
36
|
+
@status
|
37
|
+
end
|
38
|
+
|
39
|
+
def no_results?
|
40
|
+
[passes.count, fails.count, errors.count].all? { |count| count == 0 }
|
41
|
+
end
|
42
|
+
|
43
|
+
def any_failures?
|
44
|
+
[fails.count, errors.count].any? { |count| count > 0 }
|
45
|
+
end
|
46
|
+
|
47
|
+
def any_successes?
|
48
|
+
[fails.count, errors.count].any? { |count| count > 0 }
|
49
|
+
end
|
50
|
+
|
51
|
+
def summary
|
52
|
+
"Passed: #{passes.count}\n" \
|
53
|
+
"Failed: #{fails.count}\n" \
|
54
|
+
"Errors: #{errors.count}\n"
|
55
|
+
end
|
56
|
+
|
57
|
+
def output
|
58
|
+
@the_output.summary summary
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/proof.rb
CHANGED
@@ -1 +1,17 @@
|
|
1
|
-
require '
|
1
|
+
require 'logging'
|
2
|
+
require 'single'
|
3
|
+
require 'setter'
|
4
|
+
require 'output'
|
5
|
+
require 'initializer'
|
6
|
+
|
7
|
+
require 'proof/namespace'
|
8
|
+
require 'proof/description'
|
9
|
+
require 'proof/extend'
|
10
|
+
require 'proof/result'
|
11
|
+
require 'proof/execution'
|
12
|
+
require 'proof/error'
|
13
|
+
require 'proof/core_ext'
|
14
|
+
require 'proof/proof'
|
15
|
+
require 'proof/output'
|
16
|
+
require 'proof/suite'
|
17
|
+
require 'proof/summary'
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
-
|
8
|
+
- The Sans Collective
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-04-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: logging
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
@@ -33,10 +33,21 @@ executables: []
|
|
33
33
|
extensions: []
|
34
34
|
extra_rdoc_files: []
|
35
35
|
files:
|
36
|
+
- lib/proof/core_ext/object.rb
|
37
|
+
- lib/proof/core_ext.rb
|
38
|
+
- lib/proof/description.rb
|
39
|
+
- lib/proof/error.rb
|
40
|
+
- lib/proof/execution.rb
|
41
|
+
- lib/proof/extend.rb
|
42
|
+
- lib/proof/namespace.rb
|
43
|
+
- lib/proof/output.rb
|
36
44
|
- lib/proof/proof.rb
|
37
|
-
- lib/proof/
|
45
|
+
- lib/proof/result.rb
|
46
|
+
- lib/proof/runner.rb
|
47
|
+
- lib/proof/suite.rb
|
48
|
+
- lib/proof/summary.rb
|
38
49
|
- lib/proof.rb
|
39
|
-
homepage:
|
50
|
+
homepage: https://github.com/Sans/proof
|
40
51
|
licenses: []
|
41
52
|
post_install_message:
|
42
53
|
rdoc_options: []
|
@@ -56,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
67
|
version: '0'
|
57
68
|
requirements: []
|
58
69
|
rubyforge_project:
|
59
|
-
rubygems_version: 1.8.
|
70
|
+
rubygems_version: 1.8.25
|
60
71
|
signing_key:
|
61
72
|
specification_version: 3
|
62
73
|
summary: Proof Library
|
data/lib/proof/version.rb
DELETED