From c08cc393be5cfb80caee9e9bcaef882cfb01ab1a Mon Sep 17 00:00:00 2001 From: sean-dickinson <90267290+sean-dickinson@users.noreply.github.com> Date: Mon, 20 Jan 2025 13:30:10 -0500 Subject: [PATCH 1/3] feat: add unique option --- lib/rom/factory/dsl.rb | 12 +++++++++--- spec/integration/rom/factory_spec.rb | 12 ++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/rom/factory/dsl.rb b/lib/rom/factory/dsl.rb index 9fe1203..be93a00 100644 --- a/lib/rom/factory/dsl.rb +++ b/lib/rom/factory/dsl.rb @@ -13,17 +13,23 @@ module Factory class << self # @api private def fake(*args, **options) - api = fetch_or_store(:faker, *args) do + const, method_name = fetch_or_store(:faker, *args) do *ns, method_name = args const = ns.reduce(::Faker) do |obj, name| obj.const_get(::Dry::Core::Inflector.camelize(name)) end - const.method(method_name) + [const, method_name] end - api.(**options) + is_unique = options.delete(:unique) { false } + + if is_unique + const.unique.public_send(method_name, **options) + else + const.method(method_name).(**options) + end end end diff --git a/spec/integration/rom/factory_spec.rb b/spec/integration/rom/factory_spec.rb index df77548..a21eb3f 100644 --- a/spec/integration/rom/factory_spec.rb +++ b/spec/integration/rom/factory_spec.rb @@ -919,6 +919,18 @@ class Admin < ROM::Struct expect(user.created_at).to_not be(nil) expect(user.created_at).to_not be(nil) end + + it "uses unique when the unique option is true" do + factories.define(:user) do |f| + f.first_name { fake(:name) } + f.last_name { fake(:name, :last_name) } + f.email { fake(:internet, :email, unique: true) } + f.timestamps + end + + emails = 10.times.map { factories.structs[:user].email } + expect(emails.uniq.length).to eq(emails.length) + end end context "custom non integer sequence primary_key" do From f62176f2617a3f6dd8ab7b4eb68f0c4aa102b0ee Mon Sep 17 00:00:00 2001 From: sean-dickinson <90267290+sean-dickinson@users.noreply.github.com> Date: Mon, 20 Jan 2025 13:33:15 -0500 Subject: [PATCH 2/3] docs: update documentation --- docsite/source/index.html.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docsite/source/index.html.md b/docsite/source/index.html.md index c254a17..bdbc13b 100644 --- a/docsite/source/index.html.md +++ b/docsite/source/index.html.md @@ -141,6 +141,14 @@ Factory.define(:user) do |f| end ``` +##### Unique values with fake +Passing the unique: true option will use Faker's [unique](https://github.com/faker-ruby/faker#ensuring-unique-values) feature +```ruby +Factory.define(:user) do |f| + f.email { fake(:internet, :email, unique: true) } +end +``` + #### Dependent attributes Attributes can be based on the values of other attributes: From 0c34dd8714f6197bc16ae01906854fb41a0bcf99 Mon Sep 17 00:00:00 2001 From: sean-dickinson <90267290+sean-dickinson@users.noreply.github.com> Date: Mon, 20 Jan 2025 13:36:54 -0500 Subject: [PATCH 3/3] docs: update api documentation --- lib/rom/factory/dsl.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/rom/factory/dsl.rb b/lib/rom/factory/dsl.rb index be93a00..3bbbfcd 100644 --- a/lib/rom/factory/dsl.rb +++ b/lib/rom/factory/dsl.rb @@ -119,9 +119,13 @@ def timestamps # @example # f.email { fake(:number, :between, from: 10, to: 100) } # + # @example + # f.email { fake(:internet, :email, unique: true) } + # # @param [Symbol] genre The faker API identifier ie. :internet, :product etc. # @param [Symbol] type The value type to generate - # @param [Hash] options Additional arguments + # @param [Hash] options Additional arguments, including unique: true will generate unique values + # # # @overload fake(genre, subgenre, type, **options) # @example