standard_procedure_fabrik 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +59 -59
- data/checksums/standard_procedure_fabrik-0.1.1.gem.sha512 +1 -0
- data/checksums/standard_procedure_fabrik-0.1.2.gem.sha512 +1 -0
- data/lib/fabrik/database.rb +7 -2
- data/lib/fabrik/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2742aab097f1a8977498b4b654829b4a6b9d54e98320a4e56a2c1419aeeb53ad
|
4
|
+
data.tar.gz: 34394ab7faa6707a2afcd4fa03d24fedc5ae84471c0f461b37ac70de5ef51ca5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c049dacfdaa1a044e70510216f244d3008e441f3cf950439e7862c7ed165a915e0f6b42787a3afdcca4d50be3bfd1408668308c6cab176196ffc26cad5053481
|
7
|
+
data.tar.gz: e814649e75c6cd9ea0a69d6705205b62ef91bc34b4bf545d093c616924bebe2ee84bfea09df4d0298dc294c759d44c7f4fdb7f6ee752c2a9b568e0dd7bcbdb04
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,66 +1,66 @@
|
|
1
1
|
# Fabrik
|
2
2
|
|
3
|
-
## Simplify your database seeds and test fixtures.
|
3
|
+
## Simplify your database seeds and test fixtures.
|
4
4
|
|
5
|
-
Fabrik is a factory for your ActiveRecord models.
|
5
|
+
Fabrik is a factory for your ActiveRecord models.
|
6
6
|
|
7
|
-
It's designed to be used in both your test cases and in your database seeds.
|
7
|
+
It's designed to be used in both your test cases and in your database seeds.
|
8
|
+
|
9
|
+
And I think the API is pretty nice and the code is pretty simple.
|
8
10
|
|
9
|
-
And I think the API is pretty nice and the code is pretty simple.
|
10
|
-
|
11
11
|
## Database seeds
|
12
12
|
|
13
|
-
Database seeds are great.
|
13
|
+
Database seeds are great.
|
14
14
|
|
15
|
-
Screwed up your development database? Just drop it, rebuild it and load in your starting data.
|
15
|
+
Screwed up your development database? Just drop it, rebuild it and load in your starting data.
|
16
16
|
|
17
|
-
Added a new feature and want to show people what it looks like? Add some new records into your seeds, run them, then you've got a nice set of demo data, all pre-loaded.
|
17
|
+
Added a new feature and want to show people what it looks like? Add some new records into your seeds, run them, then you've got a nice set of demo data, all pre-loaded.
|
18
18
|
|
19
|
-
For this to work, seeds need to be idempotent. When you run your seeds against a database with existing data, it should only insert the new stuff, leaving the old untouched.
|
19
|
+
For this to work, seeds need to be idempotent. When you run your seeds against a database with existing data, it should only insert the new stuff, leaving the old untouched.
|
20
20
|
|
21
|
-
Fabrik does this.
|
21
|
+
Fabrik does this.
|
22
22
|
|
23
23
|
## Specs and tests
|
24
24
|
|
25
|
-
I love RSpec. Other test frameworks (cough; minitest) are available.
|
25
|
+
I love RSpec. Other test frameworks (cough; minitest) are available.
|
26
26
|
|
27
|
-
And if you're writing Rails apps, your tests or specs are, most likely, going to be using ActiveRecord models which end up hitting the database. That's just how Rails works, no matter what the isolationists say.
|
27
|
+
And if you're writing Rails apps, your tests or specs are, most likely, going to be using ActiveRecord models which end up hitting the database. That's just how Rails works, no matter what the isolationists say.
|
28
28
|
|
29
|
-
So, when setting up your test fixtures, you want to set up the smallest amount of data to prove your case.
|
29
|
+
So, when setting up your test fixtures, you want to set up the smallest amount of data to prove your case.
|
30
30
|
|
31
|
-
And, because tests are documentation, you want that setup to be there, next to the test code, so anyone reading it can understand how everything hangs together.
|
31
|
+
And, because tests are documentation, you want that setup to be there, next to the test code, so anyone reading it can understand how everything hangs together.
|
32
32
|
|
33
|
-
Fabrik does this.
|
33
|
+
Fabrik does this.
|
34
34
|
|
35
35
|
## Configuration
|
36
36
|
|
37
|
-
Fabrik allows you to configure three aspects of how you create your objects.
|
37
|
+
Fabrik allows you to configure three aspects of how you create your objects.
|
38
38
|
|
39
39
|
### Default attributes
|
40
40
|
|
41
|
-
When you're writing a spec, you probably only care about one aspect of the model involved.
|
41
|
+
When you're writing a spec, you probably only care about one aspect of the model involved.
|
42
42
|
|
43
|
-
So Fabrik allows you to set default attributes; then when you're creating a model, you can specify the ones you're interested in and ignore all the rest.
|
43
|
+
So Fabrik allows you to set default attributes; then when you're creating a model, you can specify the ones you're interested in and ignore all the rest.
|
44
44
|
|
45
45
|
```ruby
|
46
46
|
db.configure do
|
47
47
|
with Person do
|
48
|
-
defaults first_name: -> { "Alice" }, last_name: -> { Faker::Name.last_name }, age: -> { 33 }
|
48
|
+
defaults first_name: ->(db) { "Alice" }, last_name: ->(db) { Faker::Name.last_name }, age: ->(db) { 33 }
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
@alice = db.people.create last_name: "Anteater"
|
53
53
|
|
54
|
-
puts @alice.first_name # => Alice
|
55
|
-
puts @alice.last_name # => Anteater
|
54
|
+
puts @alice.first_name # => Alice
|
55
|
+
puts @alice.last_name # => Anteater
|
56
56
|
puts @alice.age # => 33
|
57
57
|
```
|
58
58
|
|
59
59
|
### Uniqueness
|
60
60
|
|
61
|
-
When you've got a database packed with existing data, you don't want your seeds to fail because of a uniqueness constraint. Or your tests to fail because suddenly they're finding two records when they were only expecting one.
|
61
|
+
When you've got a database packed with existing data, you don't want your seeds to fail because of a uniqueness constraint. Or your tests to fail because suddenly they're finding two records when they were only expecting one.
|
62
62
|
|
63
|
-
So Fabrik lets you define what makes a model unique. Then when you create it, it checks for an existing record first and only creates a new one if the original is not found.
|
63
|
+
So Fabrik lets you define what makes a model unique. Then when you create it, it checks for an existing record first and only creates a new one if the original is not found.
|
64
64
|
|
65
65
|
```ruby
|
66
66
|
db.configure do
|
@@ -71,25 +71,25 @@ end
|
|
71
71
|
@alice = db.people.create first_name: "Alice", last_name: "Aardvark", email: "alice@example.com"
|
72
72
|
@zac = db.people.create first_name: "Zac", last_name: "Zebra", email: "alice@example.com"
|
73
73
|
|
74
|
-
@alice == @zac # => true
|
74
|
+
@alice == @zac # => true
|
75
75
|
puts @zac.first_name # => Alice
|
76
76
|
```
|
77
77
|
|
78
78
|
### Special processing
|
79
79
|
|
80
|
-
Some models are special. They can't live on their own. Their invariants won't let them. Maybe a `Company` cannot exist without a `CEO`. While your main application logic can ensure that's always the case, when you're writing your tests, it becomes a pain specifying it over and over again.
|
80
|
+
Some models are special. They can't live on their own. Their invariants won't let them. Maybe a `Company` cannot exist without a `CEO`. While your main application logic can ensure that's always the case, when you're writing your tests, it becomes a pain specifying it over and over again.
|
81
81
|
|
82
|
-
So Fabrik lets you define specific processing that happens after a new record is created.
|
82
|
+
So Fabrik lets you define specific processing that happens after a new record is created.
|
83
83
|
|
84
84
|
```ruby
|
85
85
|
db.configure do
|
86
|
-
with Company do
|
86
|
+
with Company do
|
87
87
|
defaults name: -> { Faker::Company.name }
|
88
88
|
after_create do |company, db|
|
89
89
|
db.employees.create company: company, role: "CEO"
|
90
90
|
end
|
91
|
-
end
|
92
|
-
with Employee do
|
91
|
+
end
|
92
|
+
with Employee do
|
93
93
|
defaults first_name: -> { Faker::Name.first_name }, last_name: -> { Faker::Name.last_name }, role: -> { "Cleaner" }
|
94
94
|
end
|
95
95
|
end
|
@@ -99,9 +99,9 @@ puts Company.find_by(name: "MegaCorp").employees.size # => 1
|
|
99
99
|
|
100
100
|
## References
|
101
101
|
|
102
|
-
You've created a load of models. And you need to reference them to create more models. You could search for them by hand, but that's for chumps.
|
102
|
+
You've created a load of models. And you need to reference them to create more models. You could search for them by hand, but that's for chumps.
|
103
103
|
|
104
|
-
So Fabrik let's you give your models a label. And then refer back to that model using the label.
|
104
|
+
So Fabrik let's you give your models a label. And then refer back to that model using the label.
|
105
105
|
|
106
106
|
```ruby
|
107
107
|
db.people.create :alice, first_name: "Alice"
|
@@ -113,7 +113,7 @@ puts db.people[:alice] # => Alice
|
|
113
113
|
|
114
114
|
You've got a load of models in your application. Fabrik allows you to configure some rules for each one. But not all of them need special processing. Why waste your time telling Fabrik about all these classes when you've got more important things to do?
|
115
115
|
|
116
|
-
So Fabrik takes a guess at any names you give it and tries its best to figure out which class you mean.
|
116
|
+
So Fabrik takes a guess at any names you give it and tries its best to figure out which class you mean.
|
117
117
|
|
118
118
|
```ruby
|
119
119
|
class Intergalactic::Spaceship < ApplicationRecord
|
@@ -125,18 +125,18 @@ db.intergalactic_spaceships.create :ufo
|
|
125
125
|
puts Intergalactic::Spaceship.count # => 1
|
126
126
|
```
|
127
127
|
|
128
|
-
Or maybe you're writing a Rails engine and all your classes are namespaced. Typing long names is so _boring_.
|
128
|
+
Or maybe you're writing a Rails engine and all your classes are namespaced. Typing long names is so _boring_.
|
129
129
|
|
130
|
-
So Fabrik lets you register an alternative name for your classes.
|
130
|
+
So Fabrik lets you register an alternative name for your classes.
|
131
131
|
|
132
132
|
```ruby
|
133
|
-
db.configure do
|
134
|
-
with MyAccountsPackageEngine::Invoice, as: :invoice do
|
135
|
-
defaults due_date: -> { 7.days.from_now }
|
133
|
+
db.configure do
|
134
|
+
with MyAccountsPackageEngine::Invoice, as: :invoice do
|
135
|
+
defaults due_date: ->(db) { 7.days.from_now }
|
136
136
|
end
|
137
|
-
end
|
137
|
+
end
|
138
138
|
|
139
|
-
db.invoices.create :overdue_invoice, due_date: 1.day.ago
|
139
|
+
db.invoices.create :overdue_invoice, due_date: 1.day.ago
|
140
140
|
```
|
141
141
|
|
142
142
|
## Installation
|
@@ -147,59 +147,59 @@ Add `standard_procedure_fabrik` to your `Gemfile`
|
|
147
147
|
bundle add standard_procedure_fabrik
|
148
148
|
```
|
149
149
|
|
150
|
-
If you're only using it for tests, add it to your `test` group. If you're using it for seeds, add it with all your other gems. While you're at it, add [Faker](https://github.com/faker-ruby/faker) as well - at the very least, it will probably make you smile with some of the stuff it generates for your test data.
|
150
|
+
If you're only using it for tests, add it to your `test` group. If you're using it for seeds, add it with all your other gems. While you're at it, add [Faker](https://github.com/faker-ruby/faker) as well - at the very least, it will probably make you smile with some of the stuff it generates for your test data.
|
151
151
|
|
152
152
|
## Usage
|
153
153
|
|
154
154
|
### Localised (for tests)
|
155
155
|
|
156
|
-
Create an instance of a [Fabrik::Database](/lib/fabrik/database.rb), configure it and use it.
|
156
|
+
Create an instance of a [Fabrik::Database](/lib/fabrik/database.rb), configure it and use it.
|
157
157
|
|
158
158
|
```ruby
|
159
|
-
db = Fabrik::Database.new
|
160
|
-
db.configure do
|
161
|
-
with Person do
|
162
|
-
defaults first_name: -> { Faker::Name.first_name }, last_name: -> { Faker::Name.last_name }, email: -> { Faker::Internet.email }
|
159
|
+
db = Fabrik::Database.new
|
160
|
+
db.configure do
|
161
|
+
with Person do
|
162
|
+
defaults first_name: ->(db) { Faker::Name.first_name }, last_name: ->(db) { Faker::Name.last_name }, email: ->(db) { Faker::Internet.email }
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
166
166
|
db.people.create :alice, first_name: "Alice"
|
167
167
|
```
|
168
168
|
|
169
|
-
In an RSpec:
|
169
|
+
In an RSpec:
|
170
170
|
|
171
171
|
```ruby
|
172
|
-
RSpec.describe "Whatever" do
|
172
|
+
RSpec.describe "Whatever" do
|
173
173
|
let(:db) { Fabrik::Database.new }
|
174
|
-
before do
|
175
|
-
db.configure do
|
174
|
+
before do
|
175
|
+
db.configure do
|
176
176
|
# ... whatever
|
177
177
|
end
|
178
178
|
end
|
179
179
|
end
|
180
180
|
```
|
181
181
|
|
182
|
-
In a minitest ... I don't know, I've not used minitest in years but I'm sure it's easy enough.
|
182
|
+
In a minitest ... I don't know, I've not used minitest in years but I'm sure it's easy enough.
|
183
183
|
|
184
184
|
### Global (for seeds and generally creating stuff)
|
185
185
|
|
186
|
-
Configure the global `Fabrik::Database`, then use it.
|
186
|
+
Configure the global `Fabrik::Database`, then use it.
|
187
187
|
|
188
188
|
```ruby
|
189
|
-
Fabrik.configure do
|
190
|
-
with Person do
|
191
|
-
defaults first_name: -> { Faker::Name.first_name }, last_name: -> { Faker::Name.last_name }, email: -> { Faker::Internet.email }
|
189
|
+
Fabrik.configure do
|
190
|
+
with Person do
|
191
|
+
defaults first_name: ->(db) { Faker::Name.first_name }, last_name: ->(db) { Faker::Name.last_name }, email: ->(db) { Faker::Internet.email }
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
195
|
Fabrik.db.people.create :alice, first_name: "Alice"
|
196
196
|
```
|
197
197
|
|
198
|
-
Watch out - because this uses a global instance, it's not thread-safe. That's not an issue if you're just using it for database seeds or in most test runners(single-threaded or parallelised with multiple processes). But it *might* cause problems if you're using threads to parallelise your tests, or you're reconfiguring while your application is running.
|
198
|
+
Watch out - because this uses a global instance, it's not thread-safe. That's not an issue if you're just using it for database seeds or in most test runners(single-threaded or parallelised with multiple processes). But it *might* cause problems if you're using threads to parallelise your tests, or you're reconfiguring while your application is running.
|
199
199
|
|
200
200
|
## Development
|
201
201
|
|
202
|
-
Important note: this gem is not under the MIT Licence - it's under the [LGPL](/LICENSE). This may or may not make it suitable for your use. I have reasons for this, which don't belong in a README. But the net result is, this library is open-source, it's free software and you can license *your own* code any way you want. But if you change *this code*, you have to publish those changes under the same rules.
|
202
|
+
Important note: this gem is not under the MIT Licence - it's under the [LGPL](/LICENSE). This may or may not make it suitable for your use. I have reasons for this, which don't belong in a README. But the net result is, this library is open-source, it's free software and you can license *your own* code any way you want. But if you change *this code*, you have to publish those changes under the same rules.
|
203
203
|
|
204
204
|
So, fork the repo, bundle install, add RSpecs for the changes you want to make and `rake spec` to run the tests. Then send me a pull request. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
205
205
|
|
@@ -212,8 +212,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/standa
|
|
212
212
|
|
213
213
|
### Code of Conduct
|
214
214
|
|
215
|
-
Don't be a dick.
|
215
|
+
Don't be a dick.
|
216
216
|
|
217
|
-
If you think you're being reasonable but most people think you're being a dick, then you're not being reasonable, you're actually being a dick.
|
217
|
+
If you think you're being reasonable but most people think you're being a dick, then you're not being reasonable, you're actually being a dick.
|
218
218
|
|
219
|
-
We're not computers - we're human beings. And human beings are soft, squishy and emotional. That's just how it is.
|
219
|
+
We're not computers - we're human beings. And human beings are soft, squishy and emotional. That's just how it is.
|
@@ -0,0 +1 @@
|
|
1
|
+
7946813b20b9d8a66c9fa421ead1466b55cd64170be817bd9f49c23aa69e9c9390a5d3b161640b0a5058669a0435c8431ca33a448c43ac42ae2f1c6cbaffc4e3
|
@@ -0,0 +1 @@
|
|
1
|
+
939adbdd3a1922e7dc52f5125c9511bc6eb0bdc77cde5a54464b7f56506b6bf309828aac8df062d0ac8da29bcce5a0ee66affc56b20c0112df52aaa0764f736b
|
data/lib/fabrik/database.rb
CHANGED
@@ -91,7 +91,12 @@ module Fabrik
|
|
91
91
|
|
92
92
|
private def default_attributes = @blueprint.default_attributes
|
93
93
|
|
94
|
-
private def find_or_create_record(attributes)
|
94
|
+
private def find_or_create_record(attributes)
|
95
|
+
attributes = attributes_with_defaults(attributes)
|
96
|
+
find_record(attributes) || create_record(attributes)
|
97
|
+
end
|
98
|
+
|
99
|
+
private def find_record(attributes) = attributes.slice(*search_keys).empty? ? nil : klass.find_by(**attributes.slice(*search_keys))
|
95
100
|
|
96
101
|
private def create_record(attributes)
|
97
102
|
klass.create(**attributes_with_defaults(attributes)).tap do |record|
|
@@ -101,7 +106,7 @@ module Fabrik
|
|
101
106
|
|
102
107
|
private def attributes_with_defaults attributes
|
103
108
|
attributes_to_generate = default_attributes.keys - attributes.keys
|
104
|
-
attributes_to_generate.each_with_object({}) { |name, generated_attributes| generated_attributes[name] = default_attributes[name].call }.merge(attributes)
|
109
|
+
attributes_to_generate.each_with_object({}) { |name, generated_attributes| generated_attributes[name] = default_attributes[name].call(@db) }.merge(attributes)
|
105
110
|
end
|
106
111
|
end
|
107
112
|
end
|
data/lib/fabrik/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: standard_procedure_fabrik
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahoul Baruah
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -52,6 +52,8 @@ files:
|
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
54
|
- checksums/standard_procedure_fabrik-0.1.0.gem.sha512
|
55
|
+
- checksums/standard_procedure_fabrik-0.1.1.gem.sha512
|
56
|
+
- checksums/standard_procedure_fabrik-0.1.2.gem.sha512
|
55
57
|
- lib/fabrik.rb
|
56
58
|
- lib/fabrik/database.rb
|
57
59
|
- lib/fabrik/version.rb
|