poly_belongs_to 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +86 -16
  3. data/lib/poly_belongs_to.rb +57 -52
  4. data/lib/poly_belongs_to/dup.rb +43 -0
  5. data/lib/poly_belongs_to/hierarchy.rb +23 -0
  6. data/lib/poly_belongs_to/poly_belongs_to.rb +66 -0
  7. data/lib/poly_belongs_to/version.rb +1 -1
  8. data/test/dummy/Rakefile +1 -1
  9. data/test/dummy/app/models/address.rb +3 -0
  10. data/test/dummy/app/models/contact.rb +5 -0
  11. data/test/dummy/app/models/photo.rb +3 -0
  12. data/test/dummy/app/models/profile.rb +7 -0
  13. data/test/dummy/app/models/ssn.rb +3 -0
  14. data/test/dummy/app/models/user.rb +3 -1
  15. data/test/dummy/config.ru +1 -1
  16. data/test/dummy/config/application.rb +11 -1
  17. data/test/dummy/config/boot.rb +1 -0
  18. data/test/dummy/config/environment.rb +3 -3
  19. data/test/dummy/config/environments/development.rb +1 -1
  20. data/test/dummy/config/environments/production.rb +1 -1
  21. data/test/dummy/config/environments/test.rb +1 -1
  22. data/test/dummy/config/initializers/assets.rb +3 -3
  23. data/test/dummy/config/initializers/cookies_serializer.rb +1 -1
  24. data/test/dummy/config/initializers/filter_parameter_logging.rb +1 -1
  25. data/test/dummy/config/initializers/session_store.rb +1 -1
  26. data/test/dummy/config/routes.rb +1 -1
  27. data/test/dummy/db/development.sqlite3 +0 -0
  28. data/test/dummy/db/migrate/20150211224139_create_users.rb +1 -0
  29. data/test/dummy/db/migrate/20150211224157_create_tags.rb +1 -0
  30. data/test/dummy/db/migrate/20150211224225_create_phones.rb +1 -0
  31. data/test/dummy/db/migrate/20150216092218_create_addresses.rb +10 -0
  32. data/test/dummy/db/migrate/20150216092338_create_profiles.rb +10 -0
  33. data/test/dummy/db/migrate/20150216092411_create_photos.rb +10 -0
  34. data/test/dummy/db/migrate/20150216092449_create_contacts.rb +11 -0
  35. data/test/dummy/db/migrate/20150216092519_create_ssns.rb +11 -0
  36. data/test/dummy/db/schema.rb +56 -5
  37. data/test/dummy/db/test.sqlite3 +0 -0
  38. data/test/dummy/log/development.log +50 -51
  39. data/test/dummy/log/test.log +49835 -1884
  40. data/test/dup_test.rb +39 -0
  41. data/test/fixtures/addresses.yml +18 -0
  42. data/test/fixtures/phones.yml +12 -3
  43. data/test/fixtures/photos.yml +16 -0
  44. data/test/fixtures/profiles.yml +15 -0
  45. data/test/fixtures/ssns.yml +14 -0
  46. data/test/fixtures/tags.yml +9 -2
  47. data/test/fixtures/users.yml +3 -1
  48. data/test/pbt_test.rb +61 -0
  49. data/test/poly_belongs_to_test.rb +75 -48
  50. data/test/test_helper.rb +13 -7
  51. metadata +58 -47
  52. data/test/dummy/app/assets/javascripts/application.js +0 -13
  53. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  54. data/test/dummy/test/models/phone_test.rb +0 -7
  55. data/test/dummy/test/models/tag_test.rb +0 -7
  56. data/test/dummy/test/models/user_test.rb +0 -7
