database_cleaner 0.5.2 → 0.6.0.rc.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/Gemfile.lock +145 -0
- data/History.txt +24 -1
- data/README.textile +48 -0
- data/Rakefile +4 -0
- data/TODO +3 -0
- data/VERSION.yml +3 -2
- data/examples/Gemfile +46 -0
- data/examples/Gemfile.lock +145 -0
- data/examples/config/database.yml +7 -0
- data/examples/config/database.yml.example +8 -0
- data/examples/db/activerecord_one.db +0 -0
- data/examples/db/activerecord_two.db +0 -0
- data/examples/db/datamapper_default.db +0 -0
- data/examples/db/datamapper_one.db +0 -0
- data/examples/db/datamapper_two.db +0 -0
- data/examples/db/sqlite_databases_go_here +0 -0
- data/examples/features/example_multiple_db.feature +23 -0
- data/examples/features/example_multiple_orm.feature +22 -0
- data/examples/features/step_definitions/activerecord_steps.rb +31 -0
- data/examples/features/step_definitions/couchpotato_steps.rb +31 -0
- data/examples/features/step_definitions/datamapper_steps.rb +37 -0
- data/examples/features/step_definitions/mongoid_steps.rb +23 -0
- data/examples/features/step_definitions/mongomapper_steps.rb +31 -0
- data/examples/features/step_definitions/translation_steps.rb +55 -0
- data/examples/features/support/env.rb +49 -10
- data/examples/lib/activerecord_models.rb +34 -5
- data/examples/lib/couchpotato_models.rb +46 -6
- data/examples/lib/datamapper_models.rb +37 -3
- data/examples/lib/mongoid_models.rb +28 -2
- data/examples/lib/mongomapper_models.rb +35 -1
- data/features/cleaning_multiple_dbs.feature +20 -0
- data/features/cleaning_multiple_orms.feature +29 -0
- data/features/step_definitions/database_cleaner_steps.rb +20 -13
- data/features/support/feature_runner.rb +39 -0
- data/lib/database_cleaner/active_record/base.rb +46 -0
- data/lib/database_cleaner/active_record/transaction.rb +10 -10
- data/lib/database_cleaner/active_record/truncation.rb +17 -7
- data/lib/database_cleaner/base.rb +129 -0
- data/lib/database_cleaner/configuration.rb +45 -97
- data/lib/database_cleaner/couch_potato/base.rb +7 -0
- data/lib/database_cleaner/couch_potato/truncation.rb +4 -2
- data/lib/database_cleaner/cucumber.rb +0 -1
- data/lib/database_cleaner/data_mapper/base.rb +21 -0
- data/lib/database_cleaner/data_mapper/transaction.rb +10 -5
- data/lib/database_cleaner/data_mapper/truncation.rb +52 -19
- data/lib/database_cleaner/generic/base.rb +23 -0
- data/lib/database_cleaner/generic/truncation.rb +43 -0
- data/lib/database_cleaner/mongo_mapper/base.rb +20 -0
- data/lib/database_cleaner/mongo_mapper/truncation.rb +9 -3
- data/lib/database_cleaner/mongoid/base.rb +20 -0
- data/lib/database_cleaner/mongoid/truncation.rb +9 -5
- data/spec/database_cleaner/active_record/base_spec.rb +130 -0
- data/spec/database_cleaner/active_record/truncation_spec.rb +19 -18
- data/spec/database_cleaner/base_spec.rb +441 -0
- data/spec/database_cleaner/configuration_spec.rb +255 -68
- data/spec/database_cleaner/couch_potato/truncation_spec.rb +4 -3
- data/spec/database_cleaner/data_mapper/base_spec.rb +30 -0
- data/spec/database_cleaner/data_mapper/transaction_spec.rb +23 -0
- data/spec/database_cleaner/data_mapper/truncation_spec.rb +11 -0
- data/spec/database_cleaner/generic/base_spec.rb +22 -0
- data/spec/database_cleaner/generic/truncation_spec.rb +68 -0
- data/spec/database_cleaner/mongo_mapper/base_spec.rb +33 -0
- data/spec/database_cleaner/mongo_mapper/mongo_examples.rb +8 -0
- data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +11 -18
- data/spec/database_cleaner/shared_strategy_spec.rb +13 -0
- data/spec/rcov.opts +1 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -3
- metadata +76 -8
- data/examples/features/step_definitions/example_steps.rb +0 -8
- data/lib/database_cleaner/truncation_base.rb +0 -41
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'database_cleaner/shared_strategy_spec'
|
3
|
+
require 'database_cleaner/generic/base'
|
4
|
+
|
5
|
+
module ::DatabaseCleaner
|
6
|
+
module Generic
|
7
|
+
class ExampleStrategy
|
8
|
+
include ::DatabaseCleaner::Generic::Base
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ExampleStrategy do
|
12
|
+
context "class methods" do
|
13
|
+
subject { ExampleStrategy }
|
14
|
+
its(:available_strategies) { should be_empty }
|
15
|
+
end
|
16
|
+
|
17
|
+
it_should_behave_like "a generic strategy"
|
18
|
+
|
19
|
+
its(:db) { should == :default }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'database_cleaner/generic/truncation'
|
3
|
+
|
4
|
+
module ::DatabaseCleaner
|
5
|
+
module Generic
|
6
|
+
class TruncationExample
|
7
|
+
include ::DatabaseCleaner::Generic::Truncation
|
8
|
+
|
9
|
+
def only
|
10
|
+
@only
|
11
|
+
end
|
12
|
+
|
13
|
+
def except
|
14
|
+
@tables_to_exclude
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class MigrationExample < TruncationExample
|
19
|
+
def migration_storage_name
|
20
|
+
"migration_storage_name"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe TruncationExample do
|
25
|
+
its(:start) { expect{ subject }.to_not raise_error }
|
26
|
+
its(:clean) { expect{ subject }.to raise_error(NotImplementedError) }
|
27
|
+
|
28
|
+
context "private methods" do
|
29
|
+
it { should_not respond_to(:tables_to_truncate) }
|
30
|
+
its(:tables_to_truncate) { expect{ subject }.to raise_error(NotImplementedError) }
|
31
|
+
|
32
|
+
it { should_not respond_to(:migration_storage_name) }
|
33
|
+
its(:migration_storage_name) { should be_nil }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "initialize" do
|
37
|
+
it { expect{ subject }.to_not raise_error }
|
38
|
+
|
39
|
+
it "should accept a hash of options" do
|
40
|
+
expect{ TruncationExample.new {} }.to_not raise_error
|
41
|
+
end
|
42
|
+
|
43
|
+
it { expect{ TruncationExample.new( { :a_random_param => "should raise ArgumentError" } ) }.to raise_error(ArgumentError) }
|
44
|
+
it { expect{ TruncationExample.new( { :except => "something",:only => "something else" } ) }.to raise_error(ArgumentError) }
|
45
|
+
it { expect{ TruncationExample.new( { :only => "something" } ) }.to_not raise_error(ArgumentError) }
|
46
|
+
it { expect{ TruncationExample.new( { :except => "something" } ) }.to_not raise_error(ArgumentError) }
|
47
|
+
|
48
|
+
context "" do
|
49
|
+
subject { TruncationExample.new( { :only => ["something"] } ) }
|
50
|
+
its(:only) { should == ["something"] }
|
51
|
+
its(:except) { should == [] }
|
52
|
+
end
|
53
|
+
|
54
|
+
context "" do
|
55
|
+
subject { TruncationExample.new( { :except => ["something"] } ) }
|
56
|
+
its(:only) { should == nil }
|
57
|
+
its(:except) { should include("something") }
|
58
|
+
end
|
59
|
+
|
60
|
+
context "" do
|
61
|
+
subject { MigrationExample.new }
|
62
|
+
its(:only) { should == nil }
|
63
|
+
its(:except) { should == ["migration_storage_name"] }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'database_cleaner/mongo_mapper/base'
|
3
|
+
require 'database_cleaner/shared_strategy_spec'
|
4
|
+
|
5
|
+
module DatabaseCleaner
|
6
|
+
describe MongoMapper do
|
7
|
+
it { should respond_to(:available_strategies) }
|
8
|
+
end
|
9
|
+
|
10
|
+
module MongoMapper
|
11
|
+
class ExampleStrategy
|
12
|
+
include ::DatabaseCleaner::MongoMapper::Base
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ExampleStrategy do
|
16
|
+
|
17
|
+
it_should_behave_like "a generic strategy"
|
18
|
+
|
19
|
+
describe "db" do
|
20
|
+
it { should respond_to(:db=) }
|
21
|
+
|
22
|
+
it "should store my desired db" do
|
23
|
+
subject.db = :my_db
|
24
|
+
subject.db.should == :my_db
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should default to :default" do
|
28
|
+
subject.db.should == :default
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,33 +1,26 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
2
|
require 'mongo_mapper'
|
3
3
|
require 'database_cleaner/mongo_mapper/truncation'
|
4
|
-
|
5
|
-
MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
|
6
|
-
TEST_DATABASE = 'database_cleaner_specs'
|
7
|
-
MongoMapper.database = TEST_DATABASE
|
8
|
-
|
9
|
-
class Widget
|
10
|
-
include MongoMapper::Document
|
11
|
-
key :name, String
|
12
|
-
end
|
13
|
-
class Gadget
|
14
|
-
include MongoMapper::Document
|
15
|
-
key :name, String
|
16
|
-
end
|
17
|
-
|
4
|
+
require File.dirname(__FILE__) + '/mongo_examples'
|
18
5
|
|
19
6
|
module DatabaseCleaner
|
20
7
|
module MongoMapper
|
21
8
|
|
22
9
|
describe Truncation do
|
10
|
+
|
11
|
+
#doing this in the file root breaks autospec, doing it before(:all) just fails the specs
|
12
|
+
before(:all) do
|
13
|
+
::MongoMapper.connection = ::Mongo::Connection.new('127.0.0.1')
|
14
|
+
@test_db = 'database_cleaner_specs'
|
15
|
+
::MongoMapper.database = @test_db
|
16
|
+
end
|
17
|
+
|
23
18
|
before(:each) do
|
24
|
-
::MongoMapper.connection.drop_database(
|
25
|
-
#::MongoMapper.connection.db(TEST_DATABASE).collections.each {|c| c.remove }
|
26
|
-
#::MongoMapper.database = TEST_DATABASE
|
19
|
+
::MongoMapper.connection.drop_database(@test_db)
|
27
20
|
end
|
28
21
|
|
29
22
|
def ensure_counts(expected_counts)
|
30
|
-
# I had to add this sanity_check garbage because I was getting non-determinisc results from mongomapper at times..
|
23
|
+
# I had to add this sanity_check garbage because I was getting non-determinisc results from mongomapper at times..
|
31
24
|
# very odd and disconcerting...
|
32
25
|
sanity_check = expected_counts.delete(:sanity_check)
|
33
26
|
begin
|
@@ -0,0 +1,13 @@
|
|
1
|
+
shared_examples_for "a generic strategy" do
|
2
|
+
it { should respond_to(:db) }
|
3
|
+
end
|
4
|
+
|
5
|
+
shared_examples_for "a generic truncation strategy" do
|
6
|
+
it { should respond_to(:start) }
|
7
|
+
it { should respond_to(:clean) }
|
8
|
+
end
|
9
|
+
|
10
|
+
shared_examples_for "a generic transaction strategy" do
|
11
|
+
it { should respond_to(:start) }
|
12
|
+
it { should respond_to(:clean) }
|
13
|
+
end
|
data/spec/rcov.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--exclude "spec/*,vendor/*,examples/*,features/*,Users/*/.rvm/gems/*/gems/*"
|
data/spec/spec.opts
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
1
|
+
require "rubygems"
|
2
|
+
|
3
|
+
require "bundler"
|
4
|
+
Bundler.setup
|
5
|
+
|
4
6
|
|
7
|
+
require 'spec'
|
8
|
+
#require 'active_record'
|
9
|
+
#require 'mongo_mapper'
|
5
10
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
6
11
|
require 'database_cleaner'
|
7
12
|
|
13
|
+
|
14
|
+
|
8
15
|
Spec::Runner.configure do |config|
|
9
16
|
|
10
17
|
end
|
metadata
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: database_cleaner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 15424119
|
5
|
+
prerelease: true
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
- 0
|
10
|
+
- rc
|
11
|
+
- 1
|
12
|
+
version: 0.6.0.rc.1
|
5
13
|
platform: ruby
|
6
14
|
authors:
|
7
15
|
- Ben Mabey
|
@@ -9,7 +17,7 @@ autorequire:
|
|
9
17
|
bindir: bin
|
10
18
|
cert_chain: []
|
11
19
|
|
12
|
-
date: 2010-
|
20
|
+
date: 2010-08-22 00:00:00 -06:00
|
13
21
|
default_executable:
|
14
22
|
dependencies: []
|
15
23
|
|
@@ -24,13 +32,31 @@ extra_rdoc_files:
|
|
24
32
|
- README.textile
|
25
33
|
- TODO
|
26
34
|
files:
|
35
|
+
- Gemfile.lock
|
27
36
|
- History.txt
|
28
37
|
- README.textile
|
29
38
|
- Rakefile
|
30
39
|
- VERSION.yml
|
31
40
|
- cucumber.yml
|
41
|
+
- examples/Gemfile
|
42
|
+
- examples/Gemfile.lock
|
43
|
+
- examples/config/database.yml
|
44
|
+
- examples/config/database.yml.example
|
45
|
+
- examples/db/activerecord_one.db
|
46
|
+
- examples/db/activerecord_two.db
|
47
|
+
- examples/db/datamapper_default.db
|
48
|
+
- examples/db/datamapper_one.db
|
49
|
+
- examples/db/datamapper_two.db
|
50
|
+
- examples/db/sqlite_databases_go_here
|
32
51
|
- examples/features/example.feature
|
33
|
-
- examples/features/
|
52
|
+
- examples/features/example_multiple_db.feature
|
53
|
+
- examples/features/example_multiple_orm.feature
|
54
|
+
- examples/features/step_definitions/activerecord_steps.rb
|
55
|
+
- examples/features/step_definitions/couchpotato_steps.rb
|
56
|
+
- examples/features/step_definitions/datamapper_steps.rb
|
57
|
+
- examples/features/step_definitions/mongoid_steps.rb
|
58
|
+
- examples/features/step_definitions/mongomapper_steps.rb
|
59
|
+
- examples/features/step_definitions/translation_steps.rb
|
34
60
|
- examples/features/support/env.rb
|
35
61
|
- examples/lib/activerecord_models.rb
|
36
62
|
- examples/lib/couchpotato_models.rb
|
@@ -38,25 +64,46 @@ files:
|
|
38
64
|
- examples/lib/mongoid_models.rb
|
39
65
|
- examples/lib/mongomapper_models.rb
|
40
66
|
- features/cleaning.feature
|
67
|
+
- features/cleaning_multiple_dbs.feature
|
68
|
+
- features/cleaning_multiple_orms.feature
|
41
69
|
- features/step_definitions/database_cleaner_steps.rb
|
42
70
|
- features/support/env.rb
|
71
|
+
- features/support/feature_runner.rb
|
43
72
|
- lib/database_cleaner.rb
|
73
|
+
- lib/database_cleaner/active_record/base.rb
|
44
74
|
- lib/database_cleaner/active_record/transaction.rb
|
45
75
|
- lib/database_cleaner/active_record/truncation.rb
|
76
|
+
- lib/database_cleaner/base.rb
|
46
77
|
- lib/database_cleaner/configuration.rb
|
78
|
+
- lib/database_cleaner/couch_potato/base.rb
|
47
79
|
- lib/database_cleaner/couch_potato/truncation.rb
|
48
80
|
- lib/database_cleaner/cucumber.rb
|
81
|
+
- lib/database_cleaner/data_mapper/base.rb
|
49
82
|
- lib/database_cleaner/data_mapper/transaction.rb
|
50
83
|
- lib/database_cleaner/data_mapper/truncation.rb
|
84
|
+
- lib/database_cleaner/generic/base.rb
|
85
|
+
- lib/database_cleaner/generic/truncation.rb
|
86
|
+
- lib/database_cleaner/mongo_mapper/base.rb
|
51
87
|
- lib/database_cleaner/mongo_mapper/truncation.rb
|
88
|
+
- lib/database_cleaner/mongoid/base.rb
|
52
89
|
- lib/database_cleaner/mongoid/truncation.rb
|
53
|
-
-
|
90
|
+
- spec/database_cleaner/active_record/base_spec.rb
|
54
91
|
- spec/database_cleaner/active_record/transaction_spec.rb
|
55
92
|
- spec/database_cleaner/active_record/truncation_spec.rb
|
93
|
+
- spec/database_cleaner/base_spec.rb
|
56
94
|
- spec/database_cleaner/configuration_spec.rb
|
57
95
|
- spec/database_cleaner/couch_potato/truncation_spec.rb
|
96
|
+
- spec/database_cleaner/data_mapper/base_spec.rb
|
97
|
+
- spec/database_cleaner/data_mapper/transaction_spec.rb
|
98
|
+
- spec/database_cleaner/data_mapper/truncation_spec.rb
|
99
|
+
- spec/database_cleaner/generic/base_spec.rb
|
100
|
+
- spec/database_cleaner/generic/truncation_spec.rb
|
101
|
+
- spec/database_cleaner/mongo_mapper/base_spec.rb
|
102
|
+
- spec/database_cleaner/mongo_mapper/mongo_examples.rb
|
58
103
|
- spec/database_cleaner/mongo_mapper/truncation_spec.rb
|
59
104
|
- spec/database_cleaner/mongoid/truncation_spec.rb
|
105
|
+
- spec/database_cleaner/shared_strategy_spec.rb
|
106
|
+
- spec/rcov.opts
|
60
107
|
- spec/spec.opts
|
61
108
|
- spec/spec_helper.rb
|
62
109
|
- LICENSE
|
@@ -71,33 +118,54 @@ rdoc_options:
|
|
71
118
|
require_paths:
|
72
119
|
- lib
|
73
120
|
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
74
122
|
requirements:
|
75
123
|
- - ">="
|
76
124
|
- !ruby/object:Gem::Version
|
125
|
+
hash: 3
|
126
|
+
segments:
|
127
|
+
- 0
|
77
128
|
version: "0"
|
78
|
-
version:
|
79
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
80
131
|
requirements:
|
81
132
|
- - ">="
|
82
133
|
- !ruby/object:Gem::Version
|
134
|
+
hash: 3
|
135
|
+
segments:
|
136
|
+
- 0
|
83
137
|
version: "0"
|
84
|
-
version:
|
85
138
|
requirements: []
|
86
139
|
|
87
140
|
rubyforge_project:
|
88
|
-
rubygems_version: 1.3.
|
141
|
+
rubygems_version: 1.3.7
|
89
142
|
signing_key:
|
90
143
|
specification_version: 3
|
91
144
|
summary: Strategies for cleaning databases. Can be used to ensure a clean state for testing.
|
92
145
|
test_files:
|
146
|
+
- spec/database_cleaner/active_record/base_spec.rb
|
93
147
|
- spec/database_cleaner/active_record/transaction_spec.rb
|
94
148
|
- spec/database_cleaner/active_record/truncation_spec.rb
|
149
|
+
- spec/database_cleaner/base_spec.rb
|
95
150
|
- spec/database_cleaner/configuration_spec.rb
|
96
151
|
- spec/database_cleaner/couch_potato/truncation_spec.rb
|
152
|
+
- spec/database_cleaner/data_mapper/base_spec.rb
|
153
|
+
- spec/database_cleaner/data_mapper/transaction_spec.rb
|
154
|
+
- spec/database_cleaner/data_mapper/truncation_spec.rb
|
155
|
+
- spec/database_cleaner/generic/base_spec.rb
|
156
|
+
- spec/database_cleaner/generic/truncation_spec.rb
|
157
|
+
- spec/database_cleaner/mongo_mapper/base_spec.rb
|
158
|
+
- spec/database_cleaner/mongo_mapper/mongo_examples.rb
|
97
159
|
- spec/database_cleaner/mongo_mapper/truncation_spec.rb
|
98
160
|
- spec/database_cleaner/mongoid/truncation_spec.rb
|
161
|
+
- spec/database_cleaner/shared_strategy_spec.rb
|
99
162
|
- spec/spec_helper.rb
|
100
|
-
- examples/features/step_definitions/
|
163
|
+
- examples/features/step_definitions/activerecord_steps.rb
|
164
|
+
- examples/features/step_definitions/couchpotato_steps.rb
|
165
|
+
- examples/features/step_definitions/datamapper_steps.rb
|
166
|
+
- examples/features/step_definitions/mongoid_steps.rb
|
167
|
+
- examples/features/step_definitions/mongomapper_steps.rb
|
168
|
+
- examples/features/step_definitions/translation_steps.rb
|
101
169
|
- examples/features/support/env.rb
|
102
170
|
- examples/lib/activerecord_models.rb
|
103
171
|
- examples/lib/couchpotato_models.rb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
module DatabaseCleaner
|
2
|
-
class TruncationBase
|
3
|
-
|
4
|
-
def initialize(options = {})
|
5
|
-
if !options.empty? && !(options.keys - [:only, :except]).empty?
|
6
|
-
raise ArgumentError, "The only valid options are :only and :except. You specified #{options.keys.join(',')}."
|
7
|
-
end
|
8
|
-
if options.has_key?(:only) && options.has_key?(:except)
|
9
|
-
raise ArgumentError, "You may only specify either :only or :either. Doing both doesn't really make sense does it?"
|
10
|
-
end
|
11
|
-
|
12
|
-
@only = options[:only]
|
13
|
-
@tables_to_exclude = (options[:except] || [])
|
14
|
-
if migration_storage = migration_storage_name
|
15
|
-
@tables_to_exclude << migration_storage
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def start
|
20
|
-
# no-op
|
21
|
-
end
|
22
|
-
|
23
|
-
def clean
|
24
|
-
raise NotImplementedError
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def tables_to_truncate
|
31
|
-
raise NotImplementedError
|
32
|
-
end
|
33
|
-
|
34
|
-
# overwrite in subclasses
|
35
|
-
# default implementation given because migration storage need not be present
|
36
|
-
def migration_storage_name
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|