rspec 0.5.0 → 0.5.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.
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