data/test/dup_test.rb ADDED
@@ -0,0 +1,39 @@
1
+
2
+ require 'test_helper'
3
+ require 'minitest/autorun'
4
+
5
+ class DupTest < ActiveSupport::TestCase
6
+ fixtures :all
7
+
8
+ it "has method pbt_dup_build" do
9
+ User.instance_methods.include?(:pbt_dup_build).must_be_same_as true
10
+ User.methods.include?(:pbt_dup_build).must_be_same_as true
11
+ end
12
+
13
+ it "has method pbt_deep_dup_build" do
14
+ User.instance_methods.include?(:pbt_deep_dup_build).must_be_same_as true
15
+ User.methods.include?(:pbt_deep_dup_build).must_be_same_as true
16
+ end
17
+
18
+ it "builds copy from dup'd attributes" do
19
+ user = users(:bob)
20
+ susan_prof = profiles(:susan_prof)
21
+ contact = user.contacts.new
22
+ contact.pbt_dup_build( susan_prof )
23
+ CleanAttrs[contact.profile].must_equal CleanAttrs[susan_prof]
24
+ end
25
+
26
+ it "builds deep copy of dup'd attributes" do
27
+ #skip "Prepping method. It's in the making."
28
+ user1 = users(:steve)
29
+ bob_prof = profiles(:bob_prof)
30
+ contact = user1.contacts.new
31
+ contact.pbt_deep_dup_build(bob_prof)
32
+ CleanAttrs[contact.profile].must_equal CleanAttrs[bob_prof]
33
+ CleanAttrs[contact.profile.addresses.first].must_equal CleanAttrs[bob_prof.addresses.first]
34
+ CleanAttrs[contact.profile.addresses.last].must_equal CleanAttrs[bob_prof.addresses.last]
35
+ CleanAttrs[contact.profile.phones.first].must_equal CleanAttrs[bob_prof.phones.first]
36
+ CleanAttrs[contact.profile.phones.last].must_equal CleanAttrs[bob_prof.phones.last]
37
+ CleanAttrs[contact.profile.photo].must_equal CleanAttrs[bob_prof.photo]
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ # Read about fixtures at
2
+ # http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
3
+
4
+ bob_address:
5
+ addressable_id: <%= ActiveRecord::FixtureSet.identify(:bob_prof) %>
6
+ addressable_type: Profile
7
+ content: <%= SecureRandom.hex %>
8
+
9
+ steve_address:
10
+ addressable_id: <%= ActiveRecord::FixtureSet.identify(:steve_prof) %>
11
+ addressable_type: Profile
12
+ content: <%= SecureRandom.hex %>
13
+
14
+ susan_address:
15
+ addressable_id: <%= ActiveRecord::FixtureSet.identify(:susan_prof) %>
16
+ addressable_type: Profile
17
+ content: <%= SecureRandom.hex %>
18
+
@@ -1,5 +1,14 @@
1
1
  # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
2
 
3
- one:
4
- phoneable_id: 1
5
- phoneable_type: User
3
+ bob_phone:
4
+ phoneable_id: <%= ActiveRecord::FixtureSet.identify(:bob_prof) %>
5
+ phoneable_type: Profile
6
+ content: <%= SecureRandom.hex %>
7
+ steve_phone:
8
+ phoneable_id: <%= ActiveRecord::FixtureSet.identify(:steve_prof) %>
9
+ phoneable_type: Profile
10
+ content: <%= SecureRandom.hex %>
11
+ susan_phone:
12
+ phoneable_id: <%= ActiveRecord::FixtureSet.identify(:susan_prof) %>
13
+ phoneable_type: Profile
14
+ content: <%= SecureRandom.hex %>
@@ -0,0 +1,16 @@
1
+ # Read about fixtures at
2
+ # http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
3
+
4
+
5
+ bob_photo:
6
+ photoable_id: <%= ActiveRecord::FixtureSet.identify(:bob_prof) %>
7
+ photoable_type: Profile
8
+ content: <%= SecureRandom.hex %>
9
+ steve_photo:
10
+ photoable_id: <%= ActiveRecord::FixtureSet.identify(:steve_prof) %>
11
+ photoable_type: Profile
12
+ content: <%= SecureRandom.hex %>
13
+ susan_photo:
14
+ photoable_id: <%= ActiveRecord::FixtureSet.identify(:susan_prof) %>
15
+ photoable_type: Profile
16
+ content: <%= SecureRandom.hex %>
@@ -0,0 +1,15 @@
1
+ # Read about fixtures at
2
+ # http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
3
+
4
+ bob_prof:
5
+ profileable_id: <%= ActiveRecord::FixtureSet.identify(:bob) %>
6
+ profileable_type: "User"
7
+ content: <%= SecureRandom.hex %>
8
+ steve_prof:
9
+ profileable_id: <%= ActiveRecord::FixtureSet.identify(:steve) %>
10
+ profileable_type: "User"
11
+ content: <%= SecureRandom.hex %>
12
+ susan_prof:
13
+ profileable_id: <%= ActiveRecord::FixtureSet.identify(:susan) %>
14
+ profileable_type: "User"
15
+ content: <%= SecureRandom.hex %>
@@ -0,0 +1,14 @@
1
+ # Read about fixtures at
2
+ # http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
3
+
4
+ bob_ssn:
5
+ user_id: <%= ActiveRecord::FixtureSet.identify(:bob) %>
6
+ content: <%= SecureRandom.hex %>
7
+
8
+ steve_ssn:
9
+ user_id: <%= ActiveRecord::FixtureSet.identify(:steve) %>
10
+ content: <%= SecureRandom.hex %>
11
+
12
+ susan_ssn:
13
+ user_id: <%= ActiveRecord::FixtureSet.identify(:susan) %>
14
+ content: <%= SecureRandom.hex %>
@@ -1,4 +1,11 @@
1
1
  # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
