rspec 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -12
- data/Rakefile +17 -12
- data/TUTORIAL +1 -1
- data/WHY_RSPEC +115 -0
- data/bin/spec +17 -4
- data/bin/test2rspec +35 -0
- data/examples/airport_spec.rb +35 -0
- data/examples/mocking_spec.rb +16 -0
- data/examples/spec_framework_spec.rb +28 -0
- data/examples/stack.rb +36 -0
- data/examples/stack_spec.rb +112 -0
- data/lib/spec.rb +5 -18
- data/lib/spec/api.rb +4 -0
- data/lib/spec/{exceptions.rb → api/exceptions.rb} +1 -1
- data/lib/spec/{expectations.rb → api/expectations.rb} +5 -4
- data/lib/spec/api/helper.rb +10 -0
- data/lib/spec/{have_helper.rb → api/helper/have_helper.rb} +1 -1
- data/lib/spec/{instance_helper.rb → api/helper/instance_helper.rb} +0 -0
- data/lib/spec/{instance_negator.rb → api/helper/instance_negator.rb} +0 -0
- data/lib/spec/{kind_helper.rb → api/helper/kind_helper.rb} +0 -0
- data/lib/spec/{kind_negator.rb → api/helper/kind_negator.rb} +0 -0
- data/lib/spec/{respond_helper.rb → api/helper/respond_helper.rb} +0 -0
- data/lib/spec/{respond_negator.rb → api/helper/respond_negator.rb} +0 -0
- data/lib/spec/{should_base.rb → api/helper/should_base.rb} +6 -4
- data/lib/spec/{should_helper.rb → api/helper/should_helper.rb} +12 -0
- data/lib/spec/{should_negator.rb → api/helper/should_negator.rb} +11 -0
- data/lib/spec/api/mock.rb +184 -0
- data/lib/spec/rake/spectask.rb +153 -0
- data/lib/spec/runner.rb +9 -0
- data/lib/spec/runner/backtrace_tweaker.rb +17 -0
- data/lib/spec/runner/context.rb +47 -0
- data/lib/spec/runner/context_runner.rb +52 -0
- data/lib/spec/runner/execution_context.rb +15 -0
- data/lib/spec/runner/instance_exec.rb +15 -0
- data/lib/spec/runner/kernel_ext.rb +6 -0
- data/lib/spec/runner/option_parser.rb +41 -0
- data/lib/spec/runner/rdoc_formatter.rb +17 -0
- data/lib/spec/runner/simple_text_reporter.rb +92 -0
- data/lib/spec/runner/specification.rb +42 -0
- data/lib/spec/tool/command_line.rb +39 -0
- data/lib/spec/tool/test_unit_translator.rb +112 -0
- data/lib/spec/version.rb +13 -0
- data/test/spec/api/helper/arbitrary_predicate_test.rb +121 -0
- data/test/spec/api/helper/containment_test.rb +117 -0
- data/test/spec/api/helper/equality_test.rb +46 -0
- data/test/spec/api/helper/identity_test.rb +68 -0
- data/test/spec/api/helper/raising_test.rb +50 -0
- data/test/spec/api/helper/regex_matching_test.rb +38 -0
- data/test/spec/api/helper/should_satisfy_test.rb +37 -0
- data/test/spec/api/helper/throwing_test.rb +56 -0
- data/test/spec/api/helper/true_false_special_case_test.rb +87 -0
- data/test/spec/api/helper/typing_test.rb +107 -0
- data/test/spec/api/mock_test.rb +161 -0
- data/test/spec/runner/backtrace_tweaker_test.rb +20 -0
- data/test/spec/runner/context_runner_test.rb +19 -0
- data/test/spec/runner/context_test.rb +29 -0
- data/test/spec/runner/execution_context_test.rb +13 -0
- data/test/spec/runner/option_parser_test.rb +50 -0
- data/test/spec/runner/rdoc_formatter_test.rb +23 -0
- data/test/spec/runner/simple_text_reporter_test.rb +128 -0
- data/test/spec/runner/specification_test.rb +70 -0
- data/test/spec/tool/command_line_test.rb +22 -0
- data/test/spec/tool/test_unit_api_spec.rb +61 -0
- data/test/spec/tool/test_unit_api_test.rb +61 -0
- data/test/spec/tool/test_unit_translator_test.rb +29 -0
- data/test/test_helper.rb +8 -0
- metadata +89 -67
- data/examples/add_specification_spec.rb +0 -15
- data/examples/craps.rb +0 -15
- data/examples/craps_spec.rb +0 -105
- data/examples/dsl_spec.rb +0 -8
- data/examples/movie.rb +0 -7
- data/examples/movie_list.rb +0 -19
- data/examples/movie_spec.rb +0 -37
- data/lib/spec/collector.rb +0 -17
- data/lib/spec/context.rb +0 -89
- data/lib/spec/dsl.rb +0 -23
- data/lib/spec/gui_runner.rb +0 -59
- data/lib/spec/mock.rb +0 -183
- data/lib/spec/text_runner.rb +0 -75
- data/test/collection_owner.rb +0 -48
- data/test/context_fixtures_test.rb +0 -71
- data/test/context_run_test.rb +0 -174
- data/test/dsl_test.rb +0 -48
- data/test/error_reporting_test.rb +0 -225
- data/test/expectations_for_should_have_test.rb +0 -144
- data/test/expectations_test.rb +0 -592
- data/test/get_classes.rb +0 -6
- data/test/gui_runner_test.rb +0 -162
- data/test/mock_test.rb +0 -157
- data/test/spec_collection_test.rb +0 -39
- data/test/specification_addition_test.rb +0 -29
- data/test/specification_identification_test.rb +0 -71
- data/test/text_runner_test.rb +0 -146
data/test/get_classes.rb
DELETED
data/test/gui_runner_test.rb
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'socket'
|
3
|
-
require 'spec'
|
4
|
-
|
5
|
-
class PassingCon < Spec::Context
|
6
|
-
|
7
|
-
def ex1
|
8
|
-
true.should.be true
|
9
|
-
end
|
10
|
-
|
11
|
-
def ex2
|
12
|
-
true.should.be true
|
13
|
-
end
|
14
|
-
|
15
|
-
def ex3
|
16
|
-
true.should.be true
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
class FailingCon < Spec::Context
|
23
|
-
|
24
|
-
def fail1
|
25
|
-
false.should.be true
|
26
|
-
end
|
27
|
-
|
28
|
-
def fail2
|
29
|
-
false.should.be true
|
30
|
-
end
|
31
|
-
|
32
|
-
def fail3
|
33
|
-
false.should.be true
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
class ErringCon < Spec::Context
|
40
|
-
|
41
|
-
def error1
|
42
|
-
raise "boom"
|
43
|
-
end
|
44
|
-
|
45
|
-
def error2
|
46
|
-
raise "boom"
|
47
|
-
end
|
48
|
-
|
49
|
-
def error3
|
50
|
-
raise "boom"
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
class SocketListener
|
56
|
-
|
57
|
-
def initialize(port)
|
58
|
-
@server_socket = TCPServer.new("127.0.0.1", port)
|
59
|
-
@expectations = Array.new
|
60
|
-
@next_expectation_index = 0
|
61
|
-
@expectations_met = false
|
62
|
-
end
|
63
|
-
|
64
|
-
def shutdown
|
65
|
-
@th.kill
|
66
|
-
@server_socket.shutdown
|
67
|
-
end
|
68
|
-
|
69
|
-
def expects(expected_regex)
|
70
|
-
@expectations << expected_regex
|
71
|
-
end
|
72
|
-
|
73
|
-
def verify
|
74
|
-
sleep 1
|
75
|
-
return if @expectations_met
|
76
|
-
msg = "Nothing matching /#{@expectations[@next_expectation_index].source}/ was seen"
|
77
|
-
raise Test::Unit::AssertionFailedError.new(msg)
|
78
|
-
end
|
79
|
-
|
80
|
-
def run
|
81
|
-
@socket = @server_socket.accept
|
82
|
-
@th = Thread.new("socket listener") do
|
83
|
-
until @expectations_met
|
84
|
-
msg, sender = @socket.readline
|
85
|
-
msg.chomp!
|
86
|
-
next unless @expectations[@next_expectation_index] =~ msg
|
87
|
-
@next_expectation_index += 1
|
88
|
-
remaining = @expectations.size - @next_expectation_index
|
89
|
-
@expectations_met = (remaining == 0)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
class TestGuiRunner < Test::Unit::TestCase
|
96
|
-
|
97
|
-
def setup
|
98
|
-
port = 13001
|
99
|
-
@listener = SocketListener.new(port)
|
100
|
-
@listener.expects /connected/
|
101
|
-
@runner = Spec::GuiRunner.new(port)
|
102
|
-
end
|
103
|
-
|
104
|
-
def teardown
|
105
|
-
@listener.shutdown
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_size_on_start
|
109
|
-
@listener.expects /start 3/
|
110
|
-
@listener.run
|
111
|
-
@runner.run(PassingCon)
|
112
|
-
@listener.verify
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_passing_example_outputs_period
|
116
|
-
@listener.expects /start/
|
117
|
-
@listener.expects /passed/
|
118
|
-
@listener.expects /passed/
|
119
|
-
@listener.expects /passed/
|
120
|
-
@listener.expects /end/
|
121
|
-
@listener.run
|
122
|
-
@runner.run(PassingCon)
|
123
|
-
@listener.verify
|
124
|
-
end
|
125
|
-
|
126
|
-
def test_failing_example_outputs_X
|
127
|
-
@listener.expects /start/
|
128
|
-
@listener.expects /failed/
|
129
|
-
@listener.expects /failed/
|
130
|
-
@listener.expects /failed/
|
131
|
-
@listener.expects /end/
|
132
|
-
@listener.run
|
133
|
-
@runner.run(FailingCon)
|
134
|
-
@listener.verify
|
135
|
-
end
|
136
|
-
|
137
|
-
def test_erring_example_outputs_X
|
138
|
-
@listener.expects /start/
|
139
|
-
@listener.expects /failed/
|
140
|
-
@listener.expects /failed/
|
141
|
-
@listener.expects /failed/
|
142
|
-
@listener.expects /end/
|
143
|
-
@listener.run
|
144
|
-
@runner.run(ErringCon)
|
145
|
-
@listener.verify
|
146
|
-
end
|
147
|
-
|
148
|
-
def test_failure_backtrace
|
149
|
-
@listener.expects /.*in `fail1'.*/
|
150
|
-
@listener.run
|
151
|
-
@runner.run(FailingCon)
|
152
|
-
@listener.verify
|
153
|
-
end
|
154
|
-
|
155
|
-
def test_error_backtrace
|
156
|
-
@listener.expects /.*in `error3'.*/
|
157
|
-
@listener.run
|
158
|
-
@runner.run(ErringCon)
|
159
|
-
@listener.verify
|
160
|
-
end
|
161
|
-
|
162
|
-
end
|
data/test/mock_test.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'spec'
|
3
|
-
|
4
|
-
class MockTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
def setup
|
7
|
-
@mock = Mock.new("test mock")
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_should_report_line_number_of_expectaion_of_unreceived_message
|
11
|
-
@mock.should_receive(:wont_happen).with("x", 3)
|
12
|
-
|
13
|
-
begin
|
14
|
-
@mock.__verify
|
15
|
-
rescue Spec::Exceptions::MockExpectationError => e
|
16
|
-
e.message.should.equal "./test/mock_test.rb:11:in `test_should_report_line_number_of_expectaion_of_unreceived_message': Mock 'test mock' expected wont_happen(<x:String>, <3:Fixnum>) once, but received it 0 times"
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_should_allow_block_to_calculate_return_values
|
22
|
-
@mock.should_receive(:random_call).with("a","b","c").and_return { |a,b,c| c+b+a }
|
23
|
-
assert_equal "cba", @mock.random_call("a","b","c")
|
24
|
-
# TODO: remove __verify when migrating to self-hosting. Verify happens transparently in teardown. (AH)
|
25
|
-
@mock.__verify
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_should_allow_parameter_as_return_value
|
29
|
-
@mock.should_receive(:random_call).with("a","b","c").and_return("booh")
|
30
|
-
assert_equal "booh", @mock.random_call("a","b","c")
|
31
|
-
@mock.__verify
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_return_nil_if_no_return_value_set
|
35
|
-
@mock.should_receive(:random_call).with("a","b","c")
|
36
|
-
assert_nil @mock.random_call("a","b","c")
|
37
|
-
@mock.__verify
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_should_test_multiple_calls_to_method_with_same_parameters
|
41
|
-
@mock.should_receive(:random_call).twice.with("a","b","c")
|
42
|
-
@mock.random_call("a","b","c")
|
43
|
-
@mock.random_call("a","b","c")
|
44
|
-
@mock.__verify
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_should_raise_exception_if_parameters_dont_match_when_method_called
|
48
|
-
@mock.should_receive(:random_call).with("a","b","c").and_return("booh")
|
49
|
-
assert_raise(Spec::Exceptions::MockExpectationError) {
|
50
|
-
@mock.random_call("a","d","c")
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_should_fail_if_unexpected_method_called
|
55
|
-
assert_raise(Spec::Exceptions::MockExpectationError) {
|
56
|
-
@mock.random_call("a","d","c")
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_should_allow_unexpected_methods_if_ignore_missing_set
|
61
|
-
m = Mock.new("null_object", :null_object=>true)
|
62
|
-
m.random_call("a","d","c")
|
63
|
-
m.__verify
|
64
|
-
end
|
65
|
-
|
66
|
-
# TODO: rename to should_raise_exception_telling_what_message_was_not_received
|
67
|
-
def test_should_raise_exception_on_verify_if_call_counts_not_as_expected
|
68
|
-
@mock.should_receive(:random_call).twice.with("a","b","c").and_return("booh")
|
69
|
-
@mock.random_call("a","b","c")
|
70
|
-
assert_raise(Spec::Exceptions::MockExpectationError) do
|
71
|
-
@mock.__verify
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_should_use_block_for_expectation_if_provided
|
76
|
-
@mock.should_receive(:random_call) do | a, b |
|
77
|
-
a.should.equal("a")
|
78
|
-
b.should.equal("b")
|
79
|
-
"booh"
|
80
|
-
end
|
81
|
-
assert_equal("booh", @mock.random_call("a", "b"))
|
82
|
-
@mock.__verify
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_failing_expectation_block_throws
|
86
|
-
@mock.should_receive(:random_call) {| a | a.should.be true}
|
87
|
-
assert_raise(Spec::Exceptions::MockExpectationError) do
|
88
|
-
@mock.random_call false
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_two_return_values
|
93
|
-
@mock.should_receive(:multi_call).twice.with_no_args.and_return_consecutively([1, 2])
|
94
|
-
assert_equal(1, @mock.multi_call)
|
95
|
-
assert_equal(2, @mock.multi_call)
|
96
|
-
@mock.__verify
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_repeating_final_return_value
|
100
|
-
@mock.should_receive(:multi_call).at_least_once.with_no_args.and_return_consecutively([1, 2])
|
101
|
-
assert_equal(1, @mock.multi_call)
|
102
|
-
assert_equal(2, @mock.multi_call)
|
103
|
-
assert_equal(2, @mock.multi_call)
|
104
|
-
@mock.__verify
|
105
|
-
end
|
106
|
-
|
107
|
-
def test_should_throw_on_call_of_never_method
|
108
|
-
@mock.should_receive(:random_call).never
|
109
|
-
assert_raise(Spec::Exceptions::MockExpectationError) do
|
110
|
-
@mock.random_call
|
111
|
-
@mock.__verify
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_should_throw_if_at_least_once_method_not_called
|
116
|
-
@mock.should_receive(:random_call).at_least_once
|
117
|
-
assert_raise(Spec::Exceptions::MockExpectationError) do
|
118
|
-
@mock.__verify
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def test_should_not_throw_if_any_number_of_times_method_not_called
|
123
|
-
@mock.should_receive(:random_call).any_number_of_times
|
124
|
-
@mock.__verify
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_should_not_throw_if_any_number_of_times_method_is_called
|
128
|
-
@mock.should_receive(:random_call).any_number_of_times
|
129
|
-
@mock.random_call
|
130
|
-
@mock.__verify
|
131
|
-
end
|
132
|
-
|
133
|
-
def test_should_not_throw_if_at_least_once_method_is_called_twice
|
134
|
-
@mock.should_receive(:random_call).at_least_once
|
135
|
-
@mock.random_call
|
136
|
-
@mock.random_call
|
137
|
-
@mock.__verify
|
138
|
-
end
|
139
|
-
|
140
|
-
def test_should_support_mutiple_calls_with_different_args
|
141
|
-
@mock.should_receive(:random_call).once.with(1)
|
142
|
-
@mock.should_receive(:random_call).once.with(2)
|
143
|
-
@mock.random_call(1)
|
144
|
-
@mock.random_call(2)
|
145
|
-
@mock.__verify
|
146
|
-
end
|
147
|
-
|
148
|
-
def test_should_support_multiple_calls_with_different_args_and_counts
|
149
|
-
@mock.should_receive(:random_call).twice.with(1)
|
150
|
-
@mock.should_receive(:random_call).once.with(2)
|
151
|
-
@mock.random_call(1)
|
152
|
-
@mock.random_call(2)
|
153
|
-
@mock.random_call(1)
|
154
|
-
@mock.__verify
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
require 'spec'
|
4
|
-
|
5
|
-
|
6
|
-
class Foobar < Spec::Context
|
7
|
-
|
8
|
-
def first_method
|
9
|
-
end
|
10
|
-
|
11
|
-
def second_method
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
class SpecCollectionTest < Test::Unit::TestCase
|
18
|
-
|
19
|
-
def setup
|
20
|
-
@collection = Foobar.collection
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_should_have_two_fixtures_in_collection
|
24
|
-
assert_equal 2, @collection.length
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_should_include_first_method_fixture
|
28
|
-
assert_equal true, @collection.any? do |spec|
|
29
|
-
spec.instance_variable_get(:@specification) == :first_method
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_should_include_second_method_fixture
|
34
|
-
assert_equal true, @collection.any? do |spec|
|
35
|
-
spec.instance_variable_get(:@specification) == :second_method
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
require 'spec'
|
4
|
-
|
5
|
-
|
6
|
-
class AddToMe < Spec::Context
|
7
|
-
|
8
|
-
def orig_spec
|
9
|
-
true.should_equal true
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
class SpecificationAdditionTest < Test::Unit::TestCase
|
16
|
-
|
17
|
-
def test_should_add_foo_specification_to_context
|
18
|
-
AddToMe.add_specification(:added_spec) { false.should_equal false }
|
19
|
-
|
20
|
-
assert_equal true, AddToMe.specifications.include?('added_spec')
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_should_add_another_specification_to_context
|
24
|
-
AddToMe.add_specification(:another_added_spec) { true.should_equal false }
|
25
|
-
|
26
|
-
assert_equal true, AddToMe.specifications.include?('another_added_spec')
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
|
3
|
-
require 'spec'
|
4
|
-
|
5
|
-
|
6
|
-
class SpecificationIdentificationContext < Spec::Context
|
7
|
-
|
8
|
-
def setup
|
9
|
-
end
|
10
|
-
|
11
|
-
def teardown
|
12
|
-
end
|
13
|
-
|
14
|
-
def foo
|
15
|
-
end
|
16
|
-
|
17
|
-
def bar
|
18
|
-
end
|
19
|
-
|
20
|
-
def baz(arg1, arg2)
|
21
|
-
end
|
22
|
-
|
23
|
-
def _method_with_underscore
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
class ContextTest < Test::Unit::TestCase
|
30
|
-
|
31
|
-
def setup
|
32
|
-
@spec_id_context = SpecificationIdentificationContext.new
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_should_inherit_from_context
|
36
|
-
assert_equal Spec::Context, @spec_id_context.class.superclass
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_should_contain_two_specifications
|
40
|
-
assert_equal 2, SpecificationIdentificationContext.specifications.length
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_should_have_foo_specification
|
44
|
-
assert_equal true, SpecificationIdentificationContext.specifications.include?('foo')
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_should_have_bar_specification
|
48
|
-
assert_equal true, SpecificationIdentificationContext.specifications.include?('bar')
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_should_not_include_specifications_method_in_specifications
|
52
|
-
assert_equal false, SpecificationIdentificationContext.specifications.include?('specifications')
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_should_not_include_setup_in_specifications
|
56
|
-
assert_equal false, SpecificationIdentificationContext.specifications.include?(:setup)
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_should_not_include_teardown_in_specifications
|
60
|
-
assert_equal false, SpecificationIdentificationContext.specifications.include?(:teardown)
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_should_not_include_methods_with_args_in_specifications
|
64
|
-
assert_equal false, SpecificationIdentificationContext.specifications.include?('baz')
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_should_not_include_methods_prefixed_with_underscore_in_specifications
|
68
|
-
assert_equal false, SpecificationIdentificationContext.specifications.include?('_method_with_underscore')
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|