lookout 2.1.4 → 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/README +537 -521
- data/lib/lookout.rb +0 -9
- data/lib/lookout/diff/algorithms/difflib/position.rb +1 -1
- data/lib/lookout/equalities/standarderror.rb +9 -3
- data/lib/lookout/expectations.rb +4 -19
- data/lib/lookout/expectations/line.rb +29 -0
- data/lib/lookout/rake/tasks/gem.rb +2 -2
- data/lib/lookout/rake/tasks/test/loader.rb +14 -11
- data/lib/lookout/results.rb +17 -3
- data/lib/lookout/results/error/exception.rb +1 -3
- data/lib/lookout/results/error/exception/backtrace.rb +17 -8
- data/lib/lookout/results/unsuccessful.rb +1 -7
- data/lib/lookout/runners.rb +1 -0
- data/lib/lookout/runners/console.rb +25 -8
- data/lib/lookout/runners/trackers.rb +5 -0
- data/lib/lookout/runners/trackers/failure.rb +14 -0
- data/lib/lookout/ui/console.rb +6 -33
- data/lib/lookout/ui/silent.rb +1 -1
- data/lib/lookout/version.rb +1 -1
- data/test/unit/lookout.rb +0 -4
- data/test/unit/lookout/expectations.rb +0 -38
- data/test/unit/lookout/expectations/line.rb +29 -0
- data/test/unit/lookout/results/error/exception/backtrace.rb +20 -0
- data/test/unit/lookout/results/unsuccessful.rb +0 -15
- data/test/unit/lookout/runners/trackers/failure.rb +30 -0
- data/test/unit/lookout/ui/{formatters/exception.rb → console.rb} +0 -1
- metadata +397 -408
- data/lib/lookout/results/instance.rb +0 -17
- data/test/unit/lookout/ui/formatters/exception/backtrace.rb +0 -10
data/lib/lookout.rb
CHANGED
@@ -24,16 +24,7 @@ module Lookout
|
|
24
24
|
return nil, nil unless match = /\A(.*):(\d+)(?::in .*)?\z/.match(location)
|
25
25
|
[match[1], match[2].to_i]
|
26
26
|
end
|
27
|
-
|
28
|
-
def runner(runner = nil)
|
29
|
-
return @runner = runner if runner
|
30
|
-
@runner ||= Lookout::Runners::Console.new.install
|
31
|
-
end
|
32
27
|
end
|
33
28
|
end
|
34
29
|
|
35
30
|
require 'lookout/object'
|
36
|
-
|
37
|
-
def Expectations(&block)
|
38
|
-
Lookout.runner.expectations_eval(&block)
|
39
|
-
end
|
@@ -6,7 +6,7 @@ class Lookout::Equalities::StandardError < Lookout::Equalities::Object
|
|
6
6
|
def equal?(expected, actual)
|
7
7
|
expected.equal?(actual) or
|
8
8
|
((actual.respond_to? :message rescue false) and
|
9
|
-
((
|
9
|
+
((regexp(expected) and regexp(expected) === actual.message) or
|
10
10
|
expected.message == actual.message))
|
11
11
|
end
|
12
12
|
|
@@ -19,8 +19,14 @@ class Lookout::Equalities::StandardError < Lookout::Equalities::Object
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def format(expected, actual)
|
22
|
-
|
23
|
-
'%p≠#<%s: %p>' % [actual, expected.class, expected
|
22
|
+
regexp(expected) ?
|
23
|
+
'%p≠#<%s: %p>' % [actual, expected.class, regexp(expected)] :
|
24
24
|
super
|
25
25
|
end
|
26
|
+
|
27
|
+
def regexp(expected)
|
28
|
+
return expected.message if Regexp === expected.message
|
29
|
+
return Regexp.new(expected.message) if expected.message =~ /\A\(\?-[mix]+:.*\)\z/
|
30
|
+
nil
|
31
|
+
end
|
26
32
|
end
|
data/lib/lookout/expectations.rb
CHANGED
@@ -2,12 +2,11 @@
|
|
2
2
|
|
3
3
|
class Lookout::Expectations
|
4
4
|
autoload :Behavior, 'lookout/expectations/behavior'
|
5
|
+
autoload :Line, 'lookout/expectations/line'
|
5
6
|
autoload :State, 'lookout/expectations/state'
|
6
7
|
|
7
|
-
def initialize(results = Lookout::Results
|
8
|
-
@results
|
9
|
-
@previous = nil
|
10
|
-
@ran_previous = false
|
8
|
+
def initialize(results = Lookout::Results.new)
|
9
|
+
@results = results
|
11
10
|
end
|
12
11
|
|
13
12
|
def mock
|
@@ -39,26 +38,12 @@ class Lookout::Expectations
|
|
39
38
|
end
|
40
39
|
|
41
40
|
def expect(expected, &block)
|
42
|
-
|
43
|
-
if @line
|
44
|
-
unless @ran_previous
|
45
|
-
if @previous and @previous.line <= @line and expectation.line > @line
|
46
|
-
@results << @previous.evaluate
|
47
|
-
@ran_previous = true
|
48
|
-
@previous = nil
|
49
|
-
else
|
50
|
-
@previous = expectation
|
51
|
-
end
|
52
|
-
end
|
53
|
-
else
|
54
|
-
@results << expectation.evaluate
|
55
|
-
end
|
41
|
+
@results << Lookout::Expectation.on(expected, *Lookout.location(caller.first), &block).evaluate
|
56
42
|
self
|
57
43
|
end
|
58
44
|
|
59
45
|
# TODO: It would be great if this method wasn’t necessary.
|
60
46
|
def flush
|
61
|
-
@results << @previous.evaluate if @previous
|
62
47
|
self
|
63
48
|
end
|
64
49
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Expectations::Line < Lookout::Expectations
|
4
|
+
def initialize(line, results = Lookout::Results.new)
|
5
|
+
super results
|
6
|
+
@line = line
|
7
|
+
@previous = nil
|
8
|
+
@ran_previous = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def expect(expected)
|
12
|
+
return self if @ran_previous
|
13
|
+
expectation = Lookout::Expectation.on(expected, *Lookout.location(caller.first), &Proc.new)
|
14
|
+
if @previous and @previous.line <= @line and expectation.line > @line
|
15
|
+
flush
|
16
|
+
@previous = nil
|
17
|
+
@ran_previous = true
|
18
|
+
else
|
19
|
+
@previous = expectation
|
20
|
+
end
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
# TODO: It would be great if this method wasn’t necessary.
|
25
|
+
def flush
|
26
|
+
@results << @previous.evaluate if @previous
|
27
|
+
self
|
28
|
+
end
|
29
|
+
end
|
@@ -14,7 +14,7 @@ class Lookout::Rake::Tasks::Gem < Rake::TaskLib
|
|
14
14
|
def define
|
15
15
|
desc 'Build %s' % specification.file_name
|
16
16
|
task :build => specification.file_name
|
17
|
-
file specification.file_name => specification.files do
|
17
|
+
file specification.file_name => [specification.loaded_from] + specification.files do
|
18
18
|
when_writing 'Building %s' % specification.file_name do
|
19
19
|
require 'rubygems' unless defined? Gem
|
20
20
|
require 'rubygems/installer' unless defined? Gem::Builder
|
@@ -26,7 +26,7 @@ class Lookout::Rake::Tasks::Gem < Rake::TaskLib
|
|
26
26
|
task :check => :build do
|
27
27
|
require 'rubygems' unless defined? Gem
|
28
28
|
require 'rubygems/installer' unless defined? Gem::Installer
|
29
|
-
checkdir = specification.full_name
|
29
|
+
checkdir = File.join(Lookout::Rake::Tasks.top_srcdir, specification.full_name)
|
30
30
|
Gem::Installer.new(specification.file_name, :unpack => true).unpack checkdir
|
31
31
|
sh 'rake --rakefile %s/Rakefile -s test' % checkdir
|
32
32
|
rm_r checkdir
|
@@ -2,18 +2,21 @@
|
|
2
2
|
|
3
3
|
require 'lookout'
|
4
4
|
|
5
|
+
results = Lookout::Results.new
|
6
|
+
line = ENV['LINE'] && ENV['LINE'].to_i
|
7
|
+
runner = Lookout::Runners::Console.new(results,
|
8
|
+
line ?
|
9
|
+
Lookout::Expectations::Line.new(line, results) :
|
10
|
+
Lookout::Expectations.new(results),
|
11
|
+
Lookout::UI::Console.new(results)).install
|
5
12
|
only_load = false
|
6
13
|
ARGV.each do |arg|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
load arg
|
14
|
-
end
|
15
|
-
rescue SyntaxError => e
|
16
|
-
raise e unless matches = %r{\A(.*?:\d+): (.*)}m.match(e.message)
|
17
|
-
raise SyntaxError, matches[2], [matches[1]]
|
14
|
+
if not only_load and arg == '--'
|
15
|
+
only_load = true
|
16
|
+
elsif not only_load and arg =~ /\A-r(.*)/
|
17
|
+
require $1
|
18
|
+
else
|
19
|
+
runner.load arg
|
18
20
|
end
|
19
21
|
end
|
22
|
+
runner.exit
|
data/lib/lookout/results.rb
CHANGED
@@ -1,11 +1,25 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
|
3
|
+
class Lookout::Results
|
4
4
|
autoload :Error, 'lookout/results/error'
|
5
5
|
autoload :Failure, 'lookout/results/failure'
|
6
6
|
autoload :Failures, 'lookout/results/failures'
|
7
7
|
autoload :Fulfilled, 'lookout/results/fulfilled'
|
8
|
-
|
9
|
-
autoload :Instance, 'lookout/results/instance'
|
10
8
|
autoload :Unsuccessful, 'lookout/results/unsuccessful'
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@listeners = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_new(&block)
|
15
|
+
@listeners << block
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def <<(result)
|
20
|
+
@listeners.each do |listener|
|
21
|
+
listener.call result
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
11
25
|
end
|
@@ -25,12 +25,10 @@ class Lookout::Results::Error::Exception
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def backtrace
|
28
|
-
@backtrace ||= Backtrace.new(@exception.backtrace)
|
28
|
+
@backtrace ||= Backtrace.new(@exception.backtrace, SystemStackError === @exception)
|
29
29
|
end
|
30
30
|
|
31
31
|
def to_s
|
32
32
|
"%s\n%s" % [message, backtrace]
|
33
33
|
end
|
34
|
-
|
35
|
-
attr_reader :exception
|
36
34
|
end
|
@@ -1,26 +1,26 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
class Lookout::Results::Error::Exception::Backtrace
|
4
|
-
def initialize(backtrace, filter = ENV['LOOKOUT_DO_NOT_FILTER_BACKTRACE'].nil?)
|
5
|
-
@filter = filter
|
4
|
+
def initialize(backtrace, trim, filter = ENV['LOOKOUT_DO_NOT_FILTER_BACKTRACE'].nil?)
|
6
5
|
@backtrace = case backtrace
|
7
6
|
when nil then []
|
8
7
|
when String then [backtrace]
|
9
8
|
when Array then backtrace.select{ |l| String === l }
|
10
9
|
end
|
11
|
-
|
12
|
-
|
13
|
-
def backtrace
|
14
|
-
return @backtrace unless @filter
|
15
|
-
before or outside or @backtrace
|
10
|
+
@trim, @filter = trim, filter
|
16
11
|
end
|
17
12
|
|
18
13
|
def to_s
|
19
|
-
backtrace.map{ |location| "\tfrom %s" % location }.join("\n")
|
14
|
+
trim(backtrace.map{ |location| "\tfrom %s" % location }).join("\n")
|
20
15
|
end
|
21
16
|
|
22
17
|
private
|
23
18
|
|
19
|
+
def backtrace
|
20
|
+
return @backtrace unless @filter
|
21
|
+
before or outside or @backtrace
|
22
|
+
end
|
23
|
+
|
24
24
|
def before
|
25
25
|
nilify(@backtrace.take_while{ |location| not reject? location })
|
26
26
|
end
|
@@ -37,5 +37,14 @@ private
|
|
37
37
|
location.start_with? Root
|
38
38
|
end
|
39
39
|
|
40
|
+
def trim(locations)
|
41
|
+
return locations unless @trim and locations.length > Head + Tail + 5
|
42
|
+
locations[0...Head] +
|
43
|
+
["\t ... %d levels ..." % (locations.length - Head - Tail)] +
|
44
|
+
locations[-Tail..-1]
|
45
|
+
end
|
46
|
+
|
40
47
|
Root = 4.times.reduce(__FILE__){ |path, _| File.dirname(path) }
|
48
|
+
Head = 8
|
49
|
+
Tail = 5
|
41
50
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
class Lookout::Results::Unsuccessful
|
4
|
-
include Lookout::Results::Instance
|
5
|
-
|
3
|
+
class Lookout::Results::Unsuccessful < Lookout::Results
|
6
4
|
include Enumerable
|
7
5
|
|
8
6
|
def initialize
|
@@ -23,10 +21,6 @@ class Lookout::Results::Unsuccessful
|
|
23
21
|
self
|
24
22
|
end
|
25
23
|
|
26
|
-
def succeeded?
|
27
|
-
@unsuccessful.empty?
|
28
|
-
end
|
29
|
-
|
30
24
|
def errors
|
31
25
|
select{ |result| Lookout::Results::Error === result }
|
32
26
|
end
|
data/lib/lookout/runners.rb
CHANGED
@@ -1,24 +1,41 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
class Lookout::Runners::Console
|
4
|
-
def initialize(results = Lookout::Results
|
5
|
-
expectations = Lookout::Expectations.new(results,
|
6
|
-
ENV['LINE'] && ENV['LINE'].to_i),
|
4
|
+
def initialize(results = Lookout::Results.new,
|
5
|
+
expectations = Lookout::Expectations.new(results),
|
7
6
|
ui = Lookout::UI::Console.new(results))
|
8
7
|
@results, @expectations, @ui = results, expectations, ui
|
9
8
|
@ui.start
|
9
|
+
@failed = Lookout::Runners::Trackers::Failure.new(@results)
|
10
10
|
end
|
11
11
|
|
12
12
|
def install
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
exit 1 unless @results.succeeded?
|
13
|
+
Kernel.module_exec(self) do |runner|
|
14
|
+
define_method :Expectations do |&block|
|
15
|
+
runner.expectations_eval(&block)
|
16
|
+
end
|
18
17
|
end
|
19
18
|
self
|
20
19
|
end
|
21
20
|
|
21
|
+
def load(file)
|
22
|
+
expectations_eval do
|
23
|
+
begin
|
24
|
+
load file
|
25
|
+
rescue SyntaxError => e
|
26
|
+
raise unless matches = %r{\A(.*?:\d+): (.*)}m.match(e.message)
|
27
|
+
raise SyntaxError, matches[2], [matches[1]]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def exit
|
33
|
+
@expectations.flush
|
34
|
+
@ui.flush
|
35
|
+
super 1 if @failed.failed?
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
22
39
|
def expectations_eval(&block)
|
23
40
|
@expectations.instance_eval(&block)
|
24
41
|
rescue Interrupt, NoMemoryError, SignalException, SystemExit
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Runners::Trackers::Failure
|
4
|
+
def initialize(results)
|
5
|
+
@failed = false
|
6
|
+
results.on_new do |result|
|
7
|
+
@failed = !(Lookout::Results::Fulfilled === result) unless @failed
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def failed?
|
12
|
+
@failed
|
13
|
+
end
|
14
|
+
end
|
data/lib/lookout/ui/console.rb
CHANGED
@@ -1,46 +1,19 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
class Lookout::UI::Console
|
4
|
-
def initialize(results, io = $
|
4
|
+
def initialize(results, io = $stderr)
|
5
5
|
@results, @io = results, io
|
6
|
-
|
7
|
-
|
8
|
-
@count += 1
|
6
|
+
results.on_new do |result|
|
7
|
+
@io.puts result unless Lookout::Results::Fulfilled === result
|
9
8
|
end
|
10
9
|
end
|
11
10
|
|
12
11
|
def start
|
13
|
-
|
12
|
+
self
|
14
13
|
end
|
15
14
|
|
16
|
-
def
|
17
|
-
return if @results.succeeded?
|
18
|
-
summarize_total
|
19
|
-
summarize_group :errors
|
20
|
-
summarize_group :failures
|
15
|
+
def flush
|
21
16
|
@io.flush
|
22
|
-
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def summarize_total
|
27
|
-
@io.printf "Ran %d expectations in %.3f seconds: %s\n",
|
28
|
-
@count,
|
29
|
-
Time.now.to_f - @start,
|
30
|
-
[['errors', @results.errors.size],
|
31
|
-
['failures', @results.failures.size]].tap{ |types|
|
32
|
-
types << ['fulfillments', @count - types.reduce(0){ |sum, pair| sum + pair[1] }]
|
33
|
-
}.select{ |type, size| size > 0 }.
|
34
|
-
map{ |type, size| '%d %s' % [size, type] }.
|
35
|
-
join(', ')
|
36
|
-
end
|
37
|
-
|
38
|
-
def summarize_group(type)
|
39
|
-
group = @results.send(type)
|
40
|
-
return if group.empty?
|
41
|
-
@io.puts '', type.to_s.upcase, ''
|
42
|
-
group.each do |item|
|
43
|
-
@io.puts item, ''
|
44
|
-
end
|
17
|
+
self
|
45
18
|
end
|
46
19
|
end
|
data/lib/lookout/ui/silent.rb
CHANGED
data/lib/lookout/version.rb
CHANGED