fabrication 2.21.1 → 2.24.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/README.markdown +1 -4
- data/Rakefile +8 -10
- data/lib/fabricate.rb +13 -16
- data/lib/fabrication/config.rb +28 -15
- data/lib/fabrication/cucumber/step_fabricator.rb +20 -13
- data/lib/fabrication/errors/duplicate_fabricator_error.rb +5 -3
- data/lib/fabrication/errors/infinite_recursion_error.rb +5 -3
- data/lib/fabrication/errors/misplaced_fabricate_error.rb +7 -3
- data/lib/fabrication/errors/unfabricatable_error.rb +5 -4
- data/lib/fabrication/errors/unknown_fabricator_error.rb +5 -5
- data/lib/fabrication/generator/active_record.rb +18 -15
- data/lib/fabrication/generator/base.rb +89 -81
- data/lib/fabrication/generator/data_mapper.rb +14 -12
- data/lib/fabrication/generator/mongoid.rb +13 -11
- data/lib/fabrication/generator/sequel.rb +29 -27
- data/lib/fabrication/railtie.rb +1 -3
- data/lib/fabrication/schematic/attribute.rb +69 -62
- data/lib/fabrication/schematic/definition.rb +141 -134
- data/lib/fabrication/schematic/evaluator.rb +61 -54
- data/lib/fabrication/schematic/manager.rb +69 -59
- data/lib/fabrication/schematic/runner.rb +12 -9
- data/lib/fabrication/sequencer.rb +23 -22
- data/lib/fabrication/support.rb +63 -54
- data/lib/fabrication/syntax/make.rb +0 -1
- data/lib/fabrication/transform.rb +34 -36
- data/lib/fabrication/version.rb +1 -1
- data/lib/fabrication.rb +6 -3
- data/lib/rails/generators/fabrication/cucumber_steps/cucumber_steps_generator.rb +2 -3
- data/lib/rails/generators/fabrication/cucumber_steps/templates/fabrication_steps.rb +10 -10
- data/lib/rails/generators/fabrication/model/model_generator.rb +9 -9
- data/lib/tasks/defined_fabricators.rake +11 -11
- metadata +7 -7
@@ -1,80 +1,90 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module Fabrication
|
4
|
+
module Schematic
|
5
|
+
class Manager
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def preinitialize
|
9
|
+
@initializing = true
|
10
|
+
clear
|
11
|
+
end
|
5
12
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
13
|
+
def initializing?
|
14
|
+
@initializing ||= nil
|
15
|
+
end
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
17
|
+
def schematics
|
18
|
+
@schematics ||= {}
|
19
|
+
end
|
14
20
|
|
15
|
-
|
16
|
-
|
17
|
-
|
21
|
+
def clear
|
22
|
+
schematics.clear
|
23
|
+
end
|
18
24
|
|
19
|
-
|
20
|
-
|
25
|
+
def empty?
|
26
|
+
schematics.empty?
|
27
|
+
end
|
21
28
|
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
def freeze
|
30
|
+
@initializing = false
|
31
|
+
end
|
25
32
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
33
|
+
def register(name, options, &block)
|
34
|
+
name = name.to_sym
|
35
|
+
raise_if_registered(name)
|
36
|
+
store(name, Array(options.delete(:aliases)), options, &block)
|
37
|
+
end
|
31
38
|
|
32
|
-
|
33
|
-
|
34
|
-
|
39
|
+
def [](name)
|
40
|
+
schematics[name.to_sym]
|
41
|
+
end
|
35
42
|
|
36
|
-
|
37
|
-
|
38
|
-
|
43
|
+
def create_stack
|
44
|
+
@create_stack ||= []
|
45
|
+
end
|
39
46
|
|
40
|
-
|
41
|
-
|
42
|
-
|
47
|
+
def build_stack
|
48
|
+
@build_stack ||= []
|
49
|
+
end
|
43
50
|
|
44
|
-
|
45
|
-
|
46
|
-
|
51
|
+
def to_params_stack
|
52
|
+
@to_params_stack ||= []
|
53
|
+
end
|
47
54
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
55
|
+
def load_definitions
|
56
|
+
preinitialize
|
57
|
+
Fabrication::Config.path_prefixes.each do |prefix|
|
58
|
+
Fabrication::Config.fabricator_paths.each do |path|
|
59
|
+
if File.file?(path)
|
60
|
+
load path
|
61
|
+
else
|
62
|
+
Dir.glob(File.join(prefix.to_s, path, '**', '*.rb')).sort.each do |file|
|
63
|
+
load file
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
54
67
|
end
|
68
|
+
ensure
|
69
|
+
freeze
|
55
70
|
end
|
56
|
-
end
|
57
|
-
rescue Exception => e
|
58
|
-
raise e
|
59
|
-
ensure
|
60
|
-
freeze
|
61
|
-
end
|
62
71
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
72
|
+
def prevent_recursion!
|
73
|
+
(create_stack + build_stack + to_params_stack).group_by(&:to_sym).each do |name, values|
|
74
|
+
raise Fabrication::InfiniteRecursionError, name if values.length > Fabrication::Config.recursion_limit
|
75
|
+
end
|
76
|
+
end
|
68
77
|
|
69
|
-
|
78
|
+
protected
|
70
79
|
|
71
|
-
|
72
|
-
|
73
|
-
|
80
|
+
def raise_if_registered(name)
|
81
|
+
(raise Fabrication::DuplicateFabricatorError, name) if self[name]
|
82
|
+
end
|
74
83
|
|
75
|
-
|
76
|
-
|
77
|
-
|
84
|
+
def store(name, aliases, options, &block)
|
85
|
+
schematic = schematics[name] = Fabrication::Schematic::Definition.new(name, options, &block)
|
86
|
+
aliases.each { |as| schematics[as.to_sym] = schematic }
|
87
|
+
end
|
88
|
+
end
|
78
89
|
end
|
79
|
-
|
80
90
|
end
|
@@ -1,13 +1,16 @@
|
|
1
|
-
|
1
|
+
module Fabrication
|
2
|
+
module Schematic
|
3
|
+
class Runner
|
4
|
+
attr_accessor :klass
|
2
5
|
|
3
|
-
|
6
|
+
def initialize(klass)
|
7
|
+
self.klass = klass
|
8
|
+
end
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
name = "#{klass.to_s.downcase.gsub(/::/, '_')}_#{name}"
|
11
|
-
Fabrication::Sequencer.sequence(name, start, &block)
|
10
|
+
def sequence(name = Fabrication::Sequencer::DEFAULT, start = nil, &block)
|
11
|
+
name = "#{klass.to_s.downcase.gsub(/::/, '_')}_#{name}"
|
12
|
+
Fabrication::Sequencer.sequence(name, start, &block)
|
13
|
+
end
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
@@ -1,29 +1,30 @@
|
|
1
|
-
|
1
|
+
module Fabrication
|
2
|
+
class Sequencer
|
3
|
+
DEFAULT = :_default
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
sequences[name] += 1
|
5
|
+
def self.sequence(name = DEFAULT, start = nil, &block)
|
6
|
+
idx = sequences[name] ||= start || Fabrication::Config.sequence_start
|
7
|
+
if block
|
8
|
+
sequence_blocks[name] = block.to_proc
|
9
|
+
else
|
10
|
+
sequence_blocks[name] ||= ->(i) { i }
|
11
|
+
end.call(idx).tap do
|
12
|
+
sequences[name] += 1
|
13
|
+
end
|
13
14
|
end
|
14
|
-
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def self.sequences
|
17
|
+
@sequences ||= {}
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def self.sequence_blocks
|
21
|
+
@sequence_blocks ||= {}
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
def self.reset
|
25
|
+
Fabrication::Config.sequence_start = nil
|
26
|
+
@sequences = nil
|
27
|
+
@sequence_blocks = nil
|
28
|
+
end
|
28
29
|
end
|
29
30
|
end
|
data/lib/fabrication/support.rb
CHANGED
@@ -1,70 +1,79 @@
|
|
1
|
-
|
1
|
+
module Fabrication
|
2
|
+
class Support
|
3
|
+
class << self
|
4
|
+
def fabricatable?(name)
|
5
|
+
Fabrication.manager[name] || class_for(name)
|
6
|
+
end
|
2
7
|
|
3
|
-
|
8
|
+
def class_for(class_or_to_s)
|
9
|
+
class_name = variable_name_to_class_name(class_or_to_s)
|
10
|
+
constantize(class_name)
|
11
|
+
rescue NameError => e
|
12
|
+
raise Fabrication::UnfabricatableError.new(class_or_to_s, e)
|
13
|
+
end
|
4
14
|
|
5
|
-
|
6
|
-
|
7
|
-
|
15
|
+
def constantize(camel_cased_word)
|
16
|
+
names = camel_cased_word.split('::')
|
17
|
+
Object.const_get(camel_cased_word) if names.empty?
|
18
|
+
names.shift if names.size > 1 && names.first.empty?
|
19
|
+
names.inject(Object) do |constant, name|
|
20
|
+
if constant == Object
|
21
|
+
constant.const_get(name)
|
22
|
+
else
|
23
|
+
candidate = constant.const_get(name)
|
24
|
+
next candidate if constant.const_defined?(name, false)
|
25
|
+
next candidate unless Object.const_defined?(name)
|
8
26
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
rescue NameError => original_error
|
13
|
-
raise Fabrication::UnfabricatableError.new(class_or_to_s, original_error)
|
14
|
-
end
|
27
|
+
constant = constant.ancestors.inject do |const, ancestor|
|
28
|
+
break const if ancestor == Object
|
29
|
+
break ancestor if ancestor.const_defined?(name, false)
|
15
30
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
names.shift if names.size > 1 && names.first.empty?
|
20
|
-
names.inject(Object) do |constant, name|
|
21
|
-
if constant == Object
|
22
|
-
constant.const_get(name)
|
23
|
-
else
|
24
|
-
candidate = constant.const_get(name)
|
25
|
-
next candidate if constant.const_defined?(name, false)
|
26
|
-
next candidate unless Object.const_defined?(name)
|
27
|
-
constant = constant.ancestors.inject do |const, ancestor|
|
28
|
-
break const if ancestor == Object
|
29
|
-
break ancestor if ancestor.const_defined?(name, false)
|
30
|
-
const
|
31
|
+
const
|
32
|
+
end
|
33
|
+
constant.const_get(name, false)
|
31
34
|
end
|
32
|
-
constant.const_get(name, false)
|
33
35
|
end
|
34
36
|
end
|
35
|
-
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
def extract_options!(args)
|
39
|
+
args.last.is_a?(::Hash) ? args.pop : {}
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
42
|
+
def variable_name_to_class_name(name)
|
43
|
+
name_string = name.to_s
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
if name_string.respond_to?(:camelize)
|
46
|
+
name_string.camelize
|
47
|
+
else
|
48
|
+
name_string.gsub(%r{/(.?)}) do
|
49
|
+
"::#{Regexp.last_match(1).upcase}"
|
50
|
+
end.gsub(/(?:^|_)(.)/) { Regexp.last_match(1).upcase }
|
51
|
+
end
|
52
|
+
end
|
49
53
|
|
50
|
-
|
51
|
-
|
52
|
-
|
54
|
+
def find_definitions
|
55
|
+
puts 'DEPRECATION WARNING: Fabrication::Support.find_definitions has been replaced ' \
|
56
|
+
'by Fabrication.manager.load_definitions and will be removed in 3.0.0.'
|
57
|
+
Fabrication.manager.load_definitions
|
58
|
+
end
|
53
59
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
string.end_with?('s') ? string[0..-2] : string
|
58
|
-
end
|
60
|
+
def hash_class
|
61
|
+
@hash_class ||= defined?(HashWithIndifferentAccess) ? HashWithIndifferentAccess : Hash
|
62
|
+
end
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
downcase
|
66
|
-
end
|
64
|
+
def singularize(string)
|
65
|
+
string.singularize
|
66
|
+
rescue StandardError
|
67
|
+
string.end_with?('s') ? string[0..-2] : string
|
68
|
+
end
|
67
69
|
|
70
|
+
def underscore(string)
|
71
|
+
string.gsub(/::/, '/')
|
72
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
73
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
74
|
+
.tr('-', '_')
|
75
|
+
.downcase
|
76
|
+
end
|
77
|
+
end
|
68
78
|
end
|
69
|
-
|
70
79
|
end
|
@@ -1,39 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module Fabrication
|
2
|
+
class Transform
|
3
|
+
class << self
|
4
|
+
def apply_to(schematic, attributes_hash)
|
5
|
+
Fabrication.manager.load_definitions if Fabrication.manager.empty?
|
6
|
+
attributes_hash.inject({}) { |h, (k, v)| h.update(k => apply_transform(schematic, k, v)) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def clear_all
|
10
|
+
@transforms = nil
|
11
|
+
@overrides = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def define(attribute, transform)
|
15
|
+
transforms[attribute] = transform
|
16
|
+
end
|
17
|
+
|
18
|
+
def only_for(schematic, attribute, transform)
|
19
|
+
overrides[schematic] = (overrides[schematic] || {}).merge!(attribute => transform)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def overrides
|
25
|
+
@overrides ||= {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def apply_transform(schematic, attribute, value)
|
29
|
+
overrides.fetch(schematic, transforms)[attribute].call(value)
|
30
|
+
end
|
31
|
+
|
32
|
+
def transforms
|
33
|
+
@transforms ||= Hash.new(->(value) { value })
|
34
|
+
end
|
8
35
|
end
|
9
|
-
|
10
|
-
def clear_all
|
11
|
-
@transforms = nil
|
12
|
-
@overrides = nil
|
13
|
-
end
|
14
|
-
|
15
|
-
def define(attribute, transform)
|
16
|
-
transforms[attribute] = transform
|
17
|
-
end
|
18
|
-
|
19
|
-
def only_for(schematic, attribute, transform)
|
20
|
-
overrides[schematic] = (overrides[schematic] || {}).merge!(attribute => transform)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def overrides
|
26
|
-
@overrides ||= {}
|
27
|
-
end
|
28
|
-
|
29
|
-
def apply_transform(schematic, attribute, value)
|
30
|
-
overrides.fetch(schematic, transforms)[attribute].call(value)
|
31
|
-
end
|
32
|
-
|
33
|
-
def transforms
|
34
|
-
@transforms ||= Hash.new(lambda {|value| value})
|
35
|
-
end
|
36
|
-
|
37
36
|
end
|
38
|
-
|
39
37
|
end
|
data/lib/fabrication/version.rb
CHANGED
data/lib/fabrication.rb
CHANGED
@@ -52,20 +52,23 @@ module Fabrication
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def self.schematics
|
55
|
-
puts
|
55
|
+
puts 'DEPRECATION WARNING: Fabrication.schematics has been replaced by '\
|
56
|
+
'Fabrication.manager and will be removed in 3.0.0.'
|
56
57
|
manager
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
|
-
|
61
|
+
# rubocop:disable Naming/MethodName
|
62
|
+
def Fabricator(name, options = {}, &block)
|
61
63
|
Fabrication.manager.register(name, options, &block)
|
62
64
|
end
|
63
65
|
|
64
|
-
def Fabricate(name, overrides={}, &block)
|
66
|
+
def Fabricate(name, overrides = {}, &block)
|
65
67
|
Fabricate.create(name, overrides, &block).tap do |object|
|
66
68
|
Fabrication::Cucumber::Fabrications[name] = object if Fabrication::Config.register_with_steps?
|
67
69
|
end
|
68
70
|
end
|
71
|
+
# rubocop:enable Naming/MethodName
|
69
72
|
|
70
73
|
module FabricationMethods
|
71
74
|
def fabrications
|
@@ -3,13 +3,12 @@ require 'rails/generators/base'
|
|
3
3
|
module Fabrication
|
4
4
|
module Generators
|
5
5
|
class CucumberStepsGenerator < Rails::Generators::Base
|
6
|
-
|
7
6
|
def generate
|
8
|
-
template 'fabrication_steps.rb',
|
7
|
+
template 'fabrication_steps.rb', 'features/step_definitions/fabrication_steps.rb'
|
9
8
|
end
|
10
9
|
|
11
10
|
def self.source_root
|
12
|
-
@
|
11
|
+
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|
@@ -7,44 +7,44 @@ def with_ivars(fabricator)
|
|
7
7
|
model = @they.last.class.to_s.underscore
|
8
8
|
instance_variable_set("@#{model.pluralize}", @they)
|
9
9
|
instance_variable_set("@#{model.singularize}", @they.last)
|
10
|
-
Fabrication::Cucumber::Fabrications[model.singularize.gsub(/\W+/,'_').downcase] = @they.last
|
10
|
+
Fabrication::Cucumber::Fabrications[model.singularize.gsub(/\W+/, '_').downcase] = @they.last
|
11
11
|
end
|
12
12
|
|
13
|
-
Given
|
13
|
+
Given(/^(\d+) ([^"]*)$/) do |count, model_name|
|
14
14
|
with_ivars Fabrication::Cucumber::StepFabricator.new(model_name) do |fab|
|
15
15
|
fab.n(count.to_i)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
Given
|
19
|
+
Given(/^the following ([^"]*):$/) do |model_name, table|
|
20
20
|
with_ivars Fabrication::Cucumber::StepFabricator.new(model_name) do |fab|
|
21
21
|
fab.from_table(table)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
Given
|
26
|
-
with_ivars Fabrication::Cucumber::StepFabricator.new(child, :
|
25
|
+
Given(/^that ([^"]*) has the following ([^"]*):$/) do |parent, child, table|
|
26
|
+
with_ivars Fabrication::Cucumber::StepFabricator.new(child, parent: parent) do |fab|
|
27
27
|
fab.from_table(table)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
Given
|
32
|
-
with_ivars Fabrication::Cucumber::StepFabricator.new(child, :
|
31
|
+
Given(/^that ([^"]*) has (\d+) ([^"]*)$/) do |parent, count, child|
|
32
|
+
with_ivars Fabrication::Cucumber::StepFabricator.new(child, parent: parent) do |fab|
|
33
33
|
fab.n(count.to_i)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
Given
|
37
|
+
Given(/^(?:that|those) (.*) belongs? to that (.*)$/) do |children, parent|
|
38
38
|
with_ivars Fabrication::Cucumber::StepFabricator.new(parent) do |fab|
|
39
39
|
fab.has_many(children)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
Then
|
43
|
+
Then(/^I should see (\d+) ([^"]*) in the database$/) do |count, model_name|
|
44
44
|
expect(Fabrication::Cucumber::StepFabricator.new(model_name).klass.count).to eq(count.to_i)
|
45
45
|
end
|
46
46
|
|
47
|
-
Then
|
47
|
+
Then(/^I should see the following (.*) in the database:$/) do |model_name, table|
|
48
48
|
klass = Fabrication::Cucumber::StepFabricator.new(model_name).klass
|
49
49
|
expect(klass.where(table.rows_hash.symbolize_keys).count).to eq(1)
|
50
50
|
end
|
@@ -3,22 +3,23 @@ require 'rails/generators/named_base'
|
|
3
3
|
module Fabrication
|
4
4
|
module Generators
|
5
5
|
class ModelGenerator < Rails::Generators::NamedBase
|
6
|
-
argument :attributes, :
|
7
|
-
class_option :dir, :
|
8
|
-
|
6
|
+
argument :attributes, type: :array, default: [], banner: 'field:type field:type'
|
7
|
+
class_option :dir, type: :string, default: 'spec/fabricators',
|
8
|
+
desc: 'The directory where the fabricators should go'
|
9
|
+
class_option :extension, type: :string, default: 'rb', desc: 'file extension name'
|
9
10
|
|
10
11
|
def create_fabrication_file
|
11
12
|
copy_attributes_from_model if attributes.empty?
|
12
13
|
template_file = File.join(
|
13
14
|
options[:dir],
|
14
15
|
class_path,
|
15
|
-
"#{file_name}_fabricator.#{options[:extension]
|
16
|
+
"#{file_name}_fabricator.#{options[:extension]}"
|
16
17
|
)
|
17
18
|
template 'fabricator.erb', template_file
|
18
19
|
end
|
19
20
|
|
20
21
|
def self.source_root
|
21
|
-
@
|
22
|
+
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
@@ -26,14 +27,13 @@ module Fabrication
|
|
26
27
|
def copy_attributes_from_model
|
27
28
|
model = class_name.constantize
|
28
29
|
if defined?(ActiveRecord) && model < ActiveRecord::Base
|
29
|
-
self.attributes = model.columns_hash.map
|
30
|
+
self.attributes = model.columns_hash.map do |name, column|
|
30
31
|
Rails::Generators::GeneratedAttribute.new(name, column.type)
|
31
|
-
|
32
|
+
end
|
32
33
|
end
|
33
|
-
rescue
|
34
|
+
rescue StandardError
|
34
35
|
# no table? no problem!
|
35
36
|
end
|
36
|
-
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -1,30 +1,30 @@
|
|
1
1
|
namespace :fabrication do
|
2
|
-
desc
|
3
|
-
task :
|
2
|
+
desc 'Display all registered fabricators by class'
|
3
|
+
task list: :environment do
|
4
4
|
Fabrication.manager.load_definitions if Fabrication.manager.empty?
|
5
5
|
|
6
6
|
if Fabrication.manager.schematics.none?
|
7
|
-
puts
|
7
|
+
puts 'No fabricators found'
|
8
8
|
next
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
schematic_groups = Fabrication.manager.schematics.group_by do |_name, fabdef|
|
12
12
|
fabdef.klass.name
|
13
13
|
end
|
14
14
|
|
15
15
|
fabricators = {}
|
16
|
-
|
17
|
-
fabricators[klass] = groups.map(&:first).sort.join(
|
16
|
+
schematic_groups.sort_by { |klass, _| klass }.each do |klass, groups|
|
17
|
+
fabricators[klass] = groups.map(&:first).sort.join(', ')
|
18
18
|
end
|
19
19
|
|
20
|
-
class_width = fabricators.keys.max_by
|
21
|
-
names_width = fabricators.values.max_by
|
20
|
+
class_width = fabricators.keys.max_by(&:size).size + 3 # padding
|
21
|
+
names_width = fabricators.values.max_by(&:size).size
|
22
22
|
say = lambda do |f1, f2|
|
23
23
|
printf "%-#{class_width}s%-#{names_width}s\n", f1, f2
|
24
24
|
end
|
25
25
|
|
26
|
-
say[
|
27
|
-
puts
|
28
|
-
fabricators.each { |klass, names| say[klass,names] }
|
26
|
+
say['Class', 'Fabricator']
|
27
|
+
puts '-' * (names_width + class_width)
|
28
|
+
fabricators.each { |klass, names| say[klass, names] }
|
29
29
|
end
|
30
30
|
end
|