factory_girl 2.0.0.beta1 → 2.0.0.beta2
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/Appraisals +12 -0
- data/{CONTRIBUTION_GUIDELINES.rdoc → CONTRIBUTION_GUIDELINES.md} +3 -3
- data/GETTING_STARTED.md +246 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +62 -0
- data/README.md +64 -0
- data/Rakefile +15 -30
- data/features/factory_girl_steps.feature +26 -0
- data/features/step_definitions/database_steps.rb +2 -0
- data/features/support/env.rb +0 -9
- data/features/support/factories.rb +15 -0
- data/features/support/test.db +0 -0
- data/lib/factory_girl.rb +2 -0
- data/lib/factory_girl/definition_proxy.rb +10 -43
- data/lib/factory_girl/factory.rb +48 -17
- data/lib/factory_girl/proxy.rb +3 -3
- data/lib/factory_girl/proxy/attributes_for.rb +1 -1
- data/lib/factory_girl/proxy/build.rb +3 -3
- data/lib/factory_girl/proxy/create.rb +6 -2
- data/lib/factory_girl/proxy/stub.rb +3 -3
- data/lib/factory_girl/registry.rb +59 -0
- data/lib/factory_girl/sequence.rb +23 -9
- data/lib/factory_girl/step_definitions.rb +16 -9
- data/lib/factory_girl/syntax/blueprint.rb +2 -2
- data/lib/factory_girl/syntax/default.rb +5 -3
- data/lib/factory_girl/syntax/generate.rb +6 -6
- data/lib/factory_girl/syntax/make.rb +2 -2
- data/lib/factory_girl/syntax/methods.rb +75 -0
- data/lib/factory_girl/syntax/sham.rb +2 -2
- data/lib/factory_girl/syntax/vintage.rb +16 -79
- data/lib/factory_girl/version.rb +1 -1
- data/spec/acceptance/acceptance_helper.rb +7 -12
- data/spec/acceptance/attribute_aliases_spec.rb +26 -0
- data/spec/acceptance/attributes_for_spec.rb +48 -0
- data/spec/acceptance/build_spec.rb +35 -0
- data/spec/acceptance/build_stubbed_spec.rb +79 -0
- data/spec/acceptance/callbacks_spec.rb +42 -0
- data/spec/acceptance/create_spec.rb +67 -0
- data/spec/acceptance/default_strategy_spec.rb +27 -0
- data/spec/acceptance/definition_spec.rb +28 -0
- data/spec/acceptance/parent_spec.rb +39 -0
- data/spec/acceptance/sequence_spec.rb +32 -0
- data/spec/acceptance/syntax/blueprint_spec.rb +7 -5
- data/spec/acceptance/syntax/generate_spec.rb +10 -4
- data/spec/acceptance/syntax/make_spec.rb +7 -4
- data/spec/acceptance/syntax/sham_spec.rb +15 -8
- data/spec/acceptance/syntax/vintage_spec.rb +57 -17
- data/spec/factory_girl/attribute/dynamic_spec.rb +1 -1
- data/spec/factory_girl/definition_proxy_spec.rb +13 -11
- data/spec/factory_girl/factory_spec.rb +29 -52
- data/spec/factory_girl/find_definitions_spec.rb +34 -23
- data/spec/factory_girl/proxy/attributes_for_spec.rb +6 -6
- data/spec/factory_girl/proxy/build_spec.rb +4 -4
- data/spec/factory_girl/proxy/create_spec.rb +11 -3
- data/spec/factory_girl/proxy/stub_spec.rb +6 -6
- data/spec/factory_girl/proxy_spec.rb +1 -1
- data/spec/factory_girl/registry_spec.rb +92 -0
- data/spec/factory_girl/sequence_spec.rb +65 -8
- data/spec/spec_helper.rb +75 -29
- metadata +66 -43
- data/README.rdoc +0 -282
- data/spec/acceptance/acceptance_spec.rb +0 -288
- data/spec/acceptance/models.rb +0 -48
@@ -8,6 +8,22 @@ share_examples_for "finds definitions" do
|
|
8
8
|
subject { FactoryGirl }
|
9
9
|
end
|
10
10
|
|
11
|
+
RSpec::Matchers.define :require_definitions_from do |file|
|
12
|
+
match do |given|
|
13
|
+
@has_received = have_received.method_missing(:require, file)
|
14
|
+
@has_received.matches?(given)
|
15
|
+
end
|
16
|
+
|
17
|
+
description do
|
18
|
+
"require definitions from #{file}"
|
19
|
+
end
|
20
|
+
|
21
|
+
failure_message_for_should do
|
22
|
+
@has_received.failure_message
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
11
27
|
describe "definition loading" do
|
12
28
|
def self.in_directory_with_files(*files)
|
13
29
|
before do
|
@@ -28,41 +44,35 @@ describe "definition loading" do
|
|
28
44
|
end
|
29
45
|
end
|
30
46
|
|
31
|
-
def require_definitions_from(file)
|
32
|
-
simple_matcher do |given, matcher|
|
33
|
-
has_received = have_received.method_missing(:require, file)
|
34
|
-
result = has_received.matches?(given)
|
35
|
-
matcher.description = "require definitions from #{file}"
|
36
|
-
matcher.failure_message = has_received.failure_message
|
37
|
-
result
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
47
|
describe "with factories.rb" do
|
42
48
|
in_directory_with_files 'factories.rb'
|
43
|
-
it_should_behave_like "finds definitions"
|
44
|
-
|
49
|
+
it_should_behave_like "finds definitions" do
|
50
|
+
it { should require_definitions_from('factories.rb') }
|
51
|
+
end
|
45
52
|
end
|
46
53
|
|
47
54
|
%w(spec test).each do |dir|
|
48
55
|
describe "with a factories file under #{dir}" do
|
49
56
|
in_directory_with_files File.join(dir, 'factories.rb')
|
50
|
-
it_should_behave_like "finds definitions"
|
51
|
-
|
57
|
+
it_should_behave_like "finds definitions" do
|
58
|
+
it { should require_definitions_from("#{dir}/factories.rb") }
|
59
|
+
end
|
52
60
|
end
|
53
61
|
|
54
62
|
describe "with a factories file under #{dir}/factories" do
|
55
63
|
in_directory_with_files File.join(dir, 'factories', 'post_factory.rb')
|
56
|
-
it_should_behave_like "finds definitions"
|
57
|
-
|
64
|
+
it_should_behave_like "finds definitions" do
|
65
|
+
it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
|
66
|
+
end
|
58
67
|
end
|
59
68
|
|
60
69
|
describe "with several factories files under #{dir}/factories" do
|
61
70
|
in_directory_with_files File.join(dir, 'factories', 'post_factory.rb'),
|
62
71
|
File.join(dir, 'factories', 'person_factory.rb')
|
63
|
-
it_should_behave_like "finds definitions"
|
64
|
-
|
65
|
-
|
72
|
+
it_should_behave_like "finds definitions" do
|
73
|
+
it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
|
74
|
+
it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
|
75
|
+
end
|
66
76
|
end
|
67
77
|
|
68
78
|
describe "with several factories files under #{dir}/factories in non-alphabetical order" do
|
@@ -80,10 +90,11 @@ describe "definition loading" do
|
|
80
90
|
in_directory_with_files File.join(dir, 'factories.rb'),
|
81
91
|
File.join(dir, 'factories', 'post_factory.rb'),
|
82
92
|
File.join(dir, 'factories', 'person_factory.rb')
|
83
|
-
it_should_behave_like "finds definitions"
|
84
|
-
|
85
|
-
|
86
|
-
|
93
|
+
it_should_behave_like "finds definitions" do
|
94
|
+
it { should require_definitions_from("#{dir}/factories.rb") }
|
95
|
+
it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
|
96
|
+
it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
|
97
|
+
end
|
87
98
|
end
|
88
99
|
end
|
89
100
|
end
|
@@ -7,12 +7,12 @@ describe FactoryGirl::Proxy::AttributesFor do
|
|
7
7
|
|
8
8
|
describe "when asked to associate with another factory" do
|
9
9
|
before do
|
10
|
-
stub(
|
10
|
+
stub(FactoryGirl).create
|
11
11
|
@proxy.associate(:owner, :user, {})
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should not set a value for the association" do
|
15
|
-
(@proxy.result.key?(:owner)).should_not be
|
15
|
+
(@proxy.result(nil).key?(:owner)).should_not be
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -21,9 +21,9 @@ describe FactoryGirl::Proxy::AttributesFor do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should not call Factory.create when building an association" do
|
24
|
-
stub(
|
24
|
+
stub(FactoryGirl).create
|
25
25
|
@proxy.association(:user).should be_nil
|
26
|
-
|
26
|
+
FactoryGirl.should have_received.create.never
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should always return nil when building an association" do
|
@@ -32,7 +32,7 @@ describe FactoryGirl::Proxy::AttributesFor do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should return a hash when asked for the result" do
|
35
|
-
@proxy.result.should be_kind_of(Hash)
|
35
|
+
@proxy.result(nil).should be_kind_of(Hash)
|
36
36
|
end
|
37
37
|
|
38
38
|
describe "after setting an attribute" do
|
@@ -41,7 +41,7 @@ describe FactoryGirl::Proxy::AttributesFor do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should set that value in the resulting hash" do
|
44
|
-
@proxy.result[:attribute].should == 'value'
|
44
|
+
@proxy.result(nil)[:attribute].should == 'value'
|
45
45
|
end
|
46
46
|
|
47
47
|
it "should return that value when asked for that attribute" do
|
@@ -21,7 +21,7 @@ describe FactoryGirl::Proxy::Build do
|
|
21
21
|
before do
|
22
22
|
@association = "associated-instance"
|
23
23
|
@associated_factory = "associated-factory"
|
24
|
-
stub(FactoryGirl).
|
24
|
+
stub(FactoryGirl).find { @associated_factory }
|
25
25
|
stub(@associated_factory).run { @association }
|
26
26
|
@overrides = { 'attr' => 'value' }
|
27
27
|
@proxy.associate(:owner, :user, @overrides)
|
@@ -39,7 +39,7 @@ describe FactoryGirl::Proxy::Build do
|
|
39
39
|
it "should run create when building an association" do
|
40
40
|
association = "associated-instance"
|
41
41
|
associated_factory = "associated-factory"
|
42
|
-
stub(FactoryGirl).
|
42
|
+
stub(FactoryGirl).find { associated_factory }
|
43
43
|
stub(associated_factory).run { association }
|
44
44
|
overrides = { 'attr' => 'value' }
|
45
45
|
@proxy.association(:user, overrides).should == association
|
@@ -47,14 +47,14 @@ describe FactoryGirl::Proxy::Build do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should return the built instance when asked for the result" do
|
50
|
-
@proxy.result.should == @instance
|
50
|
+
@proxy.result(nil).should == @instance
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should run the :after_build callback when retrieving the result" do
|
54
54
|
spy = Object.new
|
55
55
|
stub(spy).foo
|
56
56
|
@proxy.add_callback(:after_build, proc{ spy.foo })
|
57
|
-
@proxy.result
|
57
|
+
@proxy.result(nil)
|
58
58
|
spy.should have_received.foo
|
59
59
|
end
|
60
60
|
|
@@ -22,7 +22,7 @@ describe FactoryGirl::Proxy::Create do
|
|
22
22
|
before do
|
23
23
|
@association = "associated-instance"
|
24
24
|
@associated_factory = "associated-factory"
|
25
|
-
stub(FactoryGirl).
|
25
|
+
stub(FactoryGirl).find { @associated_factory }
|
26
26
|
stub(@associated_factory).run { @association }
|
27
27
|
@overrides = { 'attr' => 'value' }
|
28
28
|
@proxy.associate(:owner, :user, @overrides)
|
@@ -40,7 +40,7 @@ describe FactoryGirl::Proxy::Create do
|
|
40
40
|
it "should run create when building an association" do
|
41
41
|
association = "associated-instance"
|
42
42
|
associated_factory = "associated-factory"
|
43
|
-
stub(FactoryGirl).
|
43
|
+
stub(FactoryGirl).find { associated_factory }
|
44
44
|
stub(associated_factory).run { association }
|
45
45
|
overrides = { 'attr' => 'value' }
|
46
46
|
@proxy.association(:user, overrides).should == association
|
@@ -55,7 +55,7 @@ describe FactoryGirl::Proxy::Create do
|
|
55
55
|
stub(@create_spy).foo
|
56
56
|
@proxy.add_callback(:after_build, proc{ @build_spy.foo })
|
57
57
|
@proxy.add_callback(:after_create, proc{ @create_spy.foo })
|
58
|
-
@result = @proxy.result
|
58
|
+
@result = @proxy.result(nil)
|
59
59
|
end
|
60
60
|
|
61
61
|
it "should save the instance" do
|
@@ -72,6 +72,14 @@ describe FactoryGirl::Proxy::Create do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
it "runs a custom create block" do
|
76
|
+
block = 'custom create block'
|
77
|
+
stub(block).call
|
78
|
+
stub(@instance).save! { raise }
|
79
|
+
instance = @proxy.result(block)
|
80
|
+
block.should have_received.call(instance)
|
81
|
+
end
|
82
|
+
|
75
83
|
describe "when setting an attribute" do
|
76
84
|
before do
|
77
85
|
@proxy.set(:attribute, 'value')
|
@@ -13,17 +13,17 @@ describe FactoryGirl::Proxy::Stub do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should not be a new record" do
|
16
|
-
@stub.result.should_not be_new_record
|
16
|
+
@stub.result(nil).should_not be_new_record
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should not be able to connect to the database" do
|
20
|
-
lambda { @stub.result.reload }.should raise_error(RuntimeError)
|
20
|
+
lambda { @stub.result(nil).reload }.should raise_error(RuntimeError)
|
21
21
|
end
|
22
22
|
|
23
23
|
describe "when a user factory exists" do
|
24
24
|
before do
|
25
25
|
@user = "user"
|
26
|
-
stub(FactoryGirl).
|
26
|
+
stub(FactoryGirl).find { @associated_factory }
|
27
27
|
@associated_factory = 'associate-factory'
|
28
28
|
end
|
29
29
|
|
@@ -37,7 +37,7 @@ describe FactoryGirl::Proxy::Stub do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should set a value for the association" do
|
40
|
-
@stub.result.owner.should == @user
|
40
|
+
@stub.result(nil).owner.should == @user
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -48,14 +48,14 @@ describe FactoryGirl::Proxy::Stub do
|
|
48
48
|
|
49
49
|
describe "when asked for the result" do
|
50
50
|
it "should return the actual instance" do
|
51
|
-
@stub.result.should == @instance
|
51
|
+
@stub.result(nil).should == @instance
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should run the :after_stub callback" do
|
55
55
|
@spy = Object.new
|
56
56
|
stub(@spy).foo
|
57
57
|
@stub.add_callback(:after_stub, proc{ @spy.foo })
|
58
|
-
@stub.result
|
58
|
+
@stub.result(nil)
|
59
59
|
@spy.should have_received.foo
|
60
60
|
end
|
61
61
|
end
|
@@ -23,7 +23,7 @@ describe FactoryGirl::Proxy do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should raise an error when asked for the result" do
|
26
|
-
lambda { @proxy.result }.should raise_error(NotImplementedError)
|
26
|
+
lambda { @proxy.result(nil) }.should raise_error(NotImplementedError)
|
27
27
|
end
|
28
28
|
|
29
29
|
describe "when adding callbacks" do
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FactoryGirl::Registry do
|
4
|
+
let(:factory) { FactoryGirl::Factory.new(:object) }
|
5
|
+
|
6
|
+
subject { FactoryGirl::Registry.new }
|
7
|
+
|
8
|
+
it "finds a registered a factory" do
|
9
|
+
subject.add(factory)
|
10
|
+
subject.find(factory.name).should == factory
|
11
|
+
end
|
12
|
+
|
13
|
+
it "raises when finding an unregistered factory" do
|
14
|
+
expect { subject.find(:bogus) }.to raise_error(ArgumentError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "adds and returns a factory" do
|
18
|
+
subject.add(factory).should == factory
|
19
|
+
end
|
20
|
+
|
21
|
+
it "knows that a factory is registered by symbol" do
|
22
|
+
subject.add(factory)
|
23
|
+
subject.should be_registered(factory.name.to_sym)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "knows that a factory is registered by string" do
|
27
|
+
subject.add(factory)
|
28
|
+
subject.should be_registered(factory.name.to_s)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "knows that a factory isn't registered" do
|
32
|
+
subject.should_not be_registered("bogus")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can be accessed like a hash" do
|
36
|
+
subject.add(factory)
|
37
|
+
subject[factory.name].should == factory
|
38
|
+
end
|
39
|
+
|
40
|
+
it "iterates registered factories" do
|
41
|
+
other_factory = FactoryGirl::Factory.new(:string)
|
42
|
+
subject.add(factory)
|
43
|
+
subject.add(other_factory)
|
44
|
+
result = {}
|
45
|
+
|
46
|
+
subject.each do |name, value|
|
47
|
+
result[name] = value
|
48
|
+
end
|
49
|
+
|
50
|
+
result.should == { factory.name => factory,
|
51
|
+
other_factory.name => other_factory }
|
52
|
+
end
|
53
|
+
|
54
|
+
it "registers an sequence" do
|
55
|
+
sequence = FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" }
|
56
|
+
subject.add(sequence)
|
57
|
+
subject.find(:email).should == sequence
|
58
|
+
end
|
59
|
+
|
60
|
+
it "doesn't allow a duplicate name" do
|
61
|
+
expect { 2.times { subject.add(factory) } }.
|
62
|
+
to raise_error(FactoryGirl::DuplicateDefinitionError)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "registers aliases" do
|
66
|
+
aliases = [:thing, :widget]
|
67
|
+
factory = FactoryGirl::Factory.new(:object, :aliases => aliases)
|
68
|
+
subject.add(factory)
|
69
|
+
aliases.each do |name|
|
70
|
+
subject.find(name).should == factory
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "on the FactoryGirl module" do
|
75
|
+
it "finds a registered a factory" do
|
76
|
+
FactoryGirl.register(factory)
|
77
|
+
FactoryGirl.find(factory.name).should == factory
|
78
|
+
end
|
79
|
+
|
80
|
+
it "knows that a factory is registered by symbol" do
|
81
|
+
FactoryGirl.register(factory)
|
82
|
+
FactoryGirl.should be_registered(factory.name.to_sym)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "sets the registry" do
|
86
|
+
registry = FactoryGirl::Registry.new
|
87
|
+
FactoryGirl.registry = registry
|
88
|
+
FactoryGirl.registry.should == registry
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
@@ -3,40 +3,97 @@ require 'spec_helper'
|
|
3
3
|
describe FactoryGirl::Sequence do
|
4
4
|
describe "a basic sequence" do
|
5
5
|
before do
|
6
|
-
@
|
6
|
+
@name = :test
|
7
|
+
@sequence = FactoryGirl::Sequence.new(@name) {|n| "=#{n}" }
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has names" do
|
11
|
+
@sequence.names.should == [@name]
|
7
12
|
end
|
8
13
|
|
9
14
|
it "should start with a value of 1" do
|
15
|
+
@sequence.run.should == "=1"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "responds to next" do
|
10
19
|
@sequence.next.should == "=1"
|
11
20
|
end
|
12
21
|
|
22
|
+
it "responds to default_strategy" do
|
23
|
+
@sequence.default_strategy.should == :create
|
24
|
+
end
|
25
|
+
|
26
|
+
it "runs compatible with the Factory interface" do
|
27
|
+
@sequence.run(nil, nil).should == "=1"
|
28
|
+
end
|
29
|
+
|
13
30
|
describe "after being called" do
|
14
31
|
before do
|
15
|
-
@sequence.
|
32
|
+
@sequence.run
|
16
33
|
end
|
17
34
|
|
18
35
|
it "should use the next value" do
|
19
|
-
@sequence.
|
36
|
+
@sequence.run.should == "=2"
|
20
37
|
end
|
21
38
|
end
|
22
39
|
end
|
23
|
-
|
40
|
+
|
24
41
|
describe "a custom sequence" do
|
25
42
|
before do
|
26
|
-
@sequence = FactoryGirl::Sequence.new("A") {|n| "=#{n}" }
|
43
|
+
@sequence = FactoryGirl::Sequence.new(:name, "A") {|n| "=#{n}" }
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should start with a value of A" do
|
47
|
+
@sequence.run.should == "=A"
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "after being called" do
|
51
|
+
before do
|
52
|
+
@sequence.run
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should use the next value" do
|
56
|
+
@sequence.run.should == "=B"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "a basic sequence without a block" do
|
62
|
+
before do
|
63
|
+
@sequence = FactoryGirl::Sequence.new(:name)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should start with a value of 1" do
|
67
|
+
@sequence.run.should == 1
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "after being called" do
|
71
|
+
before do
|
72
|
+
@sequence.run
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should use the next value" do
|
76
|
+
@sequence.run.should == 2
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "a custom sequence without a block" do
|
82
|
+
before do
|
83
|
+
@sequence = FactoryGirl::Sequence.new(:name, "A")
|
27
84
|
end
|
28
85
|
|
29
86
|
it "should start with a value of A" do
|
30
|
-
@sequence.
|
87
|
+
@sequence.run.should == "A"
|
31
88
|
end
|
32
89
|
|
33
90
|
describe "after being called" do
|
34
91
|
before do
|
35
|
-
@sequence.
|
92
|
+
@sequence.run
|
36
93
|
end
|
37
94
|
|
38
95
|
it "should use the next value" do
|
39
|
-
@sequence.
|
96
|
+
@sequence.run.should == "B"
|
40
97
|
end
|
41
98
|
end
|
42
99
|
end
|