fixture_record 0.1.2.pre.rc → 1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0b73f48614260bc6e1dc1f0ecebcabe4b5bb44779eb3ba807be3942fd8439fc
4
- data.tar.gz: 2af43ba19fd5cde723d3dede76fd21eecd17f92d1ad38693702d14fbd85939fa
3
+ metadata.gz: 725ff327350c904ec886ba1833e976a798e47d564aac8539dec6f2614d86f298
4
+ data.tar.gz: d820511bb21ee20a76c5e12109030e56bde60e3eab69c100248285d59dbb9047
5
5
  SHA512:
6
- metadata.gz: 630ec0346571b9f9a35f2a1f319106e4041372a97e4da36980ac24038b2bc8a6f19fc64d6274813834a46a817d148cfdb3961cb9be5a9ede11a20dc7ba543b23
7
- data.tar.gz: 1c5fa27c4b2bd560bee90fb1461d53a55fc64e380c7df15876b080b17eea315b7dc3290536b3217c758a6929477c2194766e7bb09d363607414f490c3f766d49
6
+ metadata.gz: 14a8530fe32a301bdc5bc4182da67fd8751823d0d43f3d9cd708e23a4c2d99c9b292f77c47043d1ddb79b4eb75f0326382f59425b37d3986e5143328a8ebd046
7
+ data.tar.gz: 90bf683053f43a2e0f7f73acb7b6a260ac2ae6748fbffb197fefc7c6fb5cdf1c7d0e6822baa558cdba82f4fbc7a7ab587882d841566a5833d5bcfb10fe379c80
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # FixtureRecord
2
- When it comes to testing, ActiveRecrod::Fixtures provide a huge performance benefit over FactoryBot but at the expense of setting up the necessary test data. For complex associations and relationships, a large amount of time might be spent simply trying to setup the data. FixtureRecord provides a `to_test_fixture` method that accepts a chain of associations as an argument that allows you to quickly turn a large collection of existing records into test fixtures.
2
+ When it comes to testing, ActiveRecrod::Fixtures provide a huge performance benefit over FactoryBot but at the expense of setting up the necessary test data. For complex associations and relationships, a large amount of time might be spent simply trying to setup the data. FixtureRecord provides a `to_fixture_record` method that accepts a chain of associations as an argument that allows you to quickly turn a large collection of existing records into test fixtures.
3
3
 
4
4
  ## Usage
5
- `to_test_fixture` is a method that will turn the record into a test fixture. By default, the name of the fixture record will be `param_key` of the record's class and the record's id joined with `_`.
5
+ `to_fixture_record` is a method that will turn the record into a test fixture. By default, the name of the fixture record will be `param_key` of the record's class and the record's id joined with `_`.
6
6
 
7
7
  ```ruby
8
8
  user = User.find(1)
9
- user.to_test_fixture
9
+ user.to_fixture_record
10
10
 
11
11
  # creates test/fixtures/users.yml if it does not exists
12
12
  ```
@@ -41,7 +41,7 @@ Let's say an edge case bug has been found with a particular post and it's relate
41
41
 
42
42
  ```ruby
43
43
  edge_case_post = Post.find ...
44
- edge_case_post.to_test_fixture(:author, comments: :user)
44
+ edge_case_post.to_fixture_record(:author, comments: :user)
45
45
  ```
46
46
  This would create a test fixture for the post, its author, all the comments on the post and their respective users. This will also change the `belongs_to` relationships in the yaml files to reflect their respective fixture counterparts. For example, if `Post#12` author is `User#49`,
47
47
  and the post has `Comment#27` the fixture records might look like:
@@ -63,7 +63,7 @@ comment_27:
63
63
  commentable: post_12 (Post)
