rspec 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CHANGES +9 -5
  2. data/Rakefile +35 -29
  3. data/bin/spec +0 -5
  4. data/doc/README +5 -0
  5. data/doc/config.yaml +2 -0
  6. data/doc/plugin/syntax.rb +38 -0
  7. data/doc/reference/rspec reference.page +0 -0
  8. data/doc/src/community.page +8 -0
  9. data/doc/src/default.css +198 -0
  10. data/doc/src/default.template +34 -0
  11. data/doc/src/documentation/api.page +251 -0
  12. data/doc/src/documentation/index.page +8 -0
  13. data/doc/src/documentation/mocks.page +207 -0
  14. data/doc/src/documentation/specs.page +20 -0
  15. data/doc/src/download.page +8 -0
  16. data/doc/src/examples.page +9 -0
  17. data/doc/src/images/ul.gif +0 -0
  18. data/doc/src/index.page +8 -0
  19. data/doc/src/tools/index.page +8 -0
  20. data/doc/src/tools/rails.page +8 -0
  21. data/doc/src/tools/rake.page +8 -0
  22. data/doc/src/tools/rcov.page +8 -0
  23. data/doc/src/tools/spec_runner.page +8 -0
  24. data/doc/src/tools/specdoc.page +8 -0
  25. data/doc/src/tools/test2rspec.page +8 -0
  26. data/doc/src/ul.gif +0 -0
  27. data/doc/src/why_rspec.page +8 -0
  28. data/examples/mocking_spec.rb +2 -2
  29. data/examples/spec_framework_spec.rb +4 -4
  30. data/lib/spec/api/helper/have_helper.rb +55 -55
  31. data/lib/spec/api/mock.rb +111 -38
  32. data/lib/spec/runner/backtrace_tweaker.rb +4 -4
  33. data/lib/spec/runner/context.rb +2 -1
  34. data/lib/spec/runner/context_runner.rb +3 -3
  35. data/lib/spec/runner/option_parser.rb +8 -4
  36. data/lib/spec/runner/simple_text_reporter.rb +29 -19
  37. data/lib/spec/runner/specification.rb +2 -1
  38. data/lib/spec/version.rb +1 -1
  39. data/test/rake/rcov_testtask.rb +45 -0
  40. data/test/spec/api/helper/arbitrary_predicate_test.rb +39 -24
  41. data/test/spec/api/helper/equality_test.rb +19 -0
  42. data/test/spec/api/helper/should_have_test.rb +183 -0
  43. data/test/spec/api/mock_arg_constraints_test.rb +90 -0
  44. data/test/spec/api/mock_test.rb +101 -21
  45. data/test/spec/runner/context_runner_test.rb +3 -3
  46. data/test/spec/runner/context_test.rb +2 -5
  47. data/test/spec/runner/execution_context_test.rb +1 -1
  48. data/test/spec/runner/option_parser_test.rb +16 -8
  49. data/test/spec/runner/simple_text_reporter_test.rb +57 -33
  50. data/test/spec/runner/specification_test.rb +7 -7
  51. data/test/spec/tool/command_line_test.rb +4 -4
  52. data/test/test_helper.rb +2 -2
  53. metadata +37 -8
  54. data/README +0 -38
  55. data/TODO +0 -9
  56. data/TUTORIAL +0 -259
  57. data/WHY_RSPEC +0 -115
@@ -5,10 +5,10 @@ module Spec
5
5
  return if error.backtrace.nil?
6
6
  tweaked_backtrace = []
7
7
  error.backtrace.each do |line|
8
- if line.include?('__instance_exec')
9
- line = line.split(':in')[0] + ":in `#{spec_name}'"
10
- end
11
- tweaked_backtrace.push line
8
+ line = line.split(':in')[0] + ":in `#{spec_name}'" if line.include?('__instance_exec')
9
+ line = nil if line.include? '/lib/spec/api/helper/should_base.rb'
10
+ line = nil if line.include? '/lib/spec/api/helper/should_negator.rb' unless line.nil?
11
+ tweaked_backtrace.push line unless line.nil?
12
12
  end
13
13
  error.set_backtrace tweaked_backtrace
14
14
  end
@@ -15,10 +15,11 @@ module Spec
15
15
  instance_exec(&context_block)
16
16
  @@context_runner.add_context(self) unless @@context_runner.nil?
