lookout 2.1.4 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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