fixture_record 0.1.2.pre.rc → 1.0

Sign up to get free protection for your applications and to get access to all the features.
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