17
17
  ContextRunner.standalone(self) if @@context_runner.nil?
18
+ @calling_line = caller(0)[2].split(":in")[0]
18
19
  end
19
20
 
20
21
  def run(reporter)
21
- reporter.add_context(@name)
22
+ reporter.add_context(@name, @calling_line)
22
23
  @specifications.each do |specification|
23
24
  specification.run(reporter, @setup_block, @teardown_block)
24
25
  end
@@ -5,13 +5,13 @@ module Spec
5
5
  class ContextRunner
6
6
 
7
7
  def self.standalone context
8
- context_runner = ContextRunner.new(ARGV)
8
+ context_runner = ContextRunner.new(ARGV, true)
9
9
  context_runner.add_context context
10
10
  context_runner.run
11
11
  end
12
12
 
13
- def initialize(args)
14
- options = OptionParser.parse(args)
13
+ def initialize(args, standalone=false, err=$stderr)
14
+ options = OptionParser.parse(args, standalone, err)
15
15
  @contexts = []
16
16
  @out = options.out
17
17
  @out = File.open(@out, 'w') if @out.is_a? String
@@ -4,14 +4,14 @@ module Spec
4
4
  module Runner
5
5
  class OptionParser
6
6
 
7
- def self.parse(args)
7
+ def self.parse(args, standalone=false, err=$stderr)
8
8
  options = OpenStruct.new
9
9
  options.out = $stdout
10
10
  options.verbose = false;
11
11
  options.doc = false;
12
12
 
13
13
  opts = ::OptionParser.new do |opts|
14
- opts.banner = "Usage: specdoc [options] FILE|DIRECTORY"
14
+ opts.banner = "Usage: spec [options] (FILE|DIRECTORY)+"
15
15
  opts.separator ""
16
16
 
17
17
  opts.on("-o", "--of [FILE]", "Set the output file (defaults to STDOUT)") do |outfile|
@@ -28,12 +28,16 @@ module Spec
28
28
  end
29
29
 
30
30
  opts.on_tail("-h", "--help", "Show this message") do
31
- puts opts
32
- exit
31
+ err.puts opts
32
+ exit if err == $stderr
33
33
  end
34
34
 
35
35
  end
36
36
  opts.parse!(args)
37
+ if args.empty?
38
+ err.puts opts unless standalone
39
+ exit if err == $stderr unless standalone
40
+ end
37
41
  options
38
42
  end
39
43
  end
@@ -6,23 +6,24 @@ module Spec
6
6
  @context_names = []
7
7
  @errors = []
8
8
  @spec_names = []
9
+ @failures = []
9
10
  @verbose = verbose
10
11
  @backtrace_tweaker = backtrace_tweaker
11
12
  end
12
13
 
13
- def add_context(name)
14
+ def add_context(name, calling_line=nil)
14
15
  @output << "\n" if @context_names.empty? unless @verbose
15
16
  @output << "\n#{name}\n" if @verbose
16
- @context_names << name
17
+ @context_names << [name, calling_line]
17
18
  end
18
19
 
19
- def add_spec(name, errors=[])
20
+ def add_spec(name, calling_line, errors=[])
20
21
  if errors.empty?
21
22
  spec_passed(name)
22
23
  else
23
24
  errors.each { |error| @backtrace_tweaker.tweak_backtrace(error, name) }
24
25
  # only show the first one (there might be more)
25
- spec_failed(name, errors[0])
26
+ spec_failed(name, calling_line, errors[0])
26
27
  end
27
28
  end
28
29
 
@@ -35,11 +36,9 @@ module Spec
35
36
  end
36
37
 
37
38
  def dump
38
- unless @verbose
39
- @output << "\n"
40
- dump_failures
41
- @output << "\n\n" unless @errors.empty?
42
- end
39
+ @output << "\n"
40
+ dump_failures
41
+ @output << "\n\n" unless @errors.empty?
43
42
  @output << "\n" if @errors.empty?
44
43
  @output << "Finished in " << (duration).to_s << " seconds\n\n"
45
44
  @output << "#{@context_names.length} context#{'s' unless @context_names.length == 1 }, "
@@ -51,11 +50,13 @@ module Spec
51
50
  def dump_failures
52
51
  return if @errors.empty?
53
52
  @output << "\n"
54
- @errors.inject(1) do |index, error|
53
+ @failures.inject(1) do |index, failure|
55
54
  @output << "\n\n" if index > 1