2
 
3
- one:
4
- user_id: 1
3
+ bob_tag:
4
+ user_id: <%= ActiveRecord::FixtureSet.identify(:bob) %>
5
+ content: <%= SecureRandom.hex %>
6
+ steve_tag:
7
+ user_id: <%= ActiveRecord::FixtureSet.identify(:steve) %>
8
+ content: <%= SecureRandom.hex %>
9
+ susan_tag:
10
+ user_id: <%= ActiveRecord::FixtureSet.identify(:susan) %>
11
+ content: <%= SecureRandom.hex %>
@@ -4,4 +4,6 @@
4
4
  # model remove the '{}' from the fixture names and add the columns immediately
5
5
  # below each fixture, per the syntax in the comments below
6
6
  #
7
- one: {}
7
+ bob: {}
8
+ steve: {}
9
+ susan: {}
data/test/pbt_test.rb ADDED
@@ -0,0 +1,61 @@
1
+ require 'test_helper'
2
+ require 'minitest/autorun'
3
+
4
+ class PbtTest < ActiveSupport::TestCase
5
+ fixtures :all
6
+
7
+ it "AttrSanitizer removes conflicting attributes" do
8
+ user = users(:bob)
9
+ PolyBelongsTo::Pbt::AttrSanitizer[user].must_equal Hash[id: nil, content: user.content].stringify_keys
10
+ end
11
+
12
+ it "BuildCmd returns build command" do
13
+ profile = profiles(:bob_prof)
14
+ "#{PolyBelongsTo::Pbt::BuildCmd[profile,Phone]}".must_equal "phones.build"
15
+ "#{PolyBelongsTo::Pbt::BuildCmd[profile,Photo]}".must_equal "build_photo"
16
+ end
17
+
18
+ it "Reflects retruns has_one and has_many relationships" do
19
+ profile = profiles(:bob_prof)
20
+ PolyBelongsTo::Pbt::Reflects[profile].sort.must_equal [:phones, :addresses, :photo].sort
21
+ end
22
+
23
+ it "ReflectsAsClasses one and many relations as classes" do
24
+ profile = profiles(:bob_prof)
25
+ PolyBelongsTo::Pbt::ReflectsAsClasses[profile].map(&:hash).sort.must_equal [Phone, Address, Photo].map(&:hash).sort
26
+ end
27
+
28
+ it "IsReflected gives boolean of child" do
29
+ profile = profiles(:bob_prof)
30
+ PolyBelongsTo::Pbt::IsReflected[profile,Phone].must_equal true
31
+ PolyBelongsTo::Pbt::IsReflected[profile,Address].must_equal true
32
+ PolyBelongsTo::Pbt::IsReflected[profile,Photo].must_equal true
33
+ PolyBelongsTo::Pbt::IsReflected[profile,User].must_equal false
34
+ end
35
+
36
+ it "SingularOrPlural respongs for child relations" do
37
+ profile = profiles(:susan_prof)
38
+ PolyBelongsTo::Pbt::SingularOrPlural[profile,Phone].must_equal :plural
39
+ PolyBelongsTo::Pbt::SingularOrPlural[profile,Photo].must_equal :singular
40
+ PolyBelongsTo::Pbt::SingularOrPlural[profile,User].must_equal nil
41
+ end
42
+
43
+ it "IsSingular tells child singleness" do
44
+ profile = profiles(:steve_prof)
45
+ PolyBelongsTo::Pbt::IsSingular[profile,Phone].must_be_same_as false
46
+ PolyBelongsTo::Pbt::IsSingular[profile,Photo].must_be_same_as true
47
+ end
48
+
49
+ it "IsPlural tells child pluralness" do
50
+ profile = profiles(:bob_prof)
51
+ PolyBelongsTo::Pbt::IsPlural[profile,Phone].must_be_same_as true
52
+ PolyBelongsTo::Pbt::IsPlural[profile,Photo].must_be_same_as false
53
+ end
54
+
55
+ it "CollectionProxy: singular or plural proxy name" do
56
+ profile = profiles(:steve_prof)
57
+ PolyBelongsTo::Pbt::CollectionProxy[profile,Phone].must_equal :phones
58
+ PolyBelongsTo::Pbt::CollectionProxy[profile,Photo].must_equal :photo
59
+ PolyBelongsTo::Pbt::CollectionProxy[profile,User].must_equal nil
60
+ end
61
+ end
@@ -1,141 +1,168 @@
1
1
  require 'test_helper'
