faker_maker 3.0.0 → 4.0.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 +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/.gitignore +4 -0
- data/.rubocop.yml +1 -0
- data/Gemfile +2 -0
- data/MIGRATION_NOTES.md +47 -0
- data/TODO.md +16 -0
- data/faker_maker.gemspec +1 -1
- data/hack/nested.rb +21 -0
- data/lib/faker_maker/attribute.rb +10 -1
- data/lib/faker_maker/base.rb +2 -2
- data/lib/faker_maker/definition_proxy.rb +2 -2
- data/lib/faker_maker/factory.rb +122 -34
- data/lib/faker_maker/version.rb +1 -1
- data/usefakermaker.com/pages/about/index.md +20 -0
- data/usefakermaker.com.site/.gitignore +2 -0
- data/usefakermaker.com.site/site/assets/favicons/android-chrome-192x192.png +0 -0
- data/usefakermaker.com.site/site/assets/favicons/android-chrome-512x512.png +0 -0
- data/usefakermaker.com.site/site/assets/favicons/apple-touch-icon.png +0 -0
- data/usefakermaker.com.site/site/assets/favicons/favicon-16x16.png +0 -0
- data/usefakermaker.com.site/site/assets/favicons/favicon-32x32.png +0 -0
- data/usefakermaker.com.site/site/assets/favicons/favicon.ico +0 -0
- data/usefakermaker.com.site/site/assets/favicons/site.webmanifest +19 -0
- data/usefakermaker.com.site/site/assets/robots.txt +2 -0
- data/usefakermaker.com.site/site/assets/styles.css +351 -0
- data/{usefakermaker.com/docs/contributing/index.md → usefakermaker.com.site/site/src/docs/contributing/index.page.md} +1 -5
- data/{usefakermaker.com/docs/installing/index.md → usefakermaker.com.site/site/src/docs/installing/index.page.md} +1 -5
- data/{usefakermaker.com/docs/usage/arrays/index.md → usefakermaker.com.site/site/src/docs/usage/arrays/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/building-instances/index.md → usefakermaker.com.site/site/src/docs/usage/building-instances/index.page.md} +6 -7
- data/{usefakermaker.com/docs/usage/chaos/index.md → usefakermaker.com.site/site/src/docs/usage/chaos/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/destroying-factories/index.md → usefakermaker.com.site/site/src/docs/usage/destroying-factories/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/embedding-factories/index.md → usefakermaker.com.site/site/src/docs/usage/embedding-factories/index.page.md} +41 -7
- data/{usefakermaker.com/docs/usage/getting-started/index.md → usefakermaker.com.site/site/src/docs/usage/getting-started/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/history-logging/index.md → usefakermaker.com.site/site/src/docs/usage/history-logging/index.page.md} +1 -6
- data/{usefakermaker.com/docs/usage/inheritance/index.md → usefakermaker.com.site/site/src/docs/usage/inheritance/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/json-field-names/index.md → usefakermaker.com.site/site/src/docs/usage/json-field-names/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/lifecycle-hooks/index.md → usefakermaker.com.site/site/src/docs/usage/lifecycle-hooks/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/managing-dependencies/index.md → usefakermaker.com.site/site/src/docs/usage/managing-dependencies/index.page.md} +1 -4
- data/{usefakermaker.com/docs/usage/omitting-fields/index.md → usefakermaker.com.site/site/src/docs/usage/omitting-fields/index.page.md} +1 -4
- data/{usefakermaker.com/pages/index.markdown → usefakermaker.com.site/site/src/index.page.md} +9 -19
- data/usefakermaker.com.site/site/templates/_nav.html.erb +27 -0
- data/usefakermaker.com.site/site/templates/layout.html.erb +46 -0
- data/usefakermaker.com.site/site/templates/page.html.erb +3 -0
- metadata +39 -51
- data/usefakermaker.com/.gitignore +0 -5
- data/usefakermaker.com/404.html +0 -25
- data/usefakermaker.com/Gemfile +0 -39
- data/usefakermaker.com/README.md +0 -5
- data/usefakermaker.com/_config.yml +0 -299
- data/usefakermaker.com/_config.yml.orig +0 -55
- data/usefakermaker.com/_data/navigation.yml +0 -51
- data/usefakermaker.com/_data/ui-text.yml +0 -2132
- data/usefakermaker.com/_site/assets/css/main.css +0 -6
- data/usefakermaker.com/_site/assets/css/main.css.map +0 -1
- data/usefakermaker.com/_site/assets/js/_main.js +0 -230
- data/usefakermaker.com/_site/assets/js/lunr/lunr-en.js +0 -69
- data/usefakermaker.com/_site/assets/js/lunr/lunr-gr.js +0 -522
- data/usefakermaker.com/_site/assets/js/lunr/lunr-store.js +0 -1
- data/usefakermaker.com/_site/assets/js/lunr/lunr.js +0 -3475
- data/usefakermaker.com/_site/assets/js/lunr/lunr.min.js +0 -6
- data/usefakermaker.com/_site/assets/js/main.min.js +0 -7
- data/usefakermaker.com/_site/assets/js/main.min.js.map +0 -1
- data/usefakermaker.com/_site/assets/js/plugins/gumshoe.js +0 -484
- data/usefakermaker.com/_site/assets/js/plugins/jquery.ba-throttle-debounce.js +0 -252
- data/usefakermaker.com/_site/assets/js/plugins/jquery.fitvids.js +0 -82
- data/usefakermaker.com/_site/assets/js/plugins/jquery.greedy-navigation.js +0 -128
- data/usefakermaker.com/_site/assets/js/plugins/jquery.magnific-popup.js +0 -1860
- data/usefakermaker.com/_site/assets/js/plugins/smooth-scroll.js +0 -650
- data/usefakermaker.com/_site/assets/js/vendor/jquery/jquery-3.6.0.js +0 -10881
- data/usefakermaker.com/_site/feed.xml +0 -1
- data/usefakermaker.com/_site/robots.txt +0 -1
- data/usefakermaker.com/_site/sitemap.xml +0 -3
- data/usefakermaker.com/about.markdown +0 -18
- /data/{usefakermaker.com → usefakermaker.com.site/site}/assets/images/pug.png +0 -0
- /data/{usefakermaker.com → usefakermaker.com.site/site}/assets/images/unipug.svg +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4f341f27ec954b732dde7141c9ad532346c09dadbbed4ea469894b10cac652f8
|
|
4
|
+
data.tar.gz: 61919d74b140d82fba2750bcf0e1c25473ebe21e02a2b213bd1109d94f22d9e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: de3ae09ed6b848612d3fc23533d04f4633eaa4be42f7f7be9fc3f3938f8b86afa2a495f6928a66f38207d63233e2b37ce88897178688a4f3aa2c6c5f524b51e4
|
|
7
|
+
data.tar.gz: cdc3c4509819316bc389d2bf1857883ddfa62b14b93a8f794a043af70bd603dec46f7e0a0c37d29d8814ff447ac2762cd3d56a92fc917338bc3458b4113263c9
|
data/.github/workflows/ruby.yml
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/MIGRATION_NOTES.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Jekyll to Jackdaw Migration Notes
|
|
2
|
+
|
|
3
|
+
## 1. Project Initialization
|
|
4
|
+
* Run `jackdaw new <project_name>` to generate the standard directory structure:
|
|
5
|
+
* `site/src`: Content
|
|
6
|
+
* `site/templates`: ERB Templates
|
|
7
|
+
* `site/assets`: Static files (images, css, favicons)
|
|
8
|
+
|
|
9
|
+
## 2. Template Conversion
|
|
10
|
+
* **Layouts**: Consolidate Jekyll layouts (default, page, etc.) into `site/templates/layout.html.erb`.
|
|
11
|
+
* Replace `{{ content }}` with `<%= content %>`.
|
|
12
|
+
* Replace `{{ page.title }}` with `<%= title %>`.
|
|
13
|
+
* **Partials**: Convert `{% include file.html %}` to `<%= render 'file' %>`.
|
|
14
|
+
* Rename partial files to start with an underscore (e.g., `_nav.html.erb`).
|
|
15
|
+
* **Assets**:
|
|
16
|
+
* Move CSS/JS/Images to `site/assets/`.
|
|
17
|
+
* **Important**: When referencing in HTML, omit `assets/`.
|
|
18
|
+
* `site/assets/styles.css` -> `<link href="/styles.css">`
|
|
19
|
+
* `site/assets/img/logo.png` -> `<img src="/img/logo.png">`
|
|
20
|
+
|
|
21
|
+
## 3. Content Migration Strategies
|
|
22
|
+
* **File Extensions**:
|
|
23
|
+
* Regular pages: `.md` -> `.page.md`
|
|
24
|
+
* Blog posts: `.md` -> `.blog.md` (Filename must start with `YYYY-MM-DD-`)
|
|
25
|
+
* **Frontmatter Handling**:
|
|
26
|
+
* Jackdaw renders the *first H1* as the page title.
|
|
27
|
+
* **Task**: Strip YAML frontmatter (`--- ... ---`) and ensure the file starts with `# Page Title`.
|
|
28
|
+
* **Directory Structure**:
|
|
29
|
+
* Keep the same folder structure in `site/src` to maintain URLs.
|
|
30
|
+
* **Conflict Warning**: Do not create `topic.page.md` if you also have a folder named `topic/`. Instead, create `topic/index.page.md`.
|
|
31
|
+
|
|
32
|
+
## 4. Automation (Ruby Script)
|
|
33
|
+
For bulk migration of documentation, use a script to:
|
|
34
|
+
1. Iterate through source directories.
|
|
35
|
+
2. Read file content.
|
|
36
|
+
3. specific YAML frontmatter values (Title).
|
|
37
|
+
4. Rewrite file to destination with new header and `.page.md` extension.
|
|
38
|
+
|
|
39
|
+
## 5. Navigation & Indices
|
|
40
|
+
* Jackdaw does not automatically build navigation menus from folder structure.
|
|
41
|
+
* **Manual**: Edit `site/templates/_nav.html.erb`.
|
|
42
|
+
* **Auto-generated Indices**: Write scripts to generate index markdown files (e.g., "List of all Rules") if the content changes frequently.
|
|
43
|
+
|
|
44
|
+
## 6. Styling
|
|
45
|
+
* Jackdaw provides no default styling.
|
|
46
|
+
* Create a robust `styles.css` using CSS Variables for theming.
|
|
47
|
+
* Link fonts and stylesheets in the `<head>` of `layout.html.erb`.
|
data/TODO.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- DONE - sorta
|
|
2
|
+
2. get attributes including embedded attr -- THIS WORKS IF USING THE FACTORY PARAMETER, NOT PROC EMBEDDED FACTORIES -- NEED A CHANGE TO OSL FACTORIES
|
|
3
|
+
3. What the hell is going on with @embedded factories -- why is this always nil CHECK -- FOR THE LOVE OF GOD, WRITE DOCUMENTATION FOR THIS
|
|
4
|
+
4. Factory#attribute_names line ~ 110
|
|
5
|
+
|
|
6
|
+
-- TODO
|
|
7
|
+
|
|
8
|
+
1. nested builds using the build method -- this is hidden at the moment, it sets the value of the key to a hash rather than recursively calling the field#field method
|
|
9
|
+
5. FM[:foo].build( attributes: { does_not_exist: 1 }, raise_on_error: false ) # RAISE_ON_ERROR
|
|
10
|
+
5. FM[:foo].build( attributes: { does_not_exist: 1 }, strict: false ) # RAISE_ON_ERROR
|
|
11
|
+
5. FM[:foo].build( attributes: { does_not_exist: 1 }, very_strict: false ) # RAISE_ON_ERROR
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
building embedded factories need to know the build options passed in to the top level build call -- e.g. is chaos on or not
|
|
15
|
+
|
|
16
|
+
check naming strategies still work
|
data/faker_maker.gemspec
CHANGED
|
@@ -43,7 +43,7 @@ Gem::Specification.new do |spec|
|
|
|
43
43
|
|
|
44
44
|
spec.add_dependency 'activesupport', '>= 5.2', '< 9'
|
|
45
45
|
|
|
46
|
-
spec.add_development_dependency 'bundler', '
|
|
46
|
+
spec.add_development_dependency 'bundler', '>= 2'
|
|
47
47
|
spec.add_development_dependency 'faker', '~> 3.2'
|
|
48
48
|
spec.add_development_dependency 'guard', '~> 2.16'
|
|
49
49
|
spec.add_development_dependency 'guard-bundler', '~> 3.0'
|
data/hack/nested.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'faker_maker'
|
|
2
|
+
require 'awesome_print'
|
|
3
|
+
|
|
4
|
+
FM.factory :random do
|
|
5
|
+
flavour { 'blue' }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
FM.factory :item do
|
|
9
|
+
name { 'toothpaste' }
|
|
10
|
+
price { 0.99 }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
FM.factory :coupon do
|
|
14
|
+
discount { 0.10 }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
FM.factory :basket do
|
|
18
|
+
items( factory: %i[item random] )
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# { a: 1, b: { x: 2 } }
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module FakerMaker
|
|
4
4
|
# Attributes describe the fields of classes
|
|
5
5
|
class Attribute
|
|
6
|
-
attr_reader :name, :block, :translation, :required, :optional, :optional_weighting
|
|
6
|
+
attr_reader :name, :block, :translation, :required, :optional, :optional_weighting
|
|
7
7
|
|
|
8
8
|
DEFAULT_OPTIONAL_WEIGHTING = 0.5
|
|
9
9
|
|
|
@@ -25,6 +25,15 @@ module FakerMaker
|
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
# Return an array of factory instances
|
|
29
|
+
def embedded_factories
|
|
30
|
+
@embedded_factories.map { |name| FakerMaker[name] }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def embedded_factories?
|
|
34
|
+
@embedded_factories.any?
|
|
35
|
+
end
|
|
36
|
+
|
|
28
37
|
def array?
|
|
29
38
|
forced_array? || @array
|
|
30
39
|
end
|
data/lib/faker_maker/base.rb
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
module FakerMaker
|
|
4
4
|
# Base module for defining the DSL
|
|
5
5
|
module Base
|
|
6
|
-
def factory(name, options = {}, &
|
|
6
|
+
def factory(name, options = {}, &)
|
|
7
7
|
factory = FakerMaker.find_factory(name)
|
|
8
8
|
if factory.nil?
|
|
9
9
|
factory = FakerMaker::Factory.new name, options
|
|
10
10
|
proxy = DefinitionProxy.new factory
|
|
11
|
-
proxy.instance_eval( &
|
|
11
|
+
proxy.instance_eval( & ) if block_given?
|
|
12
12
|
FakerMaker.register_factory factory
|
|
13
13
|
else
|
|
14
14
|
factory
|
|
@@ -13,8 +13,8 @@ module FakerMaker
|
|
|
13
13
|
@factory
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def method_missing(name,
|
|
17
|
-
attribute = FakerMaker::Attribute.new
|
|
16
|
+
def method_missing(name, *, &block)
|
|
17
|
+
attribute = FakerMaker::Attribute.new(name, block, *)
|
|
18
18
|
@factory.attach_attribute attribute
|
|
19
19
|
end
|
|
20
20
|
|
data/lib/faker_maker/factory.rb
CHANGED
|
@@ -5,8 +5,26 @@ module FakerMaker
|
|
|
5
5
|
# Factories construct instances of a fake
|
|
6
6
|
class Factory
|
|
7
7
|
include Auditable
|
|
8
|
+
|
|
8
9
|
attr_reader :name, :class_name, :parent, :chaos_selected_attributes
|
|
9
10
|
|
|
11
|
+
# Create a new +Factory+ object.
|
|
12
|
+
#
|
|
13
|
+
# This method does not automatically register the factory,see
|
|
14
|
+
# FakerMaker#register_factory
|
|
15
|
+
#
|
|
16
|
+
# Options:
|
|
17
|
+
# - +:class_name+ - override the default class name that FakerMaker will generate.
|
|
18
|
+
# This is useful in the case of collisions with existing classes or keywords.
|
|
19
|
+
# - +:parent+ - the parent factory from which this factory inherits attributes.
|
|
20
|
+
# Instances built by this factory will have a class which inherits from the parent's
|
|
21
|
+
# class.
|
|
22
|
+
# - +:naming+ - one of:
|
|
23
|
+
# - +nil+ (default) - use field names as the method name and in JSON conversion
|
|
24
|
+
# - +:json+ - use field names as the method name but convert when rendering JSON, e.g.
|
|
25
|
+
# +hello_world+ becomes +helloWorld+
|
|
26
|
+
# - +:json_capitalised+ (or +:json_capitalized+) - as +:json+ but with the first letter
|
|
27
|
+
# captialised, e.g. +hello_world+ becomes +HelloWorld+
|
|
10
28
|
def initialize( name, options = {} )
|
|
11
29
|
assert_valid_options options
|
|
12
30
|
@name = name.respond_to?(:to_sym) ? name.to_sym : name.to_s.underscore.to_sym
|
|
@@ -26,6 +44,7 @@ module FakerMaker
|
|
|
26
44
|
@parent = options[:parent]
|
|
27
45
|
end
|
|
28
46
|
|
|
47
|
+
# Get the Class of the parent for this factory
|
|
29
48
|
def parent_class
|
|
30
49
|
if @parent
|
|
31
50
|
FakerMaker::Factory.const_get( FakerMaker[@parent].class_name )
|
|
@@ -34,6 +53,7 @@ module FakerMaker
|
|
|
34
53
|
end
|
|
35
54
|
end
|
|
36
55
|
|
|
56
|
+
# Attach a FakerMaker::Attribute to this Factory
|
|
37
57
|
def attach_attribute( attribute )
|
|
38
58
|
@attributes << attribute
|
|
39
59
|
end
|
|
@@ -42,14 +62,11 @@ module FakerMaker
|
|
|
42
62
|
@instance ||= instantiate
|
|
43
63
|
end
|
|
44
64
|
|
|
45
|
-
def build( attributes: {}, chaos: false
|
|
46
|
-
if kwargs.present?
|
|
47
|
-
validate_deprecated_build(kwargs)
|
|
48
|
-
attributes = kwargs
|
|
49
|
-
end
|
|
50
|
-
|
|
65
|
+
def build( attributes: {}, chaos: false )
|
|
51
66
|
@instance = nil
|
|
52
67
|
before_build if respond_to? :before_build
|
|
68
|
+
|
|
69
|
+
# TODO: make this cleverer to handle nested attributes
|
|
53
70
|
assert_only_known_attributes_for_override( attributes )
|
|
54
71
|
|
|
55
72
|
assert_chaos_options chaos if chaos
|
|
@@ -57,13 +74,19 @@ module FakerMaker
|
|
|
57
74
|
optional_attributes
|
|
58
75
|
required_attributes
|
|
59
76
|
|
|
60
|
-
populate_instance
|
|
77
|
+
populate_instance(instance, attributes, chaos:)
|
|
61
78
|
yield instance if block_given?
|
|
79
|
+
|
|
62
80
|
after_build if respond_to? :after_build
|
|
63
81
|
audit(@instance) if FakerMaker.configuration.audit?
|
|
64
82
|
instance
|
|
65
83
|
end
|
|
66
84
|
|
|
85
|
+
# Construct a Class object which will become the parent type of objects built
|
|
86
|
+
# by this factory.
|
|
87
|
+
#
|
|
88
|
+
# The Class object will be created and the attributes added to it. The returned value
|
|
89
|
+
# is a Ruby Class which can be instantiated.
|
|
67
90
|
def assemble
|
|
68
91
|
if @klass.nil?
|
|
69
92
|
@klass = Class.new parent_class
|
|
@@ -91,7 +114,7 @@ module FakerMaker
|
|
|
91
114
|
unless @json_key_map
|
|
92
115
|
@json_key_map = {}.with_indifferent_access
|
|
93
116
|
@json_key_map.merge!( FakerMaker[parent].json_key_map ) if parent?
|
|
94
|
-
attributes.each_with_object( @json_key_map ) do |attr, map|
|
|
117
|
+
attributes(include_embeddings: false).each_with_object( @json_key_map ) do |attr, map|
|
|
95
118
|
key = if attr.translation?
|
|
96
119
|
attr.translation
|
|
97
120
|
elsif @naming_strategy
|
|
@@ -106,29 +129,88 @@ module FakerMaker
|
|
|
106
129
|
@json_key_map
|
|
107
130
|
end
|
|
108
131
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
132
|
+
# Returns a transformed list of attribute names from the `attributes` array.
|
|
133
|
+
# For each item in the array:
|
|
134
|
+
# - If the item is a Hash, recursively transforms its keys and values,
|
|
135
|
+
# replacing keys with their `name` and applying the same transformation to values.
|
|
136
|
+
# - Otherwise, replaces the item with its `name`.
|
|
137
|
+
#
|
|
138
|
+
# @return [Array] An array (possibly nested) of attribute names, with hashes' keys replaced by their `name`.
|
|
139
|
+
def attribute_names
|
|
140
|
+
transform = lambda do |arr|
|
|
141
|
+
arr.map do |item|
|
|
142
|
+
if item.is_a?(Hash)
|
|
143
|
+
item.transform_keys(&:name).transform_values { |v| transform.call(v) }
|
|
144
|
+
else
|
|
145
|
+
item.name
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
transform.call(attributes)
|
|
112
150
|
end
|
|
113
151
|
|
|
114
|
-
|
|
152
|
+
# Returns a collection of attributes for the factory, optionally including embedded factory attributes.
|
|
153
|
+
#
|
|
154
|
+
# @param collection [Array] an optional array of attributes to start with (default: empty array)
|
|
155
|
+
# @param include_embeddings [Boolean] whether to include attributes from embedded factories (default: true)
|
|
156
|
+
# @return [Array] the collection of attributes, possibly including embedded factory attributes as hashes
|
|
157
|
+
#
|
|
158
|
+
# If the factory has a parent, its attributes are merged in. Attributes without embedded factories are added
|
|
159
|
+
# directly. If `include_embeddings` is true, attributes with embedded factories are added as hashes mapping
|
|
160
|
+
# the attribute to the flattened attributes of its embedded factories. If false, only the attribute itself
|
|
161
|
+
# is added.
|
|
162
|
+
def attributes( collection = [], include_embeddings: true )
|
|
115
163
|
collection |= FakerMaker[parent].attributes( collection ) if parent?
|
|
116
|
-
collection
|
|
164
|
+
collection |= @attributes.reject { |attr| attr.embedded_factories.any? }
|
|
165
|
+
|
|
166
|
+
# if there is an embedded factory(-ies) and we are including the embedded factory's
|
|
167
|
+
# fields, we are going to return a hash
|
|
168
|
+
if include_embeddings
|
|
169
|
+
@attributes.select { |attr| attr.embedded_factories.any? }.each do |attr|
|
|
170
|
+
collection << { attr => attr.embedded_factories.flat_map(&:attributes) }
|
|
171
|
+
end
|
|
172
|
+
# if there is an embedded factory(-ies) and we are not including the embedded factory's
|
|
173
|
+
# fields, just add the attribute into the set of returned fields
|
|
174
|
+
else
|
|
175
|
+
collection |= @attributes.select { |attr| attr.embedded_factories.any? }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
collection
|
|
117
179
|
end
|
|
118
180
|
|
|
181
|
+
# Finds and returns the first attribute matching the given name.
|
|
182
|
+
#
|
|
183
|
+
# This method searches through the attributes (excluding embeddings) and returns the first attribute
|
|
184
|
+
# whose name, translation, or the result of applying the naming strategy to its name matches the provided `name`.
|
|
185
|
+
#
|
|
186
|
+
# @param name [String] The name to search for among the attributes. Defaults to an empty string.
|
|
187
|
+
# @return [Object, nil] The first matching attribute object, or nil if no match is found.
|
|
119
188
|
def find_attribute( name = '' )
|
|
120
|
-
attributes.filter
|
|
189
|
+
attributes(include_embeddings: false).filter do |a|
|
|
190
|
+
[a.name, a.translation, @naming_strategy&.name(a.name)].include? name
|
|
191
|
+
end.first
|
|
121
192
|
end
|
|
122
193
|
|
|
123
194
|
protected
|
|
124
195
|
|
|
125
|
-
|
|
126
|
-
|
|
196
|
+
# Populates the given instance with attribute values, optionally applying chaos/randomization.
|
|
197
|
+
#
|
|
198
|
+
# @param instance [Object] The object instance to populate with attribute values.
|
|
199
|
+
# @param attr_override_values [Hash] A hash of attribute names and their override values.
|
|
200
|
+
# @param chaos [Boolean, Integer, nil] If truthy, enables chaos mode which may randomize or select a subset
|
|
201
|
+
# of attributes.
|
|
202
|
+
# @return [void]
|
|
203
|
+
#
|
|
204
|
+
# If the factory has a parent, its attributes are populated first.
|
|
205
|
+
# Each attribute is assigned a value, either from the override values or generated.
|
|
206
|
+
# The factory instance is set on the populated object for reference.
|
|
207
|
+
def populate_instance( instance, attr_override_values, chaos: false )
|
|
208
|
+
FakerMaker[parent].populate_instance(instance, attr_override_values, chaos:) if parent?
|
|
127
209
|
|
|
128
210
|
attributes = chaos ? chaos_select(chaos) : @attributes
|
|
129
211
|
|
|
130
212
|
attributes.each do |attribute|
|
|
131
|
-
value = value_for_attribute( instance, attribute, attr_override_values )
|
|
213
|
+
value = value_for_attribute( instance, attribute, attr_override_values, chaos: )
|
|
132
214
|
instance.send "#{attribute.name}=", value
|
|
133
215
|
end
|
|
134
216
|
instance.instance_variable_set( :@fm_factory, self )
|
|
@@ -137,7 +219,10 @@ module FakerMaker
|
|
|
137
219
|
private
|
|
138
220
|
|
|
139
221
|
def assert_only_known_attributes_for_override( attr_override_values )
|
|
140
|
-
unknown_attrs = attr_override_values.keys - attribute_names
|
|
222
|
+
unknown_attrs = attr_override_values.keys - attribute_names.flat_map do |item|
|
|
223
|
+
item.is_a?(Hash) ? item.keys : item
|
|
224
|
+
end
|
|
225
|
+
|
|
141
226
|
issue = "Can't build an instance of '#{class_name}' " \
|
|
142
227
|
"setting '#{unknown_attrs.join( ', ' )}', no such attribute(s)"
|
|
143
228
|
raise FakerMaker::NoSuchAttributeError, issue unless unknown_attrs.empty?
|
|
@@ -156,34 +241,44 @@ module FakerMaker
|
|
|
156
241
|
raise FakerMaker::ChaosConflictingAttributeError, issue unless conflicting_attributes.empty?
|
|
157
242
|
end
|
|
158
243
|
|
|
159
|
-
def
|
|
244
|
+
def overridden_value?( attr, attr_override_values )
|
|
160
245
|
attr_override_values.keys.include?( attr.name )
|
|
161
246
|
end
|
|
162
247
|
|
|
163
|
-
def value_for_attribute( instance, attr, attr_override_values )
|
|
164
|
-
if
|
|
248
|
+
def value_for_attribute( instance, attr, attr_override_values, chaos: false )
|
|
249
|
+
if !attr.embedded_factories? && overridden_value?( attr, attr_override_values )
|
|
165
250
|
attr_override_values[attr.name]
|
|
166
251
|
elsif attr.array?
|
|
167
252
|
[].tap do |a|
|
|
168
253
|
attr.cardinality.times do
|
|
169
|
-
manufacture = manufacture_from_embedded_factory( attr )
|
|
170
|
-
# if manufacture has been
|
|
254
|
+
manufacture = manufacture_from_embedded_factory( attr, attr_override_values[attr.name.to_sym], chaos: )
|
|
255
|
+
# if manufacture has been built and there is a block, instance_exec the block
|
|
171
256
|
# otherwise just add the manufacture to the array
|
|
172
257
|
a << (attr.block ? instance.instance_exec(manufacture, &attr.block) : manufacture)
|
|
173
258
|
end
|
|
174
259
|
end
|
|
175
260
|
else
|
|
176
|
-
manufacture = manufacture_from_embedded_factory( attr )
|
|
261
|
+
manufacture = manufacture_from_embedded_factory( attr, attr_override_values[attr.name.to_sym], chaos: )
|
|
177
262
|
attr.block ? instance.instance_exec(manufacture, &attr.block) : manufacture
|
|
178
263
|
end
|
|
179
264
|
end
|
|
180
265
|
|
|
181
|
-
def manufacture_from_embedded_factory( attr )
|
|
266
|
+
def manufacture_from_embedded_factory( attr, attributes = {}, chaos: false )
|
|
267
|
+
attributes ||= {}
|
|
182
268
|
# The name of the embedded factory randomly selected from the list of embedded factories.
|
|
183
|
-
|
|
269
|
+
embedded_factory = attr.embedded_factories.sample
|
|
270
|
+
|
|
271
|
+
# filter out attributes for non-chosen embedded factories to avoid triggering
|
|
272
|
+
# the NoSuchAttribute exception
|
|
273
|
+
attributes = attr
|
|
274
|
+
.embedded_factories
|
|
275
|
+
.reject { |e| e == embedded_factory }
|
|
276
|
+
.flat_map { |f| pp f.attributes.map(&:name) }
|
|
277
|
+
.then { |excl| attributes.delete_if { |k, _v| excl.include?(k) } }
|
|
278
|
+
|
|
184
279
|
# The object that is being manufactured by the factory.
|
|
185
280
|
# If an embedded factory name is provided, it builds the object using FakerMaker.
|
|
186
|
-
|
|
281
|
+
embedded_factory&.build(attributes:, chaos:)
|
|
187
282
|
end
|
|
188
283
|
|
|
189
284
|
def instantiate
|
|
@@ -264,13 +359,6 @@ module FakerMaker
|
|
|
264
359
|
.concat(selected_attrs).uniq!
|
|
265
360
|
@chaos_selected_attributes
|
|
266
361
|
end
|
|
267
|
-
|
|
268
|
-
def validate_deprecated_build(kwargs)
|
|
269
|
-
usage = kwargs.each_with_object([]) { |kwarg, result| result << "#{kwarg.first}: #{kwarg.last}" }.join(', ')
|
|
270
|
-
|
|
271
|
-
warn "[DEPRECATION] `FM[:#{name}].build(#{usage})` is deprecated. " \
|
|
272
|
-
"Please use `FM[:#{name}].build(attributes: { #{usage} })` instead."
|
|
273
|
-
end
|
|
274
362
|
end
|
|
275
363
|
end
|
|
276
364
|
# rubocop:enable Metrics/ClassLength
|
data/lib/faker_maker/version.rb
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "About"
|
|
3
|
+
layout: single
|
|
4
|
+
permalink: /pages/about/
|
|
5
|
+
author_profile: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Faker Maker was designed to be a trivial way to create data factories that could throw JSON payloads at an API endpoint. It has grown well beyond that original purpose but still remains a thing for building things that give you data.
|
|
9
|
+
|
|
10
|
+
It is much beloved by me. Although it's a personal project, it's used extensively by my employer and influenced by the needs of my colleagues. I hope it will be useful to you as well. I am very open to ideas, feedback and contributions.
|
|
11
|
+
|
|
12
|
+
Faker Maker is licenced under the [MIT licence](https://raw.githubusercontent.com/BillyRuffian/faker_maker/refs/heads/master/LICENSE.txt). Do with it what you will and have fun.
|
|
13
|
+
|
|
14
|
+
### What's the Billy Ruffian thing?
|
|
15
|
+
|
|
16
|
+
HMS Bellerophon was a 74-gun third-rate ship of the line of the Royal Navy. Launched in 1786, she served during the French Revolutionary and Napoleonic Wars, mostly on blockades or convoy escort duties. She fought in three fleet actions: the Glorious First of June, the Battle of the Nile and the Battle of Trafalgar. She became famous as the ship upon which Napoleon surrendered and which transported him into exile in 1815.
|
|
17
|
+
|
|
18
|
+
Her sailors, not being educated in the Classics, struggled to pronounce her name and so she became known as the Billy Ruffian and her crew as the "Billy Ruffians". The name stuck and was used as a nickname for the ship for the rest of her career.
|
|
19
|
+
|
|
20
|
+
Since no one in coffee shops can spell my name, I adopted 'Billy' which turned into 'Billy Ruffian'. It's also a bloody good story.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "FakerMaker",
|
|
3
|
+
"short_name": "FakerMaker",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "/favicons/android-chrome-192x192.png",
|
|
7
|
+
"sizes": "192x192",
|
|
8
|
+
"type": "image/png"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"src": "/favicons/android-chrome-512x512.png",
|
|
12
|
+
"sizes": "512x512",
|
|
13
|
+
"type": "image/png"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"theme_color": "#ffffff",
|
|
17
|
+
"background_color": "#ffffff",
|
|
18
|
+
"display": "standalone"
|
|
19
|
+
}
|