56
- @output << index.to_s << ") "
57
- @output << "#{error.message} (#{error.class.name})\n"
58
- dump_backtrace(error.backtrace)
55
+ @output << index.to_s << ")\n"
56
+ @output << "#{failure.error.message} (#{failure.error.class.name})\n"
57
+ @output << "Context: #{failure.context_name} [#{failure.context_line}]\n"
58
+ @output << "Specification: #{failure.spec_name} [#{failure.spec_line}]\n"
59
+ dump_backtrace(failure.error.backtrace)
59
60
  index + 1
60
61
  end
61
62
  end
@@ -77,16 +78,25 @@ module Spec
77
78
  @output << '.' unless @verbose
78
79
  end
79
80
 
80
- def spec_failed(name, error)
81
+ def spec_failed(name, calling_line, error)
81
82
  @spec_names << name
82
83
  @errors << error
83
- if @verbose
84
- @output << "- #{name} (FAILED)\n#{error.message} (#{error.class.name})\n#{error.backtrace.join("\n")}\n"
85
- else
86
- @output << 'F'
87
- end
84
+ @failures << Failure.new(@context_names.last[0], @context_names.last[1], name, calling_line, error)
85
+ @output << "- #{name} (FAILED - #{@failures.length})\n" if @verbose
86
+ @output << 'F' unless @verbose
88
87
  end
89
88
 
90
89
  end
90
+
91
+ class Failure
92
+ attr_reader :context_name, :context_line, :spec_name, :spec_line, :error
93
+ def initialize(context_name, context_line, spec_name, spec_line, error)
94
+ @context_name = context_name
95
+ @context_line = context_line
96
+ @spec_name = spec_name
97
+ @spec_line = spec_line
98
+ @error = error
99
+ end
100
+ end
91
101
  end
92
102
  end
@@ -7,6 +7,7 @@ module Spec
7
7
  @block = block
8
8
  @mocks = []
9
9
  @errors = []
10
+ @calling_line = caller(0)[2].split(":in")[0]
10
11
  end
11
12
 
12
13
  def run(reporter=nil, setup_block=nil, teardown_block=nil)
@@ -27,7 +28,7 @@ module Spec
27
28
  @errors << e
28
29
  end
29
30
 
30
- reporter.add_spec(@name, @errors) unless reporter.nil?
31
+ reporter.add_spec(@name, @calling_line, @errors) unless reporter.nil?
31
32
  end
32
33
 
33
34
  def run_docs(reporter)
@@ -2,7 +2,7 @@ module Spec
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 5
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
 
@@ -0,0 +1,45 @@
1
+ module Rake
2
+ class TestTask < TaskLib
3
+ def define
4
+ lib_path = @libs.join(File::PATH_SEPARATOR)
5
+ desc "Run tests" + (@name==:test ? "" : " for #{@name}")
6
+ task @name do
7
+ run_code = ''
8
+ RakeFileUtils.verbose(@verbose) do
9
+ run_code =
10
+ case @loader
11
+ when :direct
12
+ "-e 'ARGV.each{|f| load f}'"
13
+ when :testrb
14
+ "-S testrb #{fix}"
15
+ when :rake
16
+ rake_loader
17
+ end
18
+ @ruby_opts.unshift( "-I#{lib_path}" )
19
+ @ruby_opts.unshift( "--exclude test.*.rb")
20
+ @ruby_opts.unshift( "-w" ) if @warning
21
+ rcov @ruby_opts.join(" ") +
22
+ " \"#{run_code}\" " +
23
+ file_list.collect { |fn| "\"#{fn}\"" }.join(' ') +
24
+ " #{option_list}"
25
+ end
26
+ end
27
+ self
28
+ end
29
+ end
30
+ end
31
+
32
+ module FileUtils
33
+ def rcov(*args,&block)
34
+ if Hash === args.last
35
+ options = args.pop
36
+ else
37
+ options = {}
38
+ end
39
+ if args.length > 1 then
40
+ sh(*(['rcov'] + args + [options]), &block)
41
+ else
42
+ sh("rcov #{args}", options, &block)
43
+ end
44
+ end
45
+ end
@@ -3,6 +3,31 @@ require File.dirname(__FILE__) + '/../../../test_helper'
3
3
  module Spec
4
4
  module Api
5
5
  module Helper