2
+ require 'minitest/autorun'
2
3
 
3
4
  class PolyBelongsToTest < ActiveSupport::TestCase
4
5
  fixtures :all
5
6
 
6
7
  it "is a module" do
7
- PolyBelongsTo.must_be_kind_of Module
8
+ PolyBelongsTo::Core.must_be_kind_of Module
8
9
  end
9
10
 
10
- it "reports User as not polymorphic" do
11
- user = users(:one)
11
+ it "User as not polymorphic" do
12
+ user = users(:bob)
12
13
  user.poly?.must_be_same_as false
13
14
  User.poly?.must_be_same_as false
14
15
  end
15
16
 
16
- it "reports Tag as not polymorphic" do
17
- tag = tags(:one)
17
+ it "Tag as not polymorphic" do
18
+ tag = tags(:bob_tag)
18
19
  tag.poly?.must_be_same_as false
19
20
  Tag.poly?.must_be_same_as false
20
21
  end
21
22
 
22
- it "reports Phone as polymorphic" do
23
- phone = phones(:one)
23
+ it "Phone as polymorphic" do
24
+ phone = phones(:bob_phone)
24
25
  phone.poly?.must_be_same_as true
25
26
  Phone.poly?.must_be_same_as true
26
27
  end
27
28
 
28
- it "reports User belongs to relation table as nil" do
29
- user = users(:one)
29
+ it "User belongs to table as nil" do
30
+ user = users(:bob)
30
31
  user.pbt.must_be_nil
31
32
  User.pbt.must_be_nil
32
33
  end
33
34
 
34
- it "reports Tag belongs to relation table as :user" do
35
- tag = tags(:one)
35
+ it "Tag belongs to table as :user" do
36
+ tag = tags(:bob_tag)
36
37
  tag.pbt.must_be_same_as :user
37
38
  Tag.pbt.must_be_same_as :user
38
39
  end
39
40
 
40
- it "reports Phone belongs to relation table as :phoneable" do
41
- phone = phones(:one)
41
+ it "Phone belongs to table as :phoneable" do
42
+ phone = phones(:bob_phone)
42
43
  phone.pbt.must_be_same_as :phoneable
43
44
  Phone.pbt.must_be_same_as :phoneable
44
45
  end
45
46
 