64
64
  ```
65
65
 
66
- Note that these changes to the `belongs_to` associations is only applicable to records that are part of the associations that are being passed into `to_test_fixture`. So taking the same example as above, `edge_case_post.to_test_fixture` would yield the following:
66
+ Note that these changes to the `belongs_to` associations is only applicable to records that are part of the associations that are being passed into `to_fixture_record`. So taking the same example as above, `edge_case_post.to_fixture_record` would yield the following:
67
67
  ```yaml
68
68
  post_12:
69
69
  author_id: 49
@@ -71,8 +71,8 @@ post_12:
71
71
 
72
72
  Currently, `FixtureRecord` will also not attempt to already existing fixtures to newly created data.
73
73
  ```ruby
74
- User.find(49).to_test_fixture
75
- Post.find(12).to_test_fixture
74
+ User.find(49).to_fixture_record
75
+ Post.find(12).to_fixture_record
76
76
  ```
77
77
  The above would yield fixtures that are not associated to one another.
78
78
  ```yaml
@@ -97,19 +97,19 @@ end
97
97
  ```
98
98
  Because of through association infilling the following 3 lines will produce identical results:
99
99
  ```ruby
100
- user.to_test_fixture(posts: [comments: :users])
100
+ user.to_fixture_record(posts: [comments: :users])
101
101
 
102
- user.to_test_fixture(:posts, :post_comments, :commenting_users)
102
+ user.to_fixture_record(:posts, :post_comments, :commenting_users)
103
103
 
104
104
  user.to_test_fixutre(:commenting_users)
105
105
  ```
106
106
  The reason the third example will infill the other associations is because those associations are required to create a clear path between the originating record and the final records. Without those intermediary associations, the `:commenting_users` would be orphaned from the `user` record.
107
107
 
108
108
  ### FixtureRecord::Naming
109
- There might be instances where a record was used for a particular test fixture and you want to use this same record again for a different test case but want to keep the data isolated. `FixtureRecord::Naming` (automatically included with FixtureRecord) provides`fixture_record_prefix` and `fixture_record_suffix`. These values are propagated to the associated records when calling `to_test_fixture`.
109
+ There might be instances where a record was used for a particular test fixture and you want to use this same record again for a different test case but want to keep the data isolated. `FixtureRecord::Naming` (automatically included with FixtureRecord) provides`fixture_record_prefix` and `fixture_record_suffix`. These values are propagated to the associated records when calling `to_fixture_record`.
110
110
  ```ruby
111
111
  user.test_fixture_prefix = :foo
112
- user.to_test_fixture(:posts)
112
+ user.to_fixture_record(:posts)
113
113
 
114
114
  # users.yml
115
115
 
@@ -158,7 +158,7 @@ end
158
158
  FixtureRecord.configure do |config|
159
159
  ...
160
160
 
161
- config.sanitize_pattern /created_at$|updated_at$/, with: :simple_timestamp
161
+ config.sanitize_column_regex /created_at$|updated_at$/, with: :simple_timestamp
162
162
 
163
163
  ...
164
164
  end
@@ -186,13 +186,13 @@ end
186
186
  FixtureRecord.registry.register_sanitizer MyReverseSanitizer, :reverse
187
187
  ```
188
188
  ### Assiging the Sanitizer to a Pattern
189
- In the fixture record initializer, use `#sanitize_pattern` to assign the registered sanitizer to a regex pattern. In the following example code, any column that matches `email` would be sent through the reverse sanitizer, this would include `email`, `user_email`, `primary_email`, etc.
189
+ In the fixture record initializer, use `#sanitize_column_regex` to assign the registered sanitizer to a regex pattern. In the following example code, any column that matches `email` would be sent through the reverse sanitizer, this would include `email`, `user_email`, `primary_email`, etc.
190
190
  ```ruby
191
191
  # fixture_record/initializer.rb
192
192
  FixtureRecord.configure do |config|
193
193
  ...
194
194
 
195
- config.sanitize_pattern /email/, with: :reverse
195
+ config.sanitize_column_regex /email/, with: :reverse
196
196
 
197
197
  ...
198
198
  end
@@ -200,7 +200,7 @@ end
200
200
 
201
201
  The pattern that is used for comparison is inclusive of the class name as well. So if you need a sanitizer to be scoped to a specific class you can use the class name in the regex pattern. Taking the example above:
202
202
  ```ruby
