factory-helper 1.7.5 → 1.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -13
  2. data/lib/factory-helper/version.rb +1 -1
  3. data/spec/config_spec.rb +18 -0
  4. data/spec/factory_helper/my_sql_spec.rb +123 -0
  5. data/spec/factory_helper/string_spec.rb +55 -0
  6. data/spec/rspec_locale_hooks_spec.rb +28 -0
  7. data/spec/spec_helper.rb +92 -0
  8. data/test/legacy/test_array_sample_method_compat.rb +56 -0
  9. data/test/legacy/test_avatar.rb +36 -0
  10. data/test/legacy/test_en_au_ocker_locale.rb +23 -0
  11. data/test/legacy/test_en_ca_locale.rb +18 -0
  12. data/test/legacy/test_en_locale.rb +25 -0
  13. data/test/legacy/test_en_us_locale.rb +79 -0
  14. data/test/legacy/test_es_locale.rb +34 -0
  15. data/test/legacy/test_faker.rb +29 -0
  16. data/test/legacy/test_faker_app.rb +12 -0
  17. data/test/legacy/test_faker_bitcoin.rb +14 -0
  18. data/test/legacy/test_faker_business.rb +33 -0
  19. data/test/legacy/test_faker_city.rb +46 -0
  20. data/test/legacy/test_faker_code.rb +27 -0
  21. data/test/legacy/test_faker_commerce.rb +74 -0
  22. data/test/legacy/test_faker_company.rb +19 -0
  23. data/test/legacy/test_faker_date.rb +77 -0
  24. data/test/legacy/test_faker_hacker_talk.rb +37 -0
  25. data/test/legacy/test_faker_internet.rb +146 -0
  26. data/test/legacy/test_faker_lorem.rb +87 -0
  27. data/test/legacy/test_faker_name.rb +20 -0
  28. data/test/legacy/test_faker_number.rb +77 -0
  29. data/test/legacy/test_faker_street.rb +53 -0
  30. data/test/legacy/test_faker_team.rb +13 -0
  31. data/test/legacy/test_faker_time.rb +74 -0
  32. data/test/legacy/test_flexible.rb +57 -0
  33. data/test/legacy/test_locale.rb +45 -0
  34. data/test/legacy/test_pl_locale.rb +27 -0
  35. data/test/test_avatar.rb +36 -0
  36. data/test/test_determinism.rb +57 -0
  37. data/test/test_en_au_ocker_locale.rb +23 -0
  38. data/test/test_en_ca_locale.rb +18 -0
  39. data/test/test_en_locale.rb +25 -0
  40. data/test/test_en_us_locale.rb +79 -0
  41. data/test/test_es_locale.rb +34 -0
  42. data/test/test_factory_helper.rb +28 -0
  43. data/test/test_factory_helper_app.rb +12 -0
  44. data/test/test_factory_helper_bitcoin.rb +14 -0
  45. data/test/test_factory_helper_business.rb +33 -0
  46. data/test/test_factory_helper_city.rb +46 -0
  47. data/test/test_factory_helper_code.rb +27 -0
  48. data/test/test_factory_helper_commerce.rb +70 -0
  49. data/test/test_factory_helper_company.rb +23 -0
  50. data/test/test_factory_helper_date.rb +78 -0
  51. data/test/test_factory_helper_hacker_talk.rb +37 -0
  52. data/test/test_factory_helper_internet.rb +155 -0
  53. data/test/test_factory_helper_lorem.rb +87 -0
  54. data/test/test_factory_helper_name.rb +54 -0
  55. data/test/test_factory_helper_number.rb +77 -0
  56. data/test/test_factory_helper_slack_emoji.rb +45 -0
  57. data/test/test_factory_helper_street.rb +53 -0
  58. data/test/test_factory_helper_team.rb +13 -0
  59. data/test/test_factory_helper_time.rb +74 -0
  60. data/test/test_flexible.rb +57 -0
  61. data/test/test_fr_locale.rb +34 -0
  62. data/test/test_helper.rb +15 -0
  63. data/test/test_locale.rb +45 -0
  64. data/test/test_pl_locale.rb +27 -0
  65. metadata +144 -20
