lookout 2.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/README +645 -0
- data/Rakefile +9 -0
- data/lib/lookout.rb +34 -0
- data/lib/lookout/aphonic.rb +40 -0
- data/lib/lookout/benchmark.rb +11 -0
- data/lib/lookout/diff.rb +10 -0
- data/lib/lookout/diff/algorithms.rb +5 -0
- data/lib/lookout/diff/algorithms/difflib.rb +38 -0
- data/lib/lookout/diff/algorithms/difflib/position.rb +92 -0
- data/lib/lookout/diff/algorithms/difflib/position/to.rb +47 -0
- data/lib/lookout/diff/formats.rb +7 -0
- data/lib/lookout/diff/formats/hash.rb +53 -0
- data/lib/lookout/diff/formats/inline.rb +39 -0
- data/lib/lookout/diff/formats/unified.rb +57 -0
- data/lib/lookout/diff/group.rb +61 -0
- data/lib/lookout/diff/groups.rb +34 -0
- data/lib/lookout/diff/match.rb +36 -0
- data/lib/lookout/diff/operation.rb +33 -0
- data/lib/lookout/diff/operations.rb +36 -0
- data/lib/lookout/diff/operations/delete.rb +9 -0
- data/lib/lookout/diff/operations/equal.rb +27 -0
- data/lib/lookout/diff/operations/insert.rb +9 -0
- data/lib/lookout/diff/operations/replace.rb +9 -0
- data/lib/lookout/diff/range.rb +91 -0
- data/lib/lookout/equality.rb +178 -0
- data/lib/lookout/expectation.rb +50 -0
- data/lib/lookout/expectations.rb +62 -0
- data/lib/lookout/expectations/behavior.rb +20 -0
- data/lib/lookout/expectations/state.rb +29 -0
- data/lib/lookout/mock.rb +18 -0
- data/lib/lookout/mock/method.rb +70 -0
- data/lib/lookout/mock/method/arguments.rb +33 -0
- data/lib/lookout/mock/method/arguments/any.rb +11 -0
- data/lib/lookout/mock/method/arguments/anything.rb +11 -0
- data/lib/lookout/mock/method/arguments/list.rb +15 -0
- data/lib/lookout/mock/method/arguments/none.rb +11 -0
- data/lib/lookout/mock/method/arguments/one.rb +11 -0
- data/lib/lookout/mock/method/calls.rb +11 -0
- data/lib/lookout/mock/method/calls/class.rb +21 -0
- data/lib/lookout/mock/method/calls/exactly.rb +28 -0
- data/lib/lookout/mock/method/calls/instance.rb +25 -0
- data/lib/lookout/mock/method/calls/lower.rb +22 -0
- data/lib/lookout/mock/method/calls/upper.rb +22 -0
- data/lib/lookout/mock/methods.rb +12 -0
- data/lib/lookout/mock/object.rb +12 -0
- data/lib/lookout/object.rb +11 -0
- data/lib/lookout/output.rb +21 -0
- data/lib/lookout/rake/tasks.rb +36 -0
- data/lib/lookout/rake/tasks/gem.rb +49 -0
- data/lib/lookout/rake/tasks/tags.rb +16 -0
- data/lib/lookout/rake/tasks/test.rb +46 -0
- data/lib/lookout/rake/tasks/test/loader.rb +19 -0
- data/lib/lookout/recorder.rb +45 -0
- data/lib/lookout/recorder/not.rb +11 -0
- data/lib/lookout/recorder/tape.rb +21 -0
- data/lib/lookout/recorders.rb +6 -0
- data/lib/lookout/recorders/reception.rb +47 -0
- data/lib/lookout/recorders/state.rb +35 -0
- data/lib/lookout/result.rb +23 -0
- data/lib/lookout/results.rb +46 -0
- data/lib/lookout/results/error.rb +18 -0
- data/lib/lookout/results/error/exception.rb +36 -0
- data/lib/lookout/results/error/exception/backtrace.rb +41 -0
- data/lib/lookout/results/failure.rb +16 -0
- data/lib/lookout/results/failures.rb +6 -0
- data/lib/lookout/results/failures/behavior.rb +4 -0
- data/lib/lookout/results/failures/state.rb +4 -0
- data/lib/lookout/results/fulfilled.rb +9 -0
- data/lib/lookout/runners.rb +5 -0
- data/lib/lookout/runners/console.rb +22 -0
- data/lib/lookout/stub.rb +16 -0
- data/lib/lookout/stub/method.rb +105 -0
- data/lib/lookout/stub/methods.rb +18 -0
- data/lib/lookout/stub/object.rb +11 -0
- data/lib/lookout/ui.rb +7 -0
- data/lib/lookout/ui/console.rb +36 -0
- data/lib/lookout/ui/silent.rb +12 -0
- data/lib/lookout/version.rb +5 -0
- data/lib/lookout/xml.rb +17 -0
- data/test/unit/examples.rb +169 -0
- data/test/unit/lookout.rb +7 -0
- data/test/unit/lookout/diff.rb +4 -0
- data/test/unit/lookout/diff/algorithms/difflib.rb +56 -0
- data/test/unit/lookout/diff/algorithms/difflib/position.rb +92 -0
- data/test/unit/lookout/diff/algorithms/difflib/position/to.rb +12 -0
- data/test/unit/lookout/diff/formats/inline.rb +17 -0
- data/test/unit/lookout/diff/formats/unified.rb +67 -0
- data/test/unit/lookout/diff/group.rb +4 -0
- data/test/unit/lookout/diff/groups.rb +102 -0
- data/test/unit/lookout/diff/match.rb +5 -0
- data/test/unit/lookout/diff/operations.rb +22 -0
- data/test/unit/lookout/diff/operations/delete.rb +45 -0
- data/test/unit/lookout/diff/operations/equal.rb +45 -0
- data/test/unit/lookout/diff/operations/insert.rb +45 -0
- data/test/unit/lookout/diff/operations/replace.rb +45 -0
- data/test/unit/lookout/diff/range.rb +50 -0
- data/test/unit/lookout/equality.rb +113 -0
- data/test/unit/lookout/expectation.rb +39 -0
- data/test/unit/lookout/expectations.rb +58 -0
- data/test/unit/lookout/expectations/behavior.rb +35 -0
- data/test/unit/lookout/expectations/state.rb +29 -0
- data/test/unit/lookout/mock.rb +4 -0
- data/test/unit/lookout/mock/method.rb +143 -0
- data/test/unit/lookout/mock/method/arguments.rb +57 -0
- data/test/unit/lookout/mock/method/arguments/any.rb +11 -0
- data/test/unit/lookout/recorder.rb +11 -0
- data/test/unit/lookout/results.rb +30 -0
- data/test/unit/lookout/results/error.rb +7 -0
- data/test/unit/lookout/results/failures/behavior.rb +7 -0
- data/test/unit/lookout/results/failures/state.rb +7 -0
- data/test/unit/lookout/results/fulfilled.rb +7 -0
- data/test/unit/lookout/runners/console.rb +4 -0
- data/test/unit/lookout/stub.rb +4 -0
- data/test/unit/lookout/stub/method.rb +48 -0
- data/test/unit/lookout/ui/formatters/exception.rb +5 -0
- data/test/unit/lookout/ui/formatters/exception/backtrace.rb +11 -0
- data/test/unit/lookout/xml.rb +55 -0
- metadata +496 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Mock::Method::Calls::Lower
|
4
|
+
extend Lookout::Mock::Method::Calls::Class
|
5
|
+
include Lookout::Mock::Method::Calls::Instance
|
6
|
+
|
7
|
+
format 1, 0, 'expected %s to be called at least once'
|
8
|
+
format 2, 0, 'expected %s to be called at least twice'
|
9
|
+
format 2, 1, 'expected %s to be called at least twice, but was only called once'
|
10
|
+
format(-1, -1, 'expected %s to be called at least %d times, but was only called %d times')
|
11
|
+
|
12
|
+
def initialize(method, limit)
|
13
|
+
raise ArgumentError, 'limit must be > 0' unless limit > 0
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def satisfied?
|
20
|
+
@calls >= @limit
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Mock::Method::Calls::Upper
|
4
|
+
extend Lookout::Mock::Method::Calls::Class
|
5
|
+
include Lookout::Mock::Method::Calls::Instance
|
6
|
+
|
7
|
+
format 1, 2, 'expected %s to be called at most once, but was called twice'
|
8
|
+
format 1, -1, 'expected %s to be called at most once, but was called %d times'
|
9
|
+
format 2, -1, 'expected %s to be called at most twice, but was called %d times'
|
10
|
+
format(-1, -1, 'expected %s to be called at most %d times, but was called %d times')
|
11
|
+
|
12
|
+
def initialize(method, limit)
|
13
|
+
raise ArgumentError, 'limit must be > 0' unless limit > 0
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def satisfied?
|
20
|
+
@calls <= @limit
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Mock::Methods < Lookout::Stub::Methods
|
4
|
+
def define(object, method, *args, &block)
|
5
|
+
method = Lookout::Mock::Method.new(object, method, *args, &block)
|
6
|
+
raise RuntimeError,
|
7
|
+
'%s: cannot create mock as a mock has already been created: %s' %
|
8
|
+
[method, @methods.first] unless @methods.empty?
|
9
|
+
@methods << method.define
|
10
|
+
method
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Mock::Object
|
4
|
+
def inspect
|
5
|
+
'mock'
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(method, *args, &block)
|
9
|
+
raise Lookout::Mock::Method::Calls::Error,
|
10
|
+
'unexpected call to %s' % Lookout::Mock::Method.new(self, method)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
class Lookout::Output < StringIO
|
6
|
+
def initialize(expected)
|
7
|
+
@expected = expected
|
8
|
+
super()
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :expected
|
12
|
+
|
13
|
+
def actual
|
14
|
+
rewind
|
15
|
+
@actual ||= read
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
'output(%p)' % expected
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/tasklib'
|
5
|
+
|
6
|
+
module Lookout module Rake end end
|
7
|
+
|
8
|
+
module Lookout::Rake::Tasks
|
9
|
+
autoload :Gem, 'lookout/rake/tasks/gem'
|
10
|
+
autoload :Tags, 'lookout/rake/tasks/tags'
|
11
|
+
autoload :Test, 'lookout/rake/tasks/test'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def top_srcdir
|
15
|
+
@top_srcdir ||= Dir.pwd
|
16
|
+
end
|
17
|
+
|
18
|
+
def gemspec
|
19
|
+
@gemspec ||= Dir['%s/*.gemspec' % top_srcdir].first
|
20
|
+
end
|
21
|
+
|
22
|
+
def specification
|
23
|
+
return @specification if defined? @specification
|
24
|
+
return nil unless defined? ::Gem
|
25
|
+
return nil unless gemspec
|
26
|
+
@specification = ::Gem::Specification.load(gemspec)
|
27
|
+
end
|
28
|
+
|
29
|
+
def specification!
|
30
|
+
specification or
|
31
|
+
raise ArgumentError,
|
32
|
+
'gem specification was not given and could not be found in project root: %s' %
|
33
|
+
top_srcdir
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Rake::Tasks::Gem < Rake::TaskLib
|
4
|
+
def initialize(specification = Lookout::Rake::Tasks.specification!)
|
5
|
+
specification or
|
6
|
+
raise ArgumentError,
|
7
|
+
'gem specification was not given and could not be found in project root: %s' %
|
8
|
+
Lookout::Rake::Tasks.top_srcdir
|
9
|
+
@specification = specification
|
10
|
+
yield self if block_given?
|
11
|
+
define
|
12
|
+
end
|
13
|
+
|
14
|
+
def define
|
15
|
+
desc 'Build %s' % specification.file_name
|
16
|
+
task :build => specification.file_name
|
17
|
+
file specification.file_name => specification.files do
|
18
|
+
when_writing 'Building %s' % specification.file_name do
|
19
|
+
require 'rubygems' unless defined? Gem
|
20
|
+
require 'rubygems/installer' unless defined? Gem::Builder
|
21
|
+
Gem::Builder.new(specification).build
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Check %s' % specification.file_name
|
26
|
+
task :check => :build do
|
27
|
+
require 'rubygems' unless defined? Gem
|
28
|
+
require 'rubygems/installer' unless defined? Gem::Installer
|
29
|
+
checkdir = specification.full_name
|
30
|
+
Gem::Installer.new(specification.file_name, :unpack => true).unpack checkdir
|
31
|
+
sh 'rake --rakefile %s/Rakefile -s test' % checkdir
|
32
|
+
rm_r checkdir
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Install %s and its dependencies' % specification.file_name
|
36
|
+
task :install do
|
37
|
+
require 'rubygems' unless defined? Gem
|
38
|
+
require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller
|
39
|
+
Gem::DependencyInstaller.new.install specification.file_name
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Push %s to rubygems.org' % specification.file_name
|
43
|
+
task :push => :check do
|
44
|
+
sh 'gem -%s-verbose push %s' % [verbose ? '' : '-no', specification.file_name]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_reader :specification
|
49
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Rake::Tasks::Tags < Rake::TaskLib
|
4
|
+
def initialize(specification = Lookout::Rake::Tasks.specification!)
|
5
|
+
@specification = specification
|
6
|
+
yield self if block_given?
|
7
|
+
define
|
8
|
+
end
|
9
|
+
|
10
|
+
def define
|
11
|
+
require 'rbtags/rake/tasks'
|
12
|
+
RbTags::Rake::Tasks::Tags.new specification.require_paths, specification.lib_files.sort
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :specification
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Rake::Tasks::Test < Rake::TaskLib
|
4
|
+
LoaderPath = File.join(File.dirname(__FILE__), 'test/loader.rb')
|
5
|
+
|
6
|
+
def initialize(specification = Lookout::Rake::Tasks.specification, name = :test)
|
7
|
+
self.specification, @name = specification, name
|
8
|
+
yield self if block_given?
|
9
|
+
define
|
10
|
+
end
|
11
|
+
|
12
|
+
def define
|
13
|
+
desc @name == :test ? 'Run tests' : 'Run tests for %s' % @name
|
14
|
+
task @name do
|
15
|
+
ruby '-w %s -- %s %s' % [options, escape(LoaderPath), arguments]
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => @name unless Rake::Task.task_defined? :default
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :requires
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def specification=(specification)
|
26
|
+
@paths, @requires = specification ?
|
27
|
+
[specification.require_paths, [specification.name]] :
|
28
|
+
[['lib'], []]
|
29
|
+
end
|
30
|
+
|
31
|
+
def options
|
32
|
+
@paths.map{ |p| '-I%s' % p }.join(' ')
|
33
|
+
end
|
34
|
+
|
35
|
+
def arguments
|
36
|
+
requires.map{ |r| '-r%s' % r }.push('--').concat(files).join(' ')
|
37
|
+
end
|
38
|
+
|
39
|
+
def files
|
40
|
+
FileList[ENV.fetch('TEST', 'test/unit/**/*.rb')].map{ |f| escape(f) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def escape(path)
|
44
|
+
path.gsub(/([^A-Za-z0-9_\-.,:\/@\n])/n, '\\\\\\1').gsub(/\n/, "'\n'")
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'lookout'
|
4
|
+
|
5
|
+
only_load = false
|
6
|
+
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]]
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Recorder < Lookout::Aphonic
|
4
|
+
autoload :Not, 'lookout/recorder/not'
|
5
|
+
autoload :Tape, 'lookout/recorder/tape'
|
6
|
+
|
7
|
+
def initialize(subject)
|
8
|
+
@subject, @negated = subject, false
|
9
|
+
end
|
10
|
+
|
11
|
+
def not
|
12
|
+
@negated = true
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def receive
|
17
|
+
extend Lookout::Recorders::Reception
|
18
|
+
receive!
|
19
|
+
end
|
20
|
+
|
21
|
+
def be
|
22
|
+
extend Lookout::Recorders::State
|
23
|
+
@verb = :be
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def have
|
28
|
+
extend Lookout::Recorders::State
|
29
|
+
@verb = :have
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def subject!(mocks, stubs)
|
34
|
+
subject
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :subject
|
38
|
+
|
39
|
+
def method_missing(method, *args)
|
40
|
+
return super unless method.to_s =~ /\?$/
|
41
|
+
extend Lookout::Recorders::State
|
42
|
+
@verb = nil
|
43
|
+
method_missing method, *args
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Lookout::Recorder::Tape
|
4
|
+
Method = Struct.new(:name, :args)
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@methods = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def empty?
|
11
|
+
@methods.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
def record(method, args)
|
15
|
+
@methods << Method.new(method, args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def play_for(subject)
|
19
|
+
@methods.inject(subject){ |result, method| result.send(method.name, *method.args) }
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Lookout::Recorders::Reception
|
4
|
+
def subject!(mocks, stubs)
|
5
|
+
@mock = @method._lookout_define(mocks)
|
6
|
+
methods.play_for @mock
|
7
|
+
subject
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify
|
11
|
+
@mock.verify
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def receive!
|
17
|
+
@method = Method.new(self, @negated)
|
18
|
+
end
|
19
|
+
|
20
|
+
def methods
|
21
|
+
@methods ||= Lookout::Recorder::Tape.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(method, *args, &block)
|
25
|
+
super unless defined? @method
|
26
|
+
methods.record method, args
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
class Method < Lookout::Aphonic
|
31
|
+
undef extend
|
32
|
+
undef is_a?
|
33
|
+
|
34
|
+
def initialize(recorder, negated)
|
35
|
+
@recorder, @negated = recorder, negated
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(method, *args, &body)
|
39
|
+
@method, @args, @body = method, args, body
|
40
|
+
@recorder
|
41
|
+
end
|
42
|
+
|
43
|
+
def _lookout_define(mocks)
|
44
|
+
mocks.define(@recorder.subject, @method, *@args, &@body).tap{ |m| m.never if @negated }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module Lookout::Recorders::State
|
4
|
+
Error = Class.new(StandardError)
|
5
|
+
|
6
|
+
def verify
|
7
|
+
!!methods.play_for(subject) ^ @negated or
|
8
|
+
raise Error,
|
9
|
+
case [@negated, @verb]
|
10
|
+
when [true, :be] then 'expected %p not to be %s'
|
11
|
+
when [true, :have] then 'expected %p not to have %s'
|
12
|
+
when [true, nil] then 'expected %p to %s'
|
13
|
+
when [false, :be] then 'expected %p to be %s'
|
14
|
+
when [false, :have] then 'expected %p to have %s'
|
15
|
+
when [false, nil] then 'expected %p to %s'
|
16
|
+
end % [subject, description.join(' ')]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def methods
|
22
|
+
@methods ||= Lookout::Recorder::Tape.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
@description ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(method, *args)
|
30
|
+
description << method.to_s
|
31
|
+
args.each{ |arg| description << arg.inspect }
|
32
|
+
methods.record method, args
|
33
|
+
self
|
34
|
+
end
|
35
|
+
end
|