203
- config.sanitize_pattern /User.email/, with: :reverse
203
+ config.sanitize_column_regex /User.email/, with: :reverse
204
204
  ```
205
205
  Now columns on other classes that include `email` in their name won't be passed to the sanitizer. Also keep in mind the mechanism being used here is basic regex pattern matching, so `User.primary_email` wouldn't match in this case and would not be sent to the sanitizer.
206
206
 
@@ -52,7 +52,7 @@ module FixtureRecord
52
52
  built_records.each do |record|
53
53
  record.fixture_record_prefix = @source_record.fixture_record_prefix
54
54
  record.fixture_record_suffix = @source_record.fixture_record_suffix
55
- record.to_test_fixture(*@next_associations)
55
+ record.to_fixture_record(*@next_associations)
56
56
  end
57
57
  end
58
58
 
@@ -2,7 +2,7 @@ module FixtureRecord
2
2
  module BelongsToUpdation
3
3
  extend ActiveSupport::Concern
4
4
 
5
- def update_belongs_to_test_fixture_associations
5
+ def update_belongs_to_fixture_record_associations
6
6
  self.class.reflect_on_all_associations(:belongs_to).each do |assoc|
7
7
  klass_name = assoc.options[:polymorphic] ? send(assoc.foreign_type) : assoc.class_name
8
8
  next unless klass_name.nil? || FixtureRecord.cache.contains_class?(klass_name)
@@ -24,9 +24,9 @@ module FixtureRecord
24
24
 
25
25
  def prepare!
26
26
  self.values
27
- .each(&:filter_attributes_for_test_fixture)
28
- .each(&:sanitize_attributes_for_test_fixture)
29
- .each(&:update_belongs_to_test_fixture_associations)
27
+ .each(&:filter_attributes_for_fxiture_record)
28
+ .each(&:sanitize_attributes_for_fxiture_record)
29
+ .each(&:update_belongs_to_fixture_record_associations)
30
30
  end
31
31
  end
32
32
  end
@@ -14,14 +14,18 @@ class FixtureRecord::Data < Hash
14
14
  end
15
15
 
16
16
  def write!
17
- FileUtils.mkdir_p(Rails.root.join('test/fixtures'))
17
+ FileUtils.mkdir_p(FixtureRecord.base_path)
18
18
  self.each do |klass, data|
19
19
  File.open(fixture_path_for(klass), 'w') { |f| f.write data.to_yaml }
20
20
  end
21
21
  end
22
22
 
23
23
  def fixture_path_for(klass)
24
- Rails.root.join('test/fixtures', klass.table_name + '.yml')
24
+ if FixtureRecord.base_path.is_a?(String)
25
+ [FixtureRecord.base_path, klass.table_name + '.yml'].join('/')
26
+ else
27
+ FixtureRecord.base_path.join(klass.table_name + '.yml')
28
+ end
25
29
  end
26
30
 
27
31
  def merge_record(record)
@@ -1,6 +1,6 @@
1
1
  module FixtureRecord
2
2
  module FilterableAttributes
3
- def filter_attributes_for_test_fixture
3
+ def filter_attributes_for_fxiture_record
4
4
  self._fixture_record_attributes = FilteredAttributes.new(self).cast
5
5
  end
6
6
 
@@ -11,7 +11,7 @@ module FixtureRecord
11
11
  end
12
12
 
13
13
  def test_fixture_name
14
- FixtureRecord.naming.call(self)
14
+ FixtureRecord.name_handler.call(self)
15
15
  end
16
16
  end
17
17
  end
@@ -1,7 +1,7 @@
1
1
  module FixtureRecord::Sanitizable
2
2
  extend ActiveSupport::Concern
3
3
 
4
- def sanitize_attributes_for_test_fixture
4
+ def sanitize_attributes_for_fxiture_record
5
5
  _fixture_record_attributes.each do |attr, value|
6
6
  registry_key = [self.class.name, attr.to_s].join('.')
7
7
  _fixture_record_attributes[attr] = sanitize_value_for_test_fixture(registry_key, value)
@@ -1,3 +1,3 @@
1
1
  module FixtureRecord
2
- VERSION = "0.1.2-rc"
2
+ VERSION = "1.0"
3
3
  end
@@ -7,7 +7,6 @@ require "fixture_record/association_traversal"
7
7
  require "fixture_record/filterable_attributes"
8
8
  require "fixture_record/belongs_to_updation"
9
9
  require "fixture_record/sanitizable"
10
- require "fixture_record/configuration"
11
10
 
12
11
  module FixtureRecord
13
12
  extend ActiveSupport::Concern
@@ -15,7 +14,9 @@ module FixtureRecord
15
14
  :cache,
16
15
  :data
17
16
 
18
- mattr_accessor :naming, default: FixtureRecord::Naming::Base.new
17
+ mattr_accessor :name_handler, default: FixtureRecord::Naming::Base.new
18
+ mattr_accessor :sanitizers, default: []
19
+ mattr_accessor :base_path, default: -> { Rails.root.join('test/fixtures') }
19
20
 
20
21
  included do
21
22
  attr_accessor :_fixture_record_attributes
@@ -29,7 +30,7 @@ module FixtureRecord
29
30
 
30
31
  Sanitizer = FixtureRecord::Sanitizable::Base
31
32
 
32
- def to_test_fixture(*associations)
33
+ def to_fixture_record(*associations)
33
34
  FixtureRecord.lock!(self)
34
35
  FixtureRecord.cache[self.test_fixture_name] ||= self
35
36
  traverse_fixture_record_associations(*associations)
@@ -41,13 +42,23 @@ module FixtureRecord
41
42
 
42
43
  class << self
43
44
  def configure
44
- yield config
45
+ yield self
45
46
  end
46
47
 
47
- def config
48
- @@config ||= Configuration.new
48
+ def base_path
49
+ @@base_path.is_a?(String) ? @@base_path : @@base_path.call
49
50
  end
50
51
 
52
+ def name_handler=(proc_or_klass)
53
+ @@name_handler = proc_or_klass.is_a?(Class) ? proc_or_klass.new : proc_or_klass
54
+ end
55
+
56
+ def sanitize_column_regex(col_regex, with:)
57
+ registry_name_or_klass = with
58
+ klass = registry_name_or_klass.is_a?(Symbol) ? FixtureRecord.registry[registry_name_or_klass] : registry_name_or_klass
59
+ klass_instance = klass.is_a?(Class) ? klass.new : klass
60
+ FixtureRecord.registry.sanitize_pattern col_regex, with: klass_instance
61
+ end
51
62
 
52
63
  def lock!(owner)
53
64
  return if locked?
@@ -5,17 +5,7 @@ module FixtureRecord::Generators
5
5
  source_root File.expand_path("templates", __dir__)
6
6
 
7
7
  def create_initializer
8
- application(nil, env: :development) do
9
- <<-TXT
10
- # By default, fixture_record will only inject itself in the development environment.
11
- # If you want it available in `test` or `production` (or other environments), please add
12
- # this require line to those environment ruby files. Alternatively, if you want it to
13
- # always be loaded, you can relocate the generated `fixture_record/initializer.rb` to
14
- # `app/config/initializers/fixture_record.rb` or require this file in `config/application.rb`.
15
- require Rails.root.join('fixture_record', 'initializer.rb')\n
16
- TXT
17
- end
18
- template "initializer.rb", Rails.root.join("fixture_record/initializer.rb")
8
+ template "initializer.rb", Rails.root.join("config/initializers/fixture_record.rb")
19
9
  end
20
10
  end
21
11
  end
@@ -1,16 +1,23 @@
1
- FixtureRecord.configure do |config|
2
- # To customize how fixtures are named, provide a class the responds to #call or a Proc.
3
- # The naming object will receive the record and should return a String
4
- # config.name_records_with = FixtureRecord::Naming::Base
1
+ if Rails.env.development?
2
+ FixtureRecord.configure do |config|
3
+ # To customize how fixtures are named, provide a class the responds to #call or a Proc.
4
+ # The name handler object will receive the record and should return a String
5
+ # config.name_handler = FixtureRecord::Naming::Base
5
6
 
6
- # Create and register custom sanitizers to format, sanitiize, obfuscate, etc. the data before it is
7
- # turned into a test fixture. Regex patterns are used to determine if a column should be passed to a
8
- # sanitizer. The regex pattern that is tested is Classname.column_name - so if a sanitizer needs to be
9
- # scoped to a specific class only, simply add the classname to the pattern, for example /User.phone_number/
10
- # would sanitize the phone_number field for a User but not the phone_number field for a Customer.
11
- # If there are other timestamp columns being used throughout your application, you can added them to this list.
12
- config.sanitize_pattern /created_at$|updated_at$/, with: :simple_timestamp
7
+ # base_path represents the base folder that FixureRecord will search for existing yml files
8
+ # to merge new fixture data with and it serves as the path for where FixtureRecord will output the
9
+ # new yml files as needed. To override, provide a String, Pathname object, or Proc/ambda to be evaluated at runtime
10
+ # config.base_path = -> { Rails.root.join('test/fixtures') }
13
11
 
14
- # Inject FixtureRecord concern into ActiveRecord
15
- ActiveRecord::Base.include(FixtureRecord)
12
+ # Create and register custom sanitizers to format, sanitiize, obfuscate, etc. the data before it is
13
+ # turned into a test fixture. Regex patterns are used to determine if a column should be passed to a
14
+ # sanitizer. The regex pattern that is tested is Classname.column_name - so if a sanitizer needs to be
15
+ # scoped to a specific class only, simply add the classname to the pattern, for example /User.phone_number/
16
+ # would sanitize the phone_number field for a User but not the phone_number field for a Customer.
17
+ # If there are other timestamp columns being used throughout your application, you can added them to this list.
18
+ config.sanitize_column_regex /created_at$|updated_at$/, with: :simple_timestamp
19
+
20
+ # Inject FixtureRecord concern into ActiveRecord
21
+ ActiveRecord::Base.include(FixtureRecord)
22
+ end
16
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fixture_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.pre.rc
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Schrag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-31 00:00:00.000000000 Z
11
+ date: 2024-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -39,7 +39,6 @@ files:
39
39
  - lib/fixture_record/association_traversal.rb
40
40
  - lib/fixture_record/belongs_to_updation.rb
41
41
  - lib/fixture_record/cache.rb
42
- - lib/fixture_record/configuration.rb
43
42
  - lib/fixture_record/data.rb
44
43
  - lib/fixture_record/filterable_attributes.rb
45
44
  - lib/fixture_record/naming.rb
@@ -1,14 +0,0 @@
1
- module FixtureRecord
2
- class Configuration
3
- def name_records_with(proc_or_klass)
4
- FixtureRecord.naming = proc_or_klass.is_a?(Class) ? proc_or_klass.new : proc_or_klass
5
- end
6
-
7
- def sanitize_pattern(pattern, with:)
8
- registry_name_or_klass = with
9
- klass = registry_name_or_klass.is_a?(Symbol) ? FixtureRecord.registry[registry_name_or_klass] : registry_name_or_klass
10
- klass_instance = klass.is_a?(Class) ? klass.new : klass
11
- FixtureRecord.registry.sanitize_pattern pattern, with: klass_instance
12
- end
13
- end
14
- end