@@ -0,0 +1,57 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ module Faker
4
+ class FoodieFaker < Base
5
+ flexible :chow
6
+ end
7
+ end
8
+
9
+ class TestFakerFlexible < Test::Unit::TestCase
10
+
11
+ def setup
12
+ I18n.reload!
13
+ I18n.backend.store_translations(:xx, :factory_helper => {:chow => {:yummie => [:fudge, :chocolate, :caramel], :taste => "delicious"}})
14
+ I18n.backend.store_translations(:home, :factory_helper => {:address => {:birthplace => [:bed, :hospital, :airplane]}})
15
+ I18n.backend.store_translations(:kindergarden, :factory_helper => {:name => {:girls_name => [:alice, :cheryl, :tatiana]}})
16
+ I18n.backend.store_translations(:work, :factory_helper => {:company => {:do_stuff => [:work, :work, :work]}})
17
+ end
18
+
19
+ def test_flexible_multiple_values
20
+ I18n.with_locale(:xx) do
21
+ actual = Faker::FoodieFaker.yummie
22
+ assert [:fudge, :chocolate, :caramel].include? actual
23
+ end
24
+ end
25
+
26
+ def test_flexible_single_value
27
+ I18n.with_locale(:xx) do
28
+ assert_equal "delicious", Faker::FoodieFaker.taste
29
+ end
30
+ end
31
+
32
+ def test_raises_no_method_error
33
+ I18n.with_locale(:xx) do
34
+ assert_raise(NoMethodError) do
35
+ Faker::FoodieFaker.eeew
36
+ end
37
+ end
38
+ end
39
+
40
+ def test_address_is_flexible
41
+ I18n.with_locale(:home) do
42
+ assert [:bed, :hospital, :airplane].include? Faker::Address.birthplace
43
+ end
44
+ end
45
+
46
+ def test_name_is_flexible
47
+ I18n.with_locale(:kindergarden) do
48
+ assert [:alice, :cheryl, :tatiana].include? Faker::Name.girls_name
49
+ end
50
+ end
51
+
52
+ def test_company_is_flexible
53
+ I18n.with_locale(:work) do
54
+ assert Faker::Company.do_stuff == :work
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
2
+
3
+ LoadedFakerYaml = ['en', 'en-BORK'].inject({}) do |h, locale|
4
+ h[locale] = YAML.load_file(File.expand_path(File.dirname(__FILE__) + "/../../lib/locales/#{locale}.yml"))[locale]['factory_helper']
5
+ h
6
+ end
7
+
8
+ class TestFakerLocale < Test::Unit::TestCase
9
+ def teardown
10
+ Faker::Config.locale = nil
11
+ end
12
+
13
+ def test_locale_separate_from_i18n
14
+ I18n.locale = :en
15
+ Faker::Config.locale = :de
16
+ assert Faker::PhoneNumber.phone_number.match(/\(0\d+\) \d+|\+49-\d+-\d+/)
17
+ assert Faker::Address.street_name.match(//)
18
+ end
19
+
20
+ def test_configured_locale_translation
21
+ Faker::Config.locale = 'en-BORK'
22
+ assert_equal Faker::Base.translate('factory_helper.lorem.words').first, LoadedFakerYaml['en-BORK']['lorem']['words'].first
23
+ end
24
+
25
+ def test_locale_override_when_calling_translate
26
+ Faker::Config.locale = 'en-BORK'
27
+ assert_equal Faker::Base.translate('factory_helper.lorem.words', :locale => :en).first, LoadedFakerYaml['en']['lorem']['words'].first
28
+ end
29
+
30
+ def test_translation_fallback
31
+ Faker::Config.locale = 'en-BORK'
32
+ assert_nil LoadedFakerYaml['en-BORK']['name']
33
+ assert_equal Faker::Base.translate('factory_helper.name.first_name').first, LoadedFakerYaml['en']['name']['first_name'].first
34
+ end
35
+
36
+ def test_regex
37
+ Faker::Config.locale = 'en-GB'
38
+ re = /[A-PR-UWYZ][A-HK-Y]?[0-9][ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}/
39
+ assert re.match(result = Faker::Address.postcode), "#{result} didn't match #{re}"
40
+ end
41
+
42
+ def test_available_locales
43
+ assert I18n.locale_available?('en-GB')
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
2
+
3
+ class TestFakerPlLocale < Test::Unit::TestCase
4
+ def setup
5
+ @phone_prefixes = %w{12 13 14 15 16 17 18 22 23 24 25 29 32 33 34 41 42 43 44 46 48 52 54 55 56 58 59 61 62 63 65 67 68 71 74 75 76 77 81 82 83 84 85 86 87 89 91 94 95}.sort
6
+ @cell_prefixes = %w{50 51 53 57 60 66 69 72 73 78 79 88}.sort
7
+ FactoryHelper::Config.locale = :pl
8
+ end
9
+
10
+ def teardown
11
+ FactoryHelper::Config.locale = nil
12
+ end
13
+
14
+ def test_pl_phone_number
15
+ 999.times do
16
+ assert_includes @phone_prefixes,
17
+ FactoryHelper::PhoneNumber.phone_number[0,2]
18
+ end
19
+ end
20
+
21
+ def test_pl_cell_phone
22
+ 999.times do
23
+ assert_includes @cell_prefixes,
24
+ FactoryHelper::PhoneNumber.cell_phone[0,2]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ class TestFactoryHelperAvatar < Test::Unit::TestCase
4
+ def setup
5
+ @tester = FactoryHelper::Avatar
6
+ end
7
+
8
+ def test_avatar
9
+ assert @tester.image.match(/http:\/\/robohash\.org\/(.+)\.png/)[1] != nil
10
+ end
11
+
12
+ def test_avatar_with_param
13
+ assert @tester.image('factory_helper').match(/http:\/\/robohash\.org\/(.+)\.png/)[1] == 'factory_helper'
14
+ end
15
+
16
+ def test_avatar_with_correct_size
17
+ assert @tester.image('factory_helper', '150x320').match(/http:\/\/robohash\.org\/factory_helper\.png\?size=(.+)/)[1] == '150x320'
18
+ end
19
+
20
+ def test_avatar_with_incorrect_size
21
+ assert_raise ArgumentError do
22
+ @tester.image(nil, '150x320z')
23
+ end
24
+ end
25
+
26
+ def test_avatar_with_supported_format
27
+ assert @tester.image('factory_helper', '300x300', 'jpg').match(/http:\/\/robohash\.org\/factory_helper\.jpg/)
28
+ end
29
+
30
+ def test_avatar_with_incorrect_format
31
+ assert_raise ArgumentError do
32
+ @tester.image(nil, '300x300', 'wrong_format')
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ class TestDeterminism < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @all_methods= all_methods.freeze
7
+ @first_run= []
8
+ end
9
+
10
+ def test_determinism
11
+ FactoryHelper::Config.seed= 42
12
+ @all_methods.each_index do |index|
13
+ store_result @all_methods[index]
14
+ end
15
+ @first_run.freeze
16
+ FactoryHelper::Config.seed= 42
17
+ @all_methods.each_index do |index|
18
+ assert deterministic_random? @first_run[index], @all_methods[index]
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def deterministic_random? first, method_name
25
+ second= eval(method_name)
26
+ (first== second) || raise(
27
+ "#{method_name} has an entropy leak; use "<<
28
+ '"FactoryHelper::Config.random.rand"'
29
+ )
30
+ end
31
+
32
+ def store_result method_name
33
+ begin
34
+ @first_run<< eval(method_name)
35
+ rescue => exception
36
+ raise %Q[#{method_name} raised "#{exception}"]
37
+ end
38
+ end
39
+
40
+ def all_methods
41
+ subclasses.map do |subclass|
42
+ subclass_methods(subclass).flatten
43
+ end.flatten.sort
44
+ end
45
+
46
+ def subclasses
47
+ FactoryHelper.constants.delete_if do |subclass|
48
+ [:Base, :Config, :VERSION].include?(subclass)
49
+ end.sort
50
+ end
51
+
52
+ def subclass_methods(subclass)
53
+ eval("FactoryHelper::#{subclass}.methods(false)").sort.map do |method|
54
+ "FactoryHelper::#{subclass}.#{method}"
55
+ end.sort
56
+ end
57
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ class TestEnUsLocale < Test::Unit::TestCase
4
+ def setup
5
+ FactoryHelper::Config.locale = nil
6
+ end
7
+
8
+ def teardown
9
+ FactoryHelper::Config.locale = nil
10
+ end
11
+
12
+ def test_au_ocker_methods_with_en_au_ocker_locale
13
+ FactoryHelper::Config.locale = 'en-au-ocker'
14
+
15
+ assert FactoryHelper::Name.first_name.is_a? String
16
+ assert FactoryHelper::Name.last_name.is_a? String
17
+ assert FactoryHelper::Name.ocker_first_name.is_a? String
18
+ assert FactoryHelper::Address.street_name.is_a? String
19
+ assert FactoryHelper::Address.city.is_a? String
20
+ assert FactoryHelper::Address.region.is_a? String
21
+ end
22
+
23
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ class TestEnCaLocale < Test::Unit::TestCase
4
+ def setup
5
+ @previous_locale = FactoryHelper::Config.locale
6
+ FactoryHelper::Config.locale = 'en-CA'
7
+ end
8
+
9
+ def teardown
10
+ FactoryHelper::Config.locale = @previous_locale
11
+ end
12
+
13
+ def test_ca_postcode
14
+ expected = /[A-VX-Y][0-9][A-CEJ-NPR-TV-Z] ?[0-9][A-CEJ-NPR-TV-Z][0-9]/
15
+ assert_match(expected, FactoryHelper::Address.postcode)
16
+ end
17
+
18
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ class TesetEnLocale < Test::Unit::TestCase
4
+ def setup
5
+ FactoryHelper::Config.locale = nil
6
+ end
7
+
8
+ def teardown
9
+ FactoryHelper::Config.locale = nil
10
+ end
11
+
12
+ def test_us_states_only_include_states
13
+ assert_equal LoadedYaml['en']['address']['state'].size, 50
14
+ assert_equal LoadedYaml['en']['address']['state'], ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']
15
+ assert_equal LoadedYaml['en']['address']['state_abbr'].size, 50
16
+ assert_equal LoadedYaml['en']['address']['state_abbr'], ['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY']
17
+ end
18
+
19
+ def test_us_zip_codes
20
+ FactoryHelper::Config.locale = 'en-US'
21
+ expected = /\d{5}(\-\d{4})?/
22
+ assert_match(expected, FactoryHelper::Address.zip_code)
23
+ end
24
+
25
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ class TesetEnUsLocale < Test::Unit::TestCase
4
+ def setup
5
+ FactoryHelper::Config.locale = nil
6
+ end
7
+
8
+ def teardown
9
+ FactoryHelper::Config.locale = nil
10
+ end
11
+
12
+ def test_us_phone_methods_return_nil_for_nil_locale
13
+ assert_nil FactoryHelper::PhoneNumber.area_code
14
+ assert_nil FactoryHelper::PhoneNumber.exchange_code
15
+ end
16
+
17
+ def test_subscriber_number_method
18
+ assert FactoryHelper::PhoneNumber.subscriber_number.is_a? String
19
+ assert_equal FactoryHelper::PhoneNumber.subscriber_number.length, 4
20
+ assert_equal FactoryHelper::PhoneNumber.subscriber_number(10).length, 10
21
+ assert_equal FactoryHelper::PhoneNumber.method(:extension), FactoryHelper::PhoneNumber.method(:subscriber_number)
22
+ end
23
+
24
+ def test_us_phone_methods_with_en_us_locale
25
+ FactoryHelper::Config.locale = 'en-US'
26
+
27
+ assert FactoryHelper::PhoneNumber.area_code.is_a? String
28
+ assert FactoryHelper::PhoneNumber.area_code.to_i.is_a? Integer
29
+ assert_equal FactoryHelper::PhoneNumber.area_code.length, 3
30
+
31
+ assert FactoryHelper::PhoneNumber.exchange_code.is_a? String
32
+ assert FactoryHelper::PhoneNumber.exchange_code.to_i.is_a? Integer
33
+ assert_equal FactoryHelper::PhoneNumber.exchange_code.length, 3
34
+ end
35
+
36
+ def test_validity_of_phone_method_output
37
+ FactoryHelper::Config.locale = 'en-US'
38
+
39
+ # got the following regex from http://stackoverflow.com/a/123666/1210055 as an expression of the NANP standard.
40
+ us_number_validation_regex = /^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/
41
+ assert_match(us_number_validation_regex, FactoryHelper::PhoneNumber.phone_number)
42
+ end
43
+
44
+ def test_us_invalid_state_raises_exception
45
+ FactoryHelper::Config.locale = 'en-US'
46
+ assert_raise I18n::MissingTranslationData do FactoryHelper::Address.zip_code('NA') end
47
+ end
48
+
49
+ def test_us_zip_codes_match_state
50
+
51
+ FactoryHelper::Config.locale = 'en-US'
52
+
53
+ state_abbr = 'AZ'
54
+ expected = /^850\d\d$/
55
+ assert_match(expected, FactoryHelper::Address.zip_code(state_abbr))
56
+
57
+ # disjointed ranges for these states
58
+ # http://www.fincen.gov/forms/files/us_state_territory_zip_codes.pdf
59
+ state_abbr = 'AR'
60
+ expected = /^717\d\d$/
61
+ assert_match(expected, FactoryHelper::Address.zip_code(state_abbr))
62
+ state_abbr = 'GA'
63
+ expected = /^301\d\d$/
64
+ assert_match(expected, FactoryHelper::Address.zip_code(state_abbr))
65
+ state_abbr = 'MA'
66
+ expected = /^026\d\d$/
67
+ assert_match(expected, FactoryHelper::Address.zip_code(state_abbr))
68
+ state_abbr = 'NY'
69
+ expected = /^122\d\d$/
70
+ assert_match(expected, FactoryHelper::Address.zip_code(state_abbr))
71
+ state_abbr = 'TX'
72
+ expected = /^798\d\d$/
73
+ assert_match(expected, FactoryHelper::Address.zip_code(state_abbr))
74
+ state_abbr = 'VA'
75
+ expected = /^222\d\d$/
76
+ assert_match(expected, FactoryHelper::Address.zip_code(state_abbr))
77
+
78
+ end
79
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ LoadedEsYaml = ['en', 'es'].inject({}) do |h, locale|
4
+ h[locale] = YAML.load_file(File.expand_path(File.dirname(__FILE__) + "/../lib/locales/#{locale}.yml"))[locale]['factory_helper']
5
+ h
6
+ end
7
+
8
+ class TestEsLocale < Test::Unit::TestCase
9
+ def teardown
10
+ FactoryHelper::Config.locale = nil
11
+ end
12
+
13
+ def test_locale_separate_from_i18n
14
+ I18n.locale = :en
15
+ FactoryHelper::Config.locale = :es
16
+ assert FactoryHelper::Address.street_name.match(//)
17
+ end
18
+
19
+ def test_configured_locale_translation
20
+ FactoryHelper::Config.locale = 'es'
21
+ assert_equal FactoryHelper::Base.translate('factory_helper.address.city_prefix').first, LoadedEsYaml['es']['address']['city_prefix'].first
22
+ end
23
+
24
+ def test_locale_override_when_calling_translate
25
+ FactoryHelper::Config.locale = 'es'
26
+ assert_equal FactoryHelper::Base.translate('factory_helper.lorem.words', :locale => :en).first, LoadedEsYaml['en']['lorem']['words'].first
27
+ end
28
+
29
+ def test_translation_fallback
30
+ FactoryHelper::Config.locale = 'es'
31
+ assert_nil LoadedEsYaml['es']['company']['bs']
32
+ assert_equal FactoryHelper::Base.translate('factory_helper.company.bs'), LoadedEsYaml['en']['company']['bs']
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')
2
+
3
+ class TestFactoryHelper < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_numerify
9
+ 100.times do
10
+ assert FactoryHelper::Base.numerify('###').match(/[1-9]\d{2}/)
11
+ end
12
+ end
13
+
14
+ def test_letterify
15
+ assert FactoryHelper::Base.letterify('???').match(/[A-Z]{3}/)
16
+ end
17
+
18
+ def test_regexify
19
+ {
20
+ 'uk post code' => /^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$/,
21
+ 'us phone' => /^(1-?)[2-8][0-1][0-9]-\d{3}-\d{4}$/
22
+ }.each do |label, re|
23
+ 10.times do
24
+ assert re.match(result = FactoryHelper::Base.regexify(re)), "#{result} is not a match for #{label}"
25
+ end
26
+ end
27
+ end
28
+ end