lookout 2.1.4 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -9,7 +9,7 @@ class Lookout::Diff::Algorithms::Difflib::Position
9
9
  new(Lookout::Diff::Range.new(from),
10
10
  to,
11
11
  block_given? ?
12
- to.indexes.reduce({}){ |j, (k, v)| j[k] = yield(k); j } :
12
+ to.indexes.reduce({}){ |j, (k, _)| j[k] = yield(k); j } :
13
13
  {})
14
14
  end
15
15
  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
- ((Regexp === expected.message and expected.message === actual.message) or
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
- Regexp === expected.message ?
23
- '%p≠#<%s: %p>' % [actual, expected.class, expected.message] :
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
@@ -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::Unsuccessful.new, line = nil)
8
- @results, @line = results, line
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
- expectation = Lookout::Expectation.on(expected, *Lookout.location(caller.first), &block)
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
- begin
8
- if not only_load and arg == '--'
9
- only_load = true
10
- elsif not only_load and arg =~ /\A-r(.*)/
11
- require $1
12
- else
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
@@ -1,11 +1,25 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- module Lookout::Results
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
- end
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
@@ -2,4 +2,5 @@
2
2
 
3
3
  module Lookout::Runners
4
4
  autoload :Console, 'lookout/runners/console'
5
+ autoload :Trackers, 'lookout/runners/trackers'
5
6
  end
@@ -1,24 +1,41 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  class Lookout::Runners::Console
4
- def initialize(results = Lookout::Results::Unsuccessful.new,
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
- at_exit do
14
- next if $!
15
- @expectations.flush
16
- @ui.summarize
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,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Lookout::Runners::Trackers
4
+ autoload :Failure, 'lookout/runners/trackers/failure'
5
+ end
@@ -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
@@ -1,46 +1,19 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  class Lookout::UI::Console
4
- def initialize(results, io = $stdout)
4
+ def initialize(results, io = $stderr)
5
5
  @results, @io = results, io
6
- @count = 0
7
- results.on_new do
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
- @start = Time.now.to_f
12
+ self
14
13
  end
15
14
 
16
- def summarize
17
- return if @results.succeeded?
18
- summarize_total
19
- summarize_group :errors
20
- summarize_group :failures
15
+ def flush
21
16
  @io.flush
22
- end
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
@@ -4,6 +4,6 @@ class Lookout::UI::Silent
4
4
  def start
5
5
  end
6
6
 
7
- def summarize
7
+ def flush
8
8
  end
9
9
  end
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Lookout
4
- Version = '2.1.4'
4
+ Version = '2.2.0'
5
5
  end
@@ -1,10 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  Expectations do
4
- expect Lookout.runner.to.receive.expectations_eval do
5
- Expectations{ }
6
- end
7
-
8
4
  expect [nil, nil] do
9
5
  Lookout.location('abc')
10
6
  end