washout_builder 0.14.1 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -2
- data/.rubocop.yml +68 -0
- data/.travis.yml +1 -1
- data/Appraisals +9 -1
- data/Gemfile +2 -3
- data/Rakefile +17 -20
- data/app/controllers/washout_builder/washout_builder_controller.rb +79 -79
- data/app/helpers/washout_builder_complex_type_helper.rb +16 -23
- data/app/helpers/washout_builder_fault_type_helper.rb +12 -13
- data/app/helpers/washout_builder_method_arguments_helper.rb +24 -26
- data/app/helpers/washout_builder_method_list_helper.rb +16 -11
- data/app/helpers/washout_builder_method_return_type_helper.rb +14 -12
- data/app/views/wash_with_html/doc.builder +2 -2
- data/bin/appraisal +16 -0
- data/bin/autospec +16 -0
- data/bin/bundler +16 -0
- data/bin/cdiff +16 -0
- data/bin/coderay +16 -0
- data/bin/colortab +16 -0
- data/bin/coveralls +16 -0
- data/bin/decolor +16 -0
- data/bin/erubis +16 -0
- data/bin/guard +16 -0
- data/bin/htmldiff +16 -0
- data/bin/ldiff +16 -0
- data/bin/listen +16 -0
- data/bin/nokogiri +16 -0
- data/bin/phare +16 -0
- data/bin/pry +16 -0
- data/bin/rackup +16 -0
- data/bin/rails +16 -0
- data/bin/rake +16 -0
- data/bin/restclient +16 -0
- data/bin/rspec +16 -0
- data/bin/rubocop +16 -0
- data/bin/ruby-parse +16 -0
- data/bin/ruby-rewrite +16 -0
- data/bin/sass +16 -0
- data/bin/sass-convert +16 -0
- data/bin/scss +16 -0
- data/bin/scss-lint +16 -0
- data/bin/term_display +16 -0
- data/bin/term_mandel +16 -0
- data/bin/thor +16 -0
- data/bin/uuid +16 -0
- data/config/routes.rb +3 -3
- data/init.rb +1 -1
- data/lib/washout_builder.rb +20 -29
- data/lib/washout_builder/document/complex_type.rb +70 -75
- data/lib/washout_builder/document/exception_model.rb +46 -51
- data/lib/washout_builder/document/generator.rb +56 -66
- data/lib/washout_builder/document/shared_complex_type.rb +2 -4
- data/lib/washout_builder/engine.rb +1 -2
- data/lib/washout_builder/soap.rb +6 -10
- data/lib/washout_builder/type.rb +9 -23
- data/lib/washout_builder/version.rb +5 -5
- data/spec/app/controllers/washout_builder_controller_spec.rb +26 -28
- data/spec/app/helpers/washout_builder_complex_type_helper_spec.rb +37 -45
- data/spec/app/helpers/washout_builder_fault_type_helper_spec.rb +65 -77
- data/spec/app/helpers/washout_builder_method_arguments_helper_spec.rb +65 -76
- data/spec/app/helpers/washout_builder_method_list_helper_spec.rb +30 -35
- data/spec/app/helpers/washout_builder_method_return_type_helper_spec.rb +25 -27
- data/spec/dummy/config/application.rb +4 -4
- data/spec/dummy/config/boot.rb +1 -1
- data/spec/dummy/config/environments/development.rb +2 -3
- data/spec/dummy/config/environments/test.rb +3 -3
- data/spec/dummy/config/initializers/secret_token.rb +1 -1
- data/spec/dummy/config/initializers/session_store.rb +1 -1
- data/spec/dummy/config/routes.rb +0 -1
- data/spec/dummy/script/rails +2 -2
- data/spec/integration/washout_builder_all_services_spec.rb +2 -5
- data/spec/integration/washout_builder_service_spec.rb +2 -5
- data/spec/lib/washout_builder/document/complex_type_spec.rb +98 -118
- data/spec/lib/washout_builder/document/exception_model_spec.rb +49 -54
- data/spec/lib/washout_builder/document/generator_spec.rb +93 -118
- data/spec/lib/washout_builder/type_spec.rb +17 -29
- data/spec/lib/washout_builder_spec.rb +293 -308
- data/spec/spec_helper.rb +24 -30
- data/spec/support/complex_types/fluffy.rb +3 -3
- data/spec/support/complex_types/fluffy_container.rb +3 -3
- data/spec/support/complex_types/project_type.rb +4 -5
- data/spec/support/complex_types/test_type.rb +4 -4
- data/washout_builder.gemspec +5 -2
- metadata +78 -3
@@ -1,88 +1,83 @@
|
|
1
|
-
#encoding:utf-8
|
1
|
+
# encoding:utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
class InheritedExceptionModel
|
4
|
+
class InheritedExceptionModel
|
5
5
|
include WashoutBuilder::Document::ExceptionModel
|
6
|
-
|
7
6
|
end
|
8
7
|
|
9
|
-
|
10
8
|
describe WashoutBuilder::Document::ExceptionModel do
|
9
|
+
let(:subject) { WashoutBuilderTestError }
|
10
|
+
|
11
|
+
let(:structure) { { 'message' => { primitive: 'string', member_type: nil }, 'backtrace' => { primitive: 'string', member_type: nil } } }
|
12
|
+
let(:base_structure) { { 'code' => { primitive: 'integer', member_type: nil }, 'message' => { primitive: 'string', member_type: nil }, 'backtrace' => { primitive: 'string', member_type: nil } } }
|
13
|
+
let(:ancestors) { [base_exception] }
|
11
14
|
|
12
|
-
let(:subject) { WashoutBuilderTestError}
|
13
|
-
|
14
|
-
let(:structure) { {"message"=>{:primitive=>"string", :member_type=>nil}, "backtrace"=>{:primitive=>"string", :member_type=>nil}}}
|
15
|
-
let(:base_structure) { {"code"=>{:primitive=>"integer", :member_type=>nil}, "message"=>{:primitive=>"string", :member_type=>nil}, "backtrace"=>{:primitive=>"string", :member_type=>nil}}}
|
16
|
-
let(:ancestors) {[base_exception]}
|
17
|
-
|
18
15
|
[
|
19
16
|
WashoutBuilder::Document::SharedComplexType
|
20
17
|
].each do |extension|
|
21
18
|
specify { described_class.included_modules.should include(extension) }
|
22
19
|
end
|
23
|
-
|
24
|
-
specify {InheritedExceptionModel.included_modules.should include(WashoutBuilder::Document::SharedComplexType) }
|
25
|
-
|
26
|
-
def fault_ancestor_hash(subject,
|
27
|
-
{:
|
20
|
+
|
21
|
+
specify { InheritedExceptionModel.included_modules.should include(WashoutBuilder::Document::SharedComplexType) }
|
22
|
+
|
23
|
+
def fault_ancestor_hash(subject, structure, ancestors)
|
24
|
+
{ fault: subject, structure: structure, ancestors: ancestors }
|
28
25
|
end
|
29
|
-
|
30
|
-
it
|
31
|
-
subject.
|
26
|
+
|
27
|
+
it 'gets the strcuture' do
|
28
|
+
subject.find_fault_model_structure.should eq(structure)
|
32
29
|
end
|
33
|
-
|
34
|
-
it
|
35
|
-
base_exception.
|
30
|
+
|
31
|
+
it 'gets the strcuture' do
|
32
|
+
base_exception.find_fault_model_structure.should eq(base_structure)
|
36
33
|
end
|
37
|
-
it
|
38
|
-
subject.
|
34
|
+
it 'gets the strcuture' do
|
35
|
+
subject.find_fault_attributes.should eq(%w(message backtrace))
|
39
36
|
end
|
40
|
-
it
|
41
|
-
base_exception.
|
37
|
+
it 'gets the strcuture' do
|
38
|
+
base_exception.find_fault_attributes.should eq(%w(code message backtrace))
|
42
39
|
end
|
43
|
-
|
44
|
-
specify { subject.check_valid_fault_method?(
|
45
|
-
specify { subject.get_fault_type_method(
|
46
|
-
specify { subject.get_fault_type_method(
|
47
|
-
specify { subject.get_fault_type_method(
|
48
|
-
|
49
|
-
it
|
50
|
-
subject.remove_fault_type_inheritable_elements([
|
40
|
+
|
41
|
+
specify { subject.check_valid_fault_method?('code').should eq(true) }
|
42
|
+
specify { subject.get_fault_type_method('code').should eq('integer') }
|
43
|
+
specify { subject.get_fault_type_method('message').should eq('string') }
|
44
|
+
specify { subject.get_fault_type_method('backtrace').should eq('string') }
|
45
|
+
|
46
|
+
it 'gets the strcuture' do
|
47
|
+
subject.remove_fault_type_inheritable_elements(['code']).should eq('message' => { primitive: 'string', member_type: nil }, 'backtrace' => { primitive: 'string', member_type: nil })
|
51
48
|
end
|
52
|
-
|
53
|
-
it
|
54
|
-
subject.fault_ancestor_hash(
|
49
|
+
|
50
|
+
it 'fault_ancestor_hash' do
|
51
|
+
subject.fault_ancestor_hash(structure, ancestors).should eq(fault_ancestor_hash(subject, structure, ancestors))
|
55
52
|
end
|
56
|
-
|
57
|
-
it
|
58
|
-
subject.expects(:get_complex_type_ancestors).with(subject, [
|
53
|
+
|
54
|
+
it 'gets the fault_ancestors' do
|
55
|
+
subject.expects(:get_complex_type_ancestors).with(subject, ['ActiveRecord::Base', 'Object', 'BasicObject', 'Exception']).returns(ancestors)
|
59
56
|
subject.fault_ancestors.should eq ancestors
|
60
57
|
end
|
61
|
-
|
62
|
-
it
|
63
|
-
subject.get_fault_type_method(
|
58
|
+
|
59
|
+
it 'gets the attribute type' do
|
60
|
+
subject.get_fault_type_method('some_name').should eq 'string'
|
64
61
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
ancestors[0].expects(:get_fault_model_structure).returns(structure)
|
62
|
+
|
63
|
+
it 'gets the fault_without_inheritable_elements' do
|
64
|
+
ancestors[0].expects(:find_fault_model_structure).returns(structure)
|
69
65
|
subject.expects(:remove_fault_type_inheritable_elements).with(structure.keys)
|
70
66
|
subject.fault_without_inheritable_elements(ancestors)
|
71
67
|
end
|
72
|
-
|
73
|
-
it
|
68
|
+
|
69
|
+
it 'gets the ancestors' do
|
74
70
|
subject.expects(:fault_ancestors).returns(nil)
|
75
|
-
subject.expects(:
|
76
|
-
subject.expects(:fault_ancestor_hash).with(structure, []).returns(fault_ancestor_hash(subject,
|
71
|
+
subject.expects(:find_fault_model_structure).returns(structure)
|
72
|
+
subject.expects(:fault_ancestor_hash).with(structure, []).returns(fault_ancestor_hash(subject, structure, ancestors))
|
77
73
|
subject.get_fault_class_ancestors([]).should eq(nil)
|
78
74
|
end
|
79
|
-
|
80
|
-
it
|
81
|
-
expected_defined = fault_ancestor_hash(subject,
|
75
|
+
|
76
|
+
it 'gets the ancestors' do
|
77
|
+
expected_defined = fault_ancestor_hash(subject, structure, ancestors)
|
82
78
|
subject.expects(:fault_ancestors).returns(ancestors)
|
83
79
|
subject.expects(:fault_without_inheritable_elements).with(ancestors).returns(structure)
|
84
80
|
subject.expects(:fault_ancestor_hash).returns(expected_defined)
|
85
81
|
subject.get_fault_class_ancestors([])
|
86
82
|
end
|
87
|
-
|
88
83
|
end
|
@@ -1,73 +1,71 @@
|
|
1
|
-
#encoding:utf-8
|
1
|
+
# encoding:utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
mock_controller do
|
4
|
-
soap_service
|
4
|
+
soap_service namespace: '/api/wsdl', description: 'some description'
|
5
5
|
|
6
|
-
soap_action 'dispatcher_method', :
|
7
|
-
soap_action 'dispatcher_method2', :
|
8
|
-
soap_action 'dispatcher_method3', :
|
6
|
+
soap_action 'dispatcher_method', args: nil, return: nil
|
7
|
+
soap_action 'dispatcher_method2', args: nil, return: nil, raises: WashoutBuilderTestError
|
8
|
+
soap_action 'dispatcher_method3', args: ProjectType, return: nil, raises: [WashoutBuilderTestError]
|
9
9
|
def dispatcher_method
|
10
|
-
#nothing
|
10
|
+
# nothing
|
11
11
|
end
|
12
|
+
|
12
13
|
def dispatcher_method2
|
13
|
-
#nothing
|
14
|
+
# nothing
|
14
15
|
end
|
16
|
+
|
15
17
|
def dispatcher_method3
|
16
|
-
#nothing
|
18
|
+
# nothing
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
22
|
describe WashoutBuilder::Document::Generator do
|
21
|
-
|
22
|
-
|
23
|
+
let(:soap_config) do
|
24
|
+
OpenStruct.new(
|
23
25
|
camelize_wsdl: false,
|
24
|
-
namespace:
|
25
|
-
description:
|
26
|
-
)
|
27
|
-
|
26
|
+
namespace: '/api/wsdl',
|
27
|
+
description: 'some description'
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
28
31
|
let(:service_class) { ApiController }
|
29
32
|
before(:each) do
|
30
|
-
@document = WashoutBuilder::Document::Generator.new(
|
33
|
+
@document = WashoutBuilder::Document::Generator.new('api')
|
31
34
|
@document.stubs(:controller_class).returns(service_class)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
context "sorted_operations" do
|
58
|
-
|
59
|
-
it "returns sorted operations" do
|
60
|
-
expected = service_class.soap_actions.sort_by { |operation, formats| operation.downcase }.uniq
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'namespace' do
|
38
|
+
specify { @document.namespace.should eq(soap_config.namespace) }
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'endpoint' do
|
42
|
+
specify { @document.endpoint.should eq(soap_config.namespace.gsub('/wsdl', '/action')) }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'service' do
|
46
|
+
specify { @document.service.should eq(service_class.name.underscore.gsub('_controller', '').camelize) }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'description' do
|
50
|
+
specify { @document.service_description.should eq(soap_config.description) }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'operations' do
|
54
|
+
specify { @document.operations.should eq(service_class.soap_actions.map { |operation, _formats| operation }) }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'sorted_operations' do
|
58
|
+
it 'returns sorted operations' do
|
59
|
+
expected = service_class.soap_actions.sort_by { |operation, _formats| operation.downcase }.uniq
|
61
60
|
@document.sorted_operations.should eq expected
|
62
61
|
end
|
63
|
-
|
64
62
|
end
|
65
|
-
|
63
|
+
|
66
64
|
def argument_types(type)
|
67
|
-
format_type = (type ==
|
65
|
+
format_type = (type == 'input') ? 'builder_in' : 'builder_out'
|
68
66
|
types = []
|
69
67
|
unless service_class.soap_actions.blank?
|
70
|
-
service_class.soap_actions.each do |
|
68
|
+
service_class.soap_actions.each do |_operation, formats|
|
71
69
|
(formats[format_type.to_sym]).each do |p|
|
72
70
|
types << p
|
73
71
|
end
|
@@ -75,91 +73,68 @@ describe WashoutBuilder::Document::Generator do
|
|
75
73
|
end
|
76
74
|
types
|
77
75
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
specify { @document.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
context
|
94
|
-
|
95
|
-
|
96
|
-
specify { @document.
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
context "get_soap_action_names" do
|
101
|
-
|
102
|
-
let(:expected) {service_class.soap_actions.map { |operation, formats| operation }.map(&:to_s).sort_by { |name| name.downcase }.uniq}
|
103
|
-
|
104
|
-
specify { @document.get_soap_action_names.should eq(expected) }
|
105
|
-
|
106
|
-
|
107
|
-
it "returns nil on empty soap actions" do
|
76
|
+
|
77
|
+
context 'input types' do
|
78
|
+
specify { @document.input_types.should eq(argument_types('input')) }
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'output types' do
|
82
|
+
specify { @document.output_types.should eq(argument_types('output')) }
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'operation exceptions' do
|
86
|
+
specify { @document.operation_exceptions('dispatcher_method').should eq([]) }
|
87
|
+
specify { @document.operation_exceptions('dispatcher_method2').should eq([WashoutBuilderTestError]) }
|
88
|
+
specify { @document.operation_exceptions('dispatcher_method3').should eq([WashoutBuilderTestError]) }
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'all_soap_action_names' do
|
92
|
+
let(:expected) { service_class.soap_actions.map { |operation, _formats| operation }.map(&:to_s).sort_by(&:downcase).uniq }
|
93
|
+
|
94
|
+
specify { @document.all_soap_action_names.should eq(expected) }
|
95
|
+
|
96
|
+
it 'returns nil on empty soap actions' do
|
108
97
|
@document.stubs(:soap_actions).returns(nil)
|
109
|
-
@document.
|
98
|
+
@document.all_soap_action_names.should eq(nil)
|
110
99
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
let(:
|
117
|
-
|
118
|
-
let(:filter_exceptions_raised) { exceptions_raised.select { |x| WashoutBuilder::Type.valid_fault_class?(x) } unless actions_with_exceptions.blank?}
|
119
|
-
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'actions with exceptions' do
|
103
|
+
let(:actions_with_exceptions) { service_class.soap_actions.select { |_operation, formats| !formats[:raises].blank? } }
|
104
|
+
let(:exceptions_raised) { actions_with_exceptions.map { |_operation, formats| formats[:raises].is_a?(Array) ? formats[:raises] : [formats[:raises]] }.flatten }
|
105
|
+
let(:filter_exceptions_raised) { exceptions_raised.select { |x| WashoutBuilder::Type.valid_fault_class?(x) } unless actions_with_exceptions.blank? }
|
106
|
+
|
120
107
|
specify { @document.actions_with_exceptions.should eq actions_with_exceptions }
|
121
108
|
specify { @document.exceptions_raised.should eq exceptions_raised }
|
122
109
|
specify { @document.filter_exceptions_raised.should eq filter_exceptions_raised }
|
123
|
-
|
124
|
-
it
|
125
|
-
WashoutBuilder::Type.stubs(:
|
110
|
+
|
111
|
+
it 'returns the fault types' do
|
112
|
+
WashoutBuilder::Type.stubs(:all_fault_classes).returns([base_exception])
|
126
113
|
@document.expects(:get_complex_fault_types).with([base_exception]).returns([base_exception])
|
127
|
-
@document.expects(:sort_complex_types).with([base_exception],
|
114
|
+
@document.expects(:sort_complex_types).with([base_exception], 'fault').returns([base_exception])
|
128
115
|
@document.fault_types.should eq([base_exception])
|
129
116
|
end
|
130
|
-
|
131
|
-
it
|
117
|
+
|
118
|
+
it 'returns complex fault types' do
|
132
119
|
base_exception.expects(:get_fault_class_ancestors).with([], true).returns(nil)
|
133
120
|
@document.expects(:filter_exceptions_raised).returns(nil)
|
134
121
|
@document.get_complex_fault_types([base_exception]).should eq([])
|
135
122
|
end
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
}
|
145
|
-
|
146
|
-
|
147
|
-
it "returns nil on empty soap actions" do
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'complex types' do
|
126
|
+
let(:expected)do
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns nil on empty soap actions' do
|
148
130
|
@document.stubs(:soap_actions).returns(nil)
|
149
131
|
@document.complex_types.should eq(nil)
|
150
132
|
end
|
151
|
-
|
152
|
-
it
|
133
|
+
|
134
|
+
it 'returns nil if no complex types detected' do
|
153
135
|
WashOut::Param.any_instance.expects(:get_nested_complex_types).returns([])
|
154
|
-
@document.expects(:sort_complex_types).with([],
|
136
|
+
@document.expects(:sort_complex_types).with([], 'class').returns(nil)
|
155
137
|
@document.complex_types.should eq(nil)
|
156
138
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
end
|
163
|
-
|
164
|
-
|
165
|
-
end
|
139
|
+
end
|
140
|
+
end
|
@@ -1,42 +1,30 @@
|
|
1
|
-
#encoding:utf-8
|
1
|
+
# encoding:utf-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe WashoutBuilder::Type do
|
6
|
+
let(:exception) { WashoutBuilderTestError }
|
7
|
+
let(:fault_classes) { [exception] }
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
it "defines a list of types" do
|
11
|
-
WashoutBuilder::Type::BASIC_TYPES.should eq([
|
12
|
-
"string",
|
13
|
-
"integer",
|
14
|
-
"double",
|
15
|
-
"boolean",
|
16
|
-
"date",
|
17
|
-
"datetime",
|
18
|
-
"float",
|
19
|
-
"time",
|
20
|
-
"int"])
|
9
|
+
it 'defines a list of types' do
|
10
|
+
WashoutBuilder::Type::BASIC_TYPES.should eq(%w(string integer double boolean date datetime float time int))
|
21
11
|
end
|
22
|
-
|
23
|
-
it
|
24
|
-
WashoutBuilder::Type.
|
12
|
+
|
13
|
+
it 'gets the fault classes defined' do
|
14
|
+
WashoutBuilder::Type.all_fault_classes.should eq([base_exception])
|
25
15
|
end
|
26
|
-
|
27
|
-
context
|
16
|
+
|
17
|
+
context 'exception' do
|
28
18
|
before(:each) do
|
29
|
-
WashoutBuilder::Type.stubs(:
|
19
|
+
WashoutBuilder::Type.stubs(:all_fault_classes).returns([base_exception])
|
30
20
|
end
|
31
|
-
|
32
|
-
it
|
33
|
-
WashoutBuilder::Type.
|
21
|
+
|
22
|
+
it 'checks if exception has ancestor' do
|
23
|
+
WashoutBuilder::Type.ancestor_fault?(exception).should eq(true)
|
34
24
|
end
|
35
|
-
|
36
|
-
it
|
25
|
+
|
26
|
+
it 'checks if exception valid' do
|
37
27
|
WashoutBuilder::Type.valid_fault_class?(exception).should eq(true)
|
38
28
|
end
|
39
29
|
end
|
40
|
-
|
41
|
-
|
42
|
-
end
|
30
|
+
end
|