6
+
7
+ class XxxMock
8
+ def initialize(return_val)
9
+ @return_val = return_val
10
+ @xxx_called = false
11
+ end
12
+
13
+ def xxx?
14
+ @xxx_called = true
15
+ @return_val
16
+ end
17
+
18
+ def yyy?(a, b, c)
19
+ a.should.be 1
20
+ b.should.be 2
21
+ c.should.be 3
22
+ @xxx_called = true
23
+ @return_val
24
+ end
25
+
26
+ def __verify
27
+ @xxx_called.should.be true
28
+ end
29
+ end
30
+
6
31
  class ArbitraryPredicateTest < Test::Unit::TestCase
7
32
 
8
33
  # should.be.xxx
@@ -14,26 +39,23 @@ module Spec
14
39
  end
15
40
 
16
41
  def test_should_be_xxx_should_raise_when_sending_xxx_to_target_returns_false
17
- mock = Mock.new("xxx? returns false")
18
- mock.should_receive(:xxx?).once.with_no_args.and_return(false)
19
- assert_raise(ExpectationNotMetError) do
42
+ mock = XxxMock.new(false)
43
+ assert_raise(ExpectationNotMetError) do
20
44
  mock.should.be.xxx
21
45
  end
22
46
  mock.__verify
23
47
  end
24
48
 
25
49
  def test_should_be_xxx_should_raise_when_sending_xxx_to_target_returns_nil
26
- mock = Mock.new("xxx? returns nil")
27
- mock.should_receive(:xxx?).once.with_no_args.and_return(nil)
28
- assert_raise(ExpectationNotMetError) do
50
+ mock = XxxMock.new(nil)
51
+ assert_raise(ExpectationNotMetError) do
29
52
  mock.should.be.xxx
30
53
  end
31
54
  mock.__verify
32
55
  end
33
56
 
34
57
  def test_should_be_xxx_should_not_raise_when_sending_xxx_to_target_returns_true
35
- mock = Mock.new("xxx? returns true")
36
- mock.should_receive(:xxx?).once.with_no_args.and_return(true)
58
+ mock = XxxMock.new(true)
37
59
  assert_nothing_raised do
38
60
  mock.should.be.xxx
39
61
  end
@@ -41,8 +63,7 @@ module Spec
41
63
  end
42
64
 
43
65
  def test_should_be_xxx_should_not_raise_when_sending_xxx_to_target_returns_something_other_than_true_false_or_nil
44
- mock = Mock.new("xxx? returns 5")
45
- mock.should_receive(:xxx?).once.with_no_args.and_return(5)
66
+ mock = XxxMock.new(5)
46
67
  assert_nothing_raised do
47
68
  mock.should.be.xxx
48
69
  end
@@ -52,10 +73,9 @@ module Spec
52
73
  # should.be.xxx(args)
53
74
 
54
75
  def test_should_be_xxx_with_args_passes_args_properly
55
- mock = Mock.new("xxx?(1 2 3) returns true")
56
- mock.should_receive(:xxx?).once.with(1, 2, 3).and_return(true)
76
+ mock = XxxMock.new(true)
57
77
  assert_nothing_raised do
58
- mock.should.be.xxx(1, 2, 3)
78
+ mock.should.be.yyy(1, 2, 3)
59
79
  end
60
80
  mock.__verify
61
81
  end
@@ -69,8 +89,7 @@ module Spec
69
89
  end
70
90
 
71
91
  def test_should_not_be_xxx_should_raise_when_sending_xxx_to_target_returns_true
72
- mock = Mock.new("xxx? returns true")
73
- mock.should_receive(:xxx?).once.with_no_args.and_return(true)
92
+ mock = XxxMock.new(true)
74
93
  assert_raise(ExpectationNotMetError) do
75
94
  mock.should.not.be.xxx
76
95
  end
@@ -78,8 +97,7 @@ module Spec
78
97
  end
79
98
 
80
99
  def test_should_not_be_xxx_shouldnt_raise_when_sending_xxx_to_target_returns_nil
81
- mock = Mock.new("xxx? returns nil")
82
- mock.should_receive(:xxx?).once.with_no_args.and_return(nil)
100
+ mock = XxxMock.new(nil)
83
101
  assert_nothing_raised do
84
102
  mock.should.not.be.xxx
85
103
  end
@@ -87,8 +105,7 @@ module Spec
87
105
  end