46
- it "reports User params name as :user" do
47
- user = users(:one)
47
+ it "User params name as :user" do
48
+ user = users(:bob)
48
49
  user.pbt_params_name.must_be_same_as :user
49
50
  User.pbt_params_name.must_be_same_as :user
50
51
  User.pbt_params_name(true).must_be_same_as :user
51
52
  User.pbt_params_name(false).must_be_same_as :user
52
53
  end
53
54
 
54
- it "reports Tag params name as :tag" do
55
- tag = tags(:one)
55
+ it "Tag params name as :tag" do
56
+ tag = tags(:bob_tag)
56
57
  tag.pbt_params_name.must_be_same_as :tag
57
58
  Tag.pbt_params_name.must_be_same_as :tag
58
59
  Tag.pbt_params_name(true).must_be_same_as :tag
59
60
  Tag.pbt_params_name(false).must_be_same_as :tag
60
61
  end
61
62
 
62
- it "reports Phone params name as :phones_attributes" do
63
- phone = phones(:one)
63
+ it "Phone params name as :phones_attributes" do
64
+ phone = phones(:bob_phone)
64
65
  phone.pbt_params_name.must_be_same_as :phones_attributes
65
66
  Phone.pbt_params_name.must_be_same_as :phones_attributes
66
67
  Phone.pbt_params_name(true).must_be_same_as :phones_attributes
67
68
  end
68
69
 
69
- it "reports Phone params name with false as :phone" do
70
- phone = phones(:one)
70
+ it "Phone params name with false as :phone" do
71
+ phone = phones(:bob_phone)
71
72
  phone.pbt_params_name(false).must_be_same_as :phone
72
73
  Phone.pbt_params_name(false).must_be_same_as :phone
73
74
  end
74
75
 
75
- it "reports User belongs to field id symbol as nil" do
76
- user = users(:one)
76
+ it "User belongs to field id symbol as nil" do
77
+ user = users(:bob)
77
78
  user.pbt_id_sym.must_be_nil
78
79
  User.pbt_id_sym.must_be_nil
79
80
  end
80
81
 
81
- it "reports Tag belongs to field id symbol as :tag_id" do
82
- tag = tags(:one)
82
+ it "Tag belongs to field id symbol as :tag_id" do
83
+ tag = tags(:bob_tag)
83
84
  tag.pbt_id_sym.must_be_same_as :user_id
84
85
  Tag.pbt_id_sym.must_be_same_as :user_id
85
86
  end
86
87
 
87
- it "reports Phone belongs to field id symbol as :phoneable_id" do
88
- phone = phones(:one)
88
+ it "Phone belongs to field id symbol as :phoneable_id" do
89
+ phone = phones(:bob_phone)
89
90
  phone.pbt_id_sym.must_be_same_as :phoneable_id
90
91
  Phone.pbt_id_sym.must_be_same_as :phoneable_id
91
92
  end
92
93
 
93
- it "reports User belongs to field type symbol as nil" do
94
- user = users(:one)
94
+ it "User belongs to field type symbol as nil" do
95
+ user = users(:bob)
95
96
  user.pbt_type_sym.must_be_nil
96
97
  User.pbt_type_sym.must_be_nil
97
98
  end
98
99
 
99
- it "reports Tag belongs to field type symbol as nil" do
100
- tag = tags(:one)
100
+ it "Tag belongs to field type symbol as nil" do
101
+ tag = tags(:bob_tag)
101
102
  tag.pbt_type_sym.must_be_nil
102
103
  Tag.pbt_type_sym.must_be_nil
103
104
  end
104
105
 
105
- it "reports Phone belongs to field type symbol as :phoneable_type" do
106
- phone = phones(:one)
106
+ it "Phone belongs to field type symbol as :phoneable_type" do
107
+ phone = phones(:bob_phone)
107
108
  phone.pbt_type_sym.must_be_same_as :phoneable_type
108
109
  Phone.pbt_type_sym.must_be_same_as :phoneable_type
109
110
  end
110
111
 
111
- it "reports User belongs to relation id as nil" do
112
- user = users(:one)
112
+ it "User belongs to id as nil" do
113
+ user = users(:bob)
113
114
  user.pbt_id.must_be_nil