88
106
 
89
107
  def test_should_not_be_xxx_shouldnt_raise_when_sending_xxx_to_target_returns_false
90
- mock = Mock.new("xxx? returns false")
91
- mock.should_receive(:xxx?).once.with_no_args.and_return(false)
108
+ mock = XxxMock.new(false)
92
109
  assert_nothing_raised do
93
110
  mock.should.not.be.xxx
94
111
  end
@@ -96,8 +113,7 @@ module Spec
96
113
  end
97
114
 
98
115
  def test_should_not_be_xxx_should_raise_when_sending_xxx_to_target_returns_something_other_than_true_false_or_nil
99
- mock = Mock.new("xxx? returns 5")
100
- mock.should_receive(:xxx?).once.with_no_args.and_return(5)
116
+ mock = XxxMock.new(5)
101
117
  assert_raise(ExpectationNotMetError) do
102
118
  mock.should.not.be.xxx
103
119
  end
@@ -107,10 +123,9 @@ module Spec
107
123
  # should.be.xxx(args)
108
124
 
109
125
  def test_should_not_be_xxx_with_args_passes_args_properly
110
- mock = Mock.new("xxx?(1 2 3) returns false")
111
- mock.should_receive(:xxx?).once.with(1, 2, 3).and_return(false)
126
+ mock = XxxMock.new(false)
112
127
  assert_nothing_raised do
113
- mock.should.not.be.xxx(1, 2, 3)
128
+ mock.should.not.be.yyy(1, 2, 3)
114
129
  end
115
130
  mock.__verify
116
131
  end
@@ -40,6 +40,25 @@ module Spec
40
40
  end
41
41
  end
42
42
 
43
+ def test_should_be_close_good_cases
44
+ assert_nothing_raised do
45
+ 3.5.should.be.close 3.5, 0.5
46
+ 3.5.should.be.close 3.1, 0.5
47
+ 3.5.should.be.close 3.01, 0.5
48
+ 3.5.should.be.close 3.9, 0.5
49
+ 3.5.should.be.close 3.99, 0.5
50
+ end
51
+ end
52
+
53
+ def test_should_be_close_failing_cases
54
+ assert_raise(ExpectationNotMetError) do
55
+ 3.5.should.be.close 3.0, 0.5
56
+ 3.5.should.be.close 2.0, 0.5
57
+ 3.5.should.be.close 4.0, 0.5
58
+ 3.5.should.be.close 5.0, 0.5
59
+ end
60
+ end
61
+
43
62
  end
44
63
  end
45
64
  end