114
115
  end
115
116
 
116
- it "reports Tag belongs to relation id as 1" do
117
- tag = tags(:one)
118
- tag.pbt_id.must_be_same_as 1
117
+ it "Tag belongs to id as user's id" do
118
+ tag = tags(:bob_tag)
119
+ tag.pbt_id.must_be_same_as ActiveRecord::FixtureSet.identify(:bob)
119
120
  end
120
121
 
121
- it "reports Phone belongs to relation id as 1" do
122
- phone = phones(:one)
123
- phone.pbt_id.must_be_same_as 1
122
+ it "Phone belongs to id as user's profile id" do
123
+ phone = phones(:bob_phone)
124
+ phone.pbt_id.must_be_same_as ActiveRecord::FixtureSet.identify(:bob_prof)
124
125
  end
125
126
 
126
- it "reports User belongs to relation type as nil" do
127
- user = users(:one)
127
+ it "User belongs to type as nil" do
128
+ user = users(:bob)
128
129
  user.pbt_type.must_be_nil
129
130
  end
130
131
 
131
- it "reports Tag belongs to relation type as nil" do
132
- tag = tags(:one)
132
+ it "Tag belongs to type as nil" do
133
+ tag = tags(:bob_tag)
133
134
  tag.pbt_type.must_be_nil
134
135
  end
135
136
 
136
- it "reports Phone belongs to relation type as 'User'" do
137
- phone = phones(:one)
138
- phone.pbt_type.must_equal "User"
137
+ it "Phone belongs to type as 'Profile'" do
138
+ phone = phones(:bob_phone)
139
+ phone.pbt_type.must_equal "Profile"
140
+ end
141
+
142
+ it "User parent returns nil" do
143
+ user = users(:bob)
144
+ user.pbt_parent.must_be_nil
145
+ end
146
+
147
+ it "Tag parent returns user instance" do
148
+ user = users(:bob)
149
+ tag = user.tags.build
150
+ tag.pbt_parent.id.must_be_same_as user.id
151
+ end
152
+
153
+ it "Phone parent returns profile" do
154
+ user = users(:bob)
155
+ profile = user.profiles.build
156
+ phone = profile.phones.build
157
+ profile.save
158
+ phone.pbt_parent.id.must_be_same_as profile.id
159
+ end
160
+
161
+ it "Profile parent returns user" do
162
+ user = users(:bob)
163
+ profile = user.profiles.build
164
+ profile.save
165
+ profile.pbt_parent.id.must_be_same_as user.id
139
166
  end
140
167
 
141
168
  end
data/test/test_helper.rb CHANGED
@@ -1,23 +1,29 @@
1
- # Configure Rails Environment
2
1
  ENV["RAILS_ENV"] = "test"
3
2
 
4
3
  require File.expand_path("../../test/dummy/config/environment.rb", __FILE__)
4
+ # require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
+
5
6
  ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../test/dummy/db/migrate", __FILE__)]
6
7
  require 'rails/test_help'
7
8
  require 'minitest/rails'
8
9
  require 'minitest/reporters'
10
+ require 'securerandom'
9
11
 
10
- # Filter out Minitest backtrace while allowing backtrace from other libraries
11
- # to be shown.
12
+ unless Rails.version =~ /^4.[2-9]/
13
+ Rails.backtrace_cleaner.remove_silencers!
14
+ end
12
15
  Minitest.backtrace_filter = Minitest::BacktraceFilter.new
13
16
 
14
- # Load support files
15
17
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
16
18
 
17
- # Load fixtures from the engine
18
19
  if ActiveSupport::TestCase.respond_to?(:fixture_path=)
19
20
  ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
20
21
  end
21
22
 
22
- reporter_options = { color: true }
23
- Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(reporter_options)]
23
+ #reporter_options = { color: true }
24
+ Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
25
+
26
+ class ActiveSupport::TestCase
27
+ ActiveRecord::Base.send(:include, PolyBelongsTo::Dup)
28
+ CleanAttrs = PolyBelongsTo::Pbt::AttrSanitizer
29
+ end