@@ -0,0 +1,183 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Spec
4
+ module Api
5
+ module Helper
6
+ class ShouldHaveTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @owner = CollectionOwner.new
10
+ (1..3).each do |n|
11
+ @owner.add_to_collection_with_length_method n
12
+ @owner.add_to_collection_with_size_method n
13
+ end
14
+ end
15
+
16
+ def test_should_raise_when_expecting_less_than_actual_length
17
+ assert_raise(ExpectationNotMetError) do
18
+ @owner.should.have(2).items_in_collection_with_length_method
19
+ end
20
+ end
21
+
22
+ def test_should_raise_when_expecting_more_than_actual_length
23
+ assert_raise(ExpectationNotMetError) do
24
+ @owner.should.have(4).items_in_collection_with_length_method
25
+ end
26
+ end
27
+
28
+ def test_should_not_raise_when_expecting_actual_length
29
+ assert_nothing_raised do
30
+ @owner.should.have(3).items_in_collection_with_length_method
31
+ end
32
+ end
33
+
34
+
35
+ def test_should_raise_when_expecting_less_than_actual_size
36
+ assert_raise(ExpectationNotMetError) do
37
+ @owner.should.have(2).items_in_collection_with_size_method
38
+ end
39
+ end
40
+
41
+ def test_should_raise_when_expecting_more_than_actual_size
42
+ assert_raise(ExpectationNotMetError) do
43
+ @owner.should.have(4).items_in_collection_with_size_method
44
+ end
45
+ end
46
+
47
+ def test_should_not_raise_when_expecting_actual_size
48
+ assert_nothing_raised do
49
+ @owner.should.have(3).items_in_collection_with_size_method
50
+ end
51
+ end
52
+ end
53
+
54
+ class ShouldHaveAtLeastTest < Test::Unit::TestCase
55
+
56
+ def setup
57
+ @owner = CollectionOwner.new
58
+ (1..3).each do |n|
59
+ @owner.add_to_collection_with_length_method n
60
+ @owner.add_to_collection_with_size_method n
61
+ end
62
+ end
63
+
64
+ def test_should_not_raise_when_expecting_less_than_actual_length
65
+ assert_nothing_raised do
66
+ @owner.should.have.at.least(2).items_in_collection_with_length_method
67
+ end
68
+ end
69
+
70
+ def test_should_raise_when_expecting_more_than_actual_length
71
+ assert_raise(ExpectationNotMetError) do
72
+ @owner.should.have.at.least(4).items_in_collection_with_length_method
73
+ end
74
+ end
75
+
76
+ def test_should_not_raise_when_expecting_actual_length
77
+ assert_nothing_raised do
78
+ @owner.should.have.at.least(3).items_in_collection_with_length_method
79
+ end
80
+ end
81
+
82
+
83
+ def test_should_not_raise_when_expecting_less_than_actual_size
84
+ assert_nothing_raised do
85
+ @owner.should.have.at.least(2).items_in_collection_with_size_method
86
+ end
87
+ end
88
+
89
+ def test_should_raise_when_expecting_more_than_actual_size
90
+ assert_raise(ExpectationNotMetError) do
91
+ @owner.should.have.at.least(4).items_in_collection_with_size_method
92
+ end
93
+ end
94
+
95
+ def test_should_not_raise_when_expecting_actual_size
96
+ assert_nothing_raised do
97
+ @owner.should.have.at.least(3).items_in_collection_with_size_method
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ class ShouldHaveAtMostTest < Test::Unit::TestCase
104
+
105
+ def setup
106
+ @owner = CollectionOwner.new
107
+ (1..3).each do |n|
108
+ @owner.add_to_collection_with_length_method n
109
+ @owner.add_to_collection_with_size_method n
110
+ end
111
+ end
112
+
113
+ def test_should_raise_when_expecting_less_than_actual_length
114
+ assert_raise(ExpectationNotMetError) do
115
+ @owner.should.have.at.most(2).items_in_collection_with_length_method
116
+ end
117
+ end
118
+
119
+ def test_should_not_raise_when_expecting_more_than_actual_length
120
+ assert_nothing_raised do
121
+ @owner.should.have.at.most(4).items_in_collection_with_length_method
122
+ end
123
+ end
124
+
125
+ def test_should_not_raise_when_expecting_actual_length
126
+ assert_nothing_raised do
127
+ @owner.should.have.at.most(3).items_in_collection_with_length_method
128
+ end
129
+ end
130
+
131
+
132
+ def test_should_raise_when_expecting_less_than_actual_size
133
+ assert_raise(ExpectationNotMetError) do
134
+ @owner.should.have.at.most(2).items_in_collection_with_size_method
135
+ end
136
+ end
137
+
138
+ def test_should_not_raise_when_expecting_more_than_actual_size
139
+ assert_nothing_raised do
140
+ @owner.should.have.at.most(4).items_in_collection_with_size_method
141
+ end
142
+ end
143
+
144
+ def test_should_not_raise_when_expecting_actual_size
145
+ assert_nothing_raised do
146
+ @owner.should.have.at.most(3).items_in_collection_with_size_method
147
+ end
148
+ end
149
+
150
+ end
151
+
152
+ class CollectionWithSizeMethod
153
+ def initialize; @list = []; end
154
+ def size; @list.size; end
155
+ def push(item); @list.push(item); end
156
+ end
157
+
158
+ class CollectionWithLengthMethod
159
+ def initialize; @list = []; end
160
+ def length; @list.size; end
161
+ def push(item); @list.push(item); end
162
+ end
163
+
164
+ class CollectionOwner
165
+ attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method
166
+
167
+ def initialize
168
+ @items_in_collection_with_size_method = CollectionWithSizeMethod.new
169
+ @items_in_collection_with_length_method = CollectionWithLengthMethod.new
170
+ end
171
+
172
+ def add_to_collection_with_size_method(item)
173
+ @items_in_collection_with_size_method.push(item)
174
+ end
175
+
176
+ def add_to_collection_with_length_method(item)
177
+ @items_in_collection_with_length_method.push(item)
178
+ end
179
+ end
180
+
181
+ end
182
+ end
183
+ end