diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..c29479b9 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,75 @@ +require: + - rubocop-rake + - rubocop-rspec + +AllCops: + Exclude: + - gemfiles/* + NewCops: enable + TargetRubyVersion: 2.5 + +Lint/ConstantDefinitionInBlock: + Exclude: + - spec/**/* +Lint/EmptyClass: + Exclude: + - spec/**/* +Lint/Void: + Exclude: + - features/step_definitions/object_verification_steps.rb + +Metrics/BlockLength: + Exclude: + - spec/**/* + +Naming/MethodName: + Exclude: + - lib/fabrication.rb +Naming/PredicateName: + Exclude: + - lib/fabrication/cucumber/step_fabricator.rb + +RSpec/ExampleLength: + Enabled: false +RSpec/MultipleExpectations: + Enabled: false +RSpec/NestedGroups: + Enabled: false + +Style/Documentation: + Enabled: false +Style/FrozenStringLiteralComment: + Enabled: false + +Metrics/AbcSize: + Enabled: False +Metrics/ClassLength: + Enabled: False +Metrics/CyclomaticComplexity: + Enabled: False +Metrics/MethodLength: + Enabled: False +Metrics/PerceivedComplexity: + Enabled: False +RSpec/ImplicitExpect: + Enabled: False +RSpec/ImplicitSubject: + Enabled: False +RSpec/LeakyConstantDeclaration: + Enabled: False +RSpec/MessageSpies: + Enabled: False +RSpec/StubbedMock: + Enabled: False +RSpec/VerifiedDoubles: + Enabled: False +Style/ClassAndModuleChildren: + Enabled: False +Style/MissingRespondToMissing: + Enabled: False +Style/ModuleFunction: + Enabled: False +Style/MultilineBlockChain: + Enabled: False +Style/MutableConstant: + Enabled: False diff --git a/Appraisals b/Appraisals index a58dedda..c873e327 100644 --- a/Appraisals +++ b/Appraisals @@ -9,6 +9,7 @@ appraise 'kitchen-sink' do end appraise 'blank-slate' do + # this simulates requiring fabrication with no known frameworks present end appraise 'rails-6.1' do diff --git a/Gemfile b/Gemfile index ceca5fde..5d155984 100644 --- a/Gemfile +++ b/Gemfile @@ -9,4 +9,6 @@ gem 'pry' gem 'rake' gem 'rspec' gem 'rspec-its' +gem 'rubocop-rake', require: false +gem 'rubocop-rspec', require: false gem 'sqlite3' diff --git a/Gemfile.lock b/Gemfile.lock index 2cf5aedb..0a24e6e8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,6 +10,7 @@ GEM bundler rake thor (>= 0.14.0) + ast (2.4.2) backports (3.8.0) builder (3.2.3) coderay (1.1.2) @@ -35,10 +36,16 @@ GEM method_source (0.9.0) multi_json (1.12.2) multi_test (0.1.2) + parallel (1.20.1) + parser (3.0.0.0) + ast (~> 2.4.1) pry (0.11.1) coderay (~> 1.1.0) method_source (~> 0.9.0) + rainbow (3.0.0) rake (12.1.0) + regexp_parser (2.1.1) + rexml (3.2.4) rspec (3.6.0) rspec-core (~> 3.6.0) rspec-expectations (~> 3.6.0) @@ -55,8 +62,26 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.6.0) rspec-support (3.6.0) + rubocop (1.11.0) + parallel (~> 1.10) + parser (>= 3.0.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.2.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.4.1) + parser (>= 2.7.1.5) + rubocop-rake (0.5.1) + rubocop + rubocop-rspec (2.2.0) + rubocop (~> 1.0) + rubocop-ast (>= 1.1.0) + ruby-progressbar (1.11.0) sqlite3 (1.3.13) thor (0.20.0) + unicode-display_width (2.0.0) PLATFORMS ruby @@ -70,6 +95,8 @@ DEPENDENCIES rake rspec rspec-its + rubocop-rake + rubocop-rspec sqlite3 BUNDLED WITH diff --git a/Rakefile b/Rakefile index a86ae07e..8e99969c 100644 --- a/Rakefile +++ b/Rakefile @@ -1,11 +1,11 @@ -require "rubygems" -require "bundler/setup" +require 'rubygems' +require 'bundler/setup' Bundler.require -require "rspec/core/rake_task" +require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |spec| - spec.pattern = "spec/**/*_spec.rb" + spec.pattern = 'spec/**/*_spec.rb' end desc 'All cucumber features with kitchen sink appraisal' @@ -13,8 +13,6 @@ task :cucumber do system('appraisal kitchen-sink cucumber -f progress') end -if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"] - task default: [:cucumber, :appraisal] -else - task default: :spec -end +default_task = !ENV['APPRAISAL_INITIALIZED'] && !ENV['TRAVIS'] ? %i[cucumber appraisal] : :spec + +task default: default_task diff --git a/fabrication.gemspec b/fabrication.gemspec index 7db416b1..72730294 100644 --- a/fabrication.gemspec +++ b/fabrication.gemspec @@ -1,25 +1,25 @@ -# -*- encoding: utf-8 -*- -lib = File.expand_path('../lib/', __FILE__) -$:.unshift lib unless $:.include?(lib) +lib = File.expand_path('lib', __dir__) +$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib) require 'fabrication/version' Gem::Specification.new do |s| - s.name = "fabrication" + s.name = 'fabrication' s.version = Fabrication::VERSION - s.license = "MIT" + s.license = 'MIT' - s.authors = ["Paul Elliott"] - s.email = ["paul@codingfrontier.com"] - s.description = "Fabrication is an object generation framework for ActiveRecord, Mongoid, DataMapper, Sequel, or any other Ruby object." + s.authors = ['Paul Elliott'] + s.email = ['paul@codingfrontier.com'] + s.description = 'Fabrication is an object generation framework for ActiveRecord, ' \ + 'Mongoid, DataMapper, Sequel, or any other Ruby object.' - s.homepage = "http://fabricationgem.org" - s.require_paths = ["lib"] - s.rubygems_version = "1.3.7" + s.homepage = 'http://fabricationgem.org' + s.require_paths = ['lib'] + s.rubygems_version = '1.3.7' s.summary = "Implementing the factory pattern in Ruby so you don't have to." - s.required_ruby_version = '>= 2.2.0' + s.required_ruby_version = '>= 2.5.0' - s.files = Dir.glob("lib/**/*") + %w(LICENSE README.markdown Rakefile) + s.files = Dir.glob('lib/**/*') + %w[LICENSE README.markdown Rakefile] s.require_path = 'lib' end diff --git a/features/step_definitions/object_verification_steps.rb b/features/step_definitions/object_verification_steps.rb index a4491536..72948402 100644 --- a/features/step_definitions/object_verification_steps.rb +++ b/features/step_definitions/object_verification_steps.rb @@ -1,10 +1,10 @@ ORDINALS = { - "first" => 0, - "second" => 1 + 'first' => 0, + 'second' => 1 } def dehumanize(string) - string.gsub(/\W+/,'_').downcase + string.gsub(/\W+/, '_').downcase end def generate_fabricator_name(model_name) @@ -16,26 +16,25 @@ def get_class(model_name) Fabrication.manager[fabricator_name].send(:klass) end - -Then /^that ([^"]*) should be persisted$/ do |object_name| +Then(/^that ([^"]*) should be persisted$/) do |object_name| object_name = dehumanize(object_name) object = fabrications[object_name] object.should be_persisted end -Then /^that ([^"]*) should have "([^"]*)" for a "([^"]*)"$/ do |object_name, value, field| +Then(/^that ([^"]*) should have "([^"]*)" for a "([^"]*)"$/) do |object_name, value, field| object_name = dehumanize(object_name) object = fabrications[object_name] object.send(dehumanize(field)).to_s.should == value end -Then /^they should be persisted$/ do +Then(/^they should be persisted$/) do @they.each do |object| object.should be_persisted end end -Then /^they should reference that ([^"]*)$/ do |parent_name| +Then(/^they should reference that ([^"]*)$/) do |parent_name| parent_name = dehumanize(parent_name) parent = fabrications[parent_name] parent_class = get_class(parent_name) @@ -46,12 +45,12 @@ def get_class(model_name) end end -Then /^the ([^"]*) should have "([^"]*)" for a "([^"]*)"$/ do |ordindal, value, field| +Then(/^the ([^"]*) should have "([^"]*)" for a "([^"]*)"$/) do |ordindal, value, field| object = @they[ORDINALS[ordindal]] object.send(dehumanize(field)).to_s.should == value end -Then /^that ([^"]*) should reference that ([^"]*)$/ do |child_name, parent_name| +Then(/^that ([^"]*) should reference that ([^"]*)$/) do |child_name, parent_name| parent_name = dehumanize(parent_name) parent = fabrications[parent_name] parent_class = get_class(parent_name) @@ -61,7 +60,7 @@ def get_class(model_name) child.send(parent_class_name).should == parent end -Then /^that (.*) should have (\d+) (.*)$/ do |parent_name, count, child_name| +Then(/^that (.*) should have (\d+) (.*)$/) do |parent_name, count, child_name| parent_name = dehumanize(parent_name) parent = fabrications[parent_name] parent.send(dehumanize(child_name).pluralize).count.should == count.to_i diff --git a/features/step_definitions/other_steps.rb b/features/step_definitions/other_steps.rb index 12bcd2b9..093d4e33 100644 --- a/features/step_definitions/other_steps.rb +++ b/features/step_definitions/other_steps.rb @@ -1,11 +1,9 @@ -When /^I try to fabricate "([^"]*)"$/ do |fabricator_name| +When(/^I try to fabricate "([^"]*)"$/) do |fabricator_name| @fabricator_name = fabricator_name end -Then /^it should tell me that it isn't defined$/ do - begin - step "1 #{@fabricator_name}" - rescue Exception => e - e.message.should == "No Fabricator defined for '#{@fabricator_name}'" - end +Then(/^it should tell me that it isn't defined$/) do + step "1 #{@fabricator_name}" +rescue StandardError => e + e.message.should == "No Fabricator defined for '#{@fabricator_name}'" end diff --git a/features/support/env.rb b/features/support/env.rb index cc19d310..cd9554c6 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -2,7 +2,9 @@ Bundler.require(:default, :development) -Dir[File.expand_path(File.join(File.dirname(__FILE__),'..','..','spec','support','**','*.rb'))].each {|f| require f} +Dir[File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec', 'support', '**', '*.rb'))].sort.each do |f| + require f +end load 'lib/rails/generators/fabrication/cucumber_steps/templates/fabrication_steps.rb' Before do diff --git a/lib/fabricate.rb b/lib/fabricate.rb index 9491a246..9247fd3d 100644 --- a/lib/fabricate.rb +++ b/lib/fabricate.rb @@ -1,51 +1,48 @@ class Fabricate - def self.times(count, name, overrides={}, &block) + def self.times(count, name, overrides = {}, &block) count.times.map { Fabricate(name, overrides, &block) } end - def self.build_times(count, name, overrides={}, &block) + def self.build_times(count, name, overrides = {}, &block) count.times.map { Fabricate.build(name, overrides, &block) } end - def self.attributes_for_times(count, name, overrides={}, &block) + def self.attributes_for_times(count, name, overrides = {}, &block) count.times.map { Fabricate.attributes_for(name, overrides, &block) } end - def self.attributes_for(name, overrides={}, &block) + def self.attributes_for(name, overrides = {}, &block) fail_if_initializing(name) schematic(name).to_attributes(overrides, &block) end - def self.to_params(name, overrides={}, &block) + def self.to_params(name, overrides = {}, &block) fail_if_initializing(name) schematic(name).to_params(overrides, &block) end - def self.build(name, overrides={}, &block) + def self.build(name, overrides = {}, &block) fail_if_initializing(name) schematic(name).build(overrides, &block).tap do |object| Fabrication::Cucumber::Fabrications[name] = object if Fabrication::Config.register_with_steps? end end - def self.create(name, overrides={}, &block) + def self.create(name, overrides = {}, &block) fail_if_initializing(name) schematic(name).fabricate(overrides, &block) end - def self.sequence(name=Fabrication::Sequencer::DEFAULT, start=nil, &block) + def self.sequence(name = Fabrication::Sequencer::DEFAULT, start = nil, &block) Fabrication::Sequencer.sequence(name, start, &block) end def self.schematic(name) Fabrication.manager.load_definitions if Fabrication.manager.empty? - Fabrication.manager[name] || raise(Fabrication::UnknownFabricatorError.new(name)) + Fabrication.manager[name] || raise(Fabrication::UnknownFabricatorError, name) end - private - def self.fail_if_initializing(name) - raise Fabrication::MisplacedFabricateError.new(name) if Fabrication.manager.initializing? + raise Fabrication::MisplacedFabricateError, name if Fabrication.manager.initializing? end - end diff --git a/lib/fabrication.rb b/lib/fabrication.rb index 3719dc62..ac691f33 100644 --- a/lib/fabrication.rb +++ b/lib/fabrication.rb @@ -52,16 +52,17 @@ def self.manager end def self.schematics - puts "DEPRECATION WARNING: Fabrication.schematics has been replaced by Fabrication.manager and will be removed in 3.0.0." + puts 'DEPRECATION WARNING: Fabrication.schematics has been replaced by Fabrication.manager' \ + ' and will be removed in 3.0.0.' manager end end -def Fabricator(name, options={}, &block) +def Fabricator(name, options = {}, &block) Fabrication.manager.register(name, options, &block) end -def Fabricate(name, overrides={}, &block) +def Fabricate(name, overrides = {}, &block) Fabricate.create(name, overrides, &block).tap do |object| Fabrication::Cucumber::Fabrications[name] = object if Fabrication::Config.register_with_steps? end diff --git a/lib/fabrication/config.rb b/lib/fabrication/config.rb index b2ae1264..fef76698 100644 --- a/lib/fabrication/config.rb +++ b/lib/fabrication/config.rb @@ -2,14 +2,16 @@ module Fabrication module Config extend self - def configure; yield self end + def configure + yield self + end def reset_defaults @fabricator_path = @path_prefix = - @sequence_start = - @generators = - nil + @sequence_start = + @generators = + nil end def fabricator_path @@ -18,43 +20,54 @@ def fabricator_path alias fabricator_paths fabricator_path def fabricator_dir - puts "DEPRECATION WARNING: Fabrication::Config.fabricator_dir has been replaced by Fabrication::Config.fabricator_path" + puts 'DEPRECATION WARNING: Fabrication::Config.fabricator_dir ' \ + 'has been replaced by Fabrication::Config.fabricator_path' fabricator_path end def fabricator_path=(folders) - @fabricator_path = (Array.new << folders).flatten + @fabricator_path = ([] << folders).flatten end def fabricator_dir=(folders) - puts "DEPRECATION WARNING: Fabrication::Config.fabricator_dir has been replaced by Fabrication::Config.fabricator_path" + puts 'DEPRECATION WARNING: Fabrication::Config.fabricator_dir ' \ + 'has been replaced by Fabrication::Config.fabricator_path' self.fabricator_path = folders end - attr_writer :sequence_start - def sequence_start; @sequence_start ||= 0 end + attr_writer :sequence_start, :register_with_steps + + def sequence_start + @sequence_start ||= 0 + end def path_prefix=(folders) - @path_prefix = (Array.new << folders).flatten + @path_prefix = ([] << folders).flatten end def path_prefix - @path_prefix ||= [defined?(Rails) ? Rails.root : "."] + @path_prefix ||= [defined?(Rails) ? Rails.root : '.'] end alias path_prefixes path_prefix - attr_writer :register_with_steps def register_with_steps? @register_with_steps ||= nil end - def generators; @generators ||= [] end + def generators + @generators ||= [] + end def generator_for(default_generators, klass) (generators + default_generators).detect { |gen| gen.supports?(klass) } end - def recursion_limit; @recursion_limit ||= 20 end - def recursion_limit=(limit); @recursion_limit = limit end + def recursion_limit + @recursion_limit ||= 20 + end + + def recursion_limit=(limit) + @recursion_limit = limit + end end end diff --git a/lib/fabrication/cucumber/step_fabricator.rb b/lib/fabrication/cucumber/step_fabricator.rb index 99acfa58..8e2f0b0c 100644 --- a/lib/fabrication/cucumber/step_fabricator.rb +++ b/lib/fabrication/cucumber/step_fabricator.rb @@ -3,22 +3,22 @@ module Cucumber class StepFabricator attr_reader :model - def initialize(model_name, opts ={}) + def initialize(model_name, opts = {}) @model = dehumanize(model_name) @fabricator = Fabrication::Support.singularize(@model).to_sym @parent_name = opts.delete(:parent) end - def from_table(table, extra={}) + def from_table(table, extra = {}) hashes = singular? ? [table.rows_hash] : table.hashes hashes.map do |hash| transformed_hash = Fabrication::Transform.apply_to(@model, parameterize_hash(hash)) make(transformed_hash.merge(extra)) - end.tap {|o| remember(o) } + end.tap { |o| remember(o) } end - def n(count, attrs={}) - count.times.map { make(attrs) }.tap {|o| remember(o) } + def n(count, attrs = {}) + count.times.map { make(attrs) }.tap { |o| remember(o) } end def has_many(children) @@ -32,6 +32,7 @@ def has_many(children) def parent return unless @parent_name + Fabrications[dehumanize(@parent_name)] end @@ -54,19 +55,20 @@ def singular? end def dehumanize(string) - string.gsub(/\W+/,'_').downcase + string.gsub(/\W+/, '_').downcase end def parameterize_hash(hash) - hash.inject({}) {|h,(k,v)| h.update(dehumanize(k).to_sym => v)} + hash.inject({}) { |h, (k, v)| h.update(dehumanize(k).to_sym => v) } end - def make(attrs={}) + def make(attrs = {}) Fabricate(@fabricator, attrs.merge(parentship)) end def parentship return {} unless parent + parent_class_name = parent.class.to_s.underscore parent_instance = parent @@ -77,18 +79,19 @@ def parentship { parent_class_name => parent_instance } end - end module Fabrications - @@fabrications = {} + def self.fabrications + @fabrications ||= {} + end def self.[](fabricator) - @@fabrications[fabricator.to_sym] + fabrications[fabricator.to_sym] end def self.[]=(fabricator, fabrication) - @@fabrications[fabricator.to_sym] = fabrication + fabrications[fabricator.to_sym] = fabrication end end end diff --git a/lib/fabrication/errors/misplaced_fabricate_error.rb b/lib/fabrication/errors/misplaced_fabricate_error.rb index cf611bf8..a8e39bfc 100644 --- a/lib/fabrication/errors/misplaced_fabricate_error.rb +++ b/lib/fabrication/errors/misplaced_fabricate_error.rb @@ -1,5 +1,7 @@ class Fabrication::MisplacedFabricateError < StandardError def initialize(name) - super("You tried to fabricate `#{name}` while Fabricators were still loading. Check your fabricator files and make sure you didn't accidentally type `Fabricate` instead of `Fabricator` in there somewhere.") + super "You tried to fabricate `#{name}` while Fabricators were still loading. " \ + "Check your fabricator files and make sure you didn't accidentally type `Fabricate` " \ + 'instead of `Fabricator` in there somewhere.' end end diff --git a/lib/fabrication/errors/unfabricatable_error.rb b/lib/fabrication/errors/unfabricatable_error.rb index f3eeb477..9932692e 100644 --- a/lib/fabrication/errors/unfabricatable_error.rb +++ b/lib/fabrication/errors/unfabricatable_error.rb @@ -1,5 +1,4 @@ class Fabrication::UnfabricatableError < StandardError - def initialize(name, original_error) super("No class found for '#{name}' (original exception: #{original_error.message})") end diff --git a/lib/fabrication/errors/unknown_fabricator_error.rb b/lib/fabrication/errors/unknown_fabricator_error.rb index 29c1d119..1a333fd1 100644 --- a/lib/fabrication/errors/unknown_fabricator_error.rb +++ b/lib/fabrication/errors/unknown_fabricator_error.rb @@ -1,7 +1,5 @@ class Fabrication::UnknownFabricatorError < StandardError - def initialize(name) super("No Fabricator defined for '#{name}'") end - end diff --git a/lib/fabrication/generator/active_record.rb b/lib/fabrication/generator/active_record.rb index 7212056c..46bcd7d5 100644 --- a/lib/fabrication/generator/active_record.rb +++ b/lib/fabrication/generator/active_record.rb @@ -1,5 +1,4 @@ class Fabrication::Generator::ActiveRecord < Fabrication::Generator::Base - def self.supports?(klass) # Some gems will declare an ActiveRecord module for their own purposes # so we can't assume because we have the ActiveRecord module that we also @@ -9,11 +8,10 @@ def self.supports?(klass) end def build_instance - if _klass.respond_to?(:protected_attributes) - self._instance = _klass.new(_attributes, without_protection: true) - else - self._instance = _klass.new(_attributes) - end + self._instance = if _klass.respond_to?(:protected_attributes) + _klass.new(_attributes, without_protection: true) + else + _klass.new(_attributes) + end end - end diff --git a/lib/fabrication/generator/base.rb b/lib/fabrication/generator/base.rb index d06eeef7..351dae68 100644 --- a/lib/fabrication/generator/base.rb +++ b/lib/fabrication/generator/base.rb @@ -1,8 +1,9 @@ class Fabrication::Generator::Base + def self.supports?(_klass) + true + end - def self.supports?(_klass); true end - - def build(attributes=[], callbacks={}) + def build(attributes = [], callbacks = {}) process_attributes(attributes) if callbacks[:initialize_with] @@ -16,7 +17,7 @@ def build(attributes=[], callbacks={}) _instance end - def create(attributes=[], callbacks=[]) + def create(attributes = [], callbacks = []) build(attributes, callbacks) execute_callbacks(callbacks[:before_validation]) execute_callbacks(callbacks[:after_validation]) @@ -29,19 +30,19 @@ def create(attributes=[], callbacks=[]) end def execute_callbacks(callbacks) - callbacks.each { |callback| _instance.instance_exec(_instance, _transient_attributes, &callback) } if callbacks + callbacks&.each { |callback| _instance.instance_exec(_instance, _transient_attributes, &callback) } end - def to_params(attributes=[]) + def to_params(attributes = []) process_attributes(attributes) _attributes.respond_to?(:with_indifferent_access) ? _attributes.with_indifferent_access : _attributes end - def to_hash(attributes=[], callbacks=[]) + def to_hash(attributes = [], _callbacks = []) process_attributes(attributes) Fabrication::Support.hash_class.new.tap do |hash| _attributes.map do |name, value| - if value && value.respond_to?(:id) + if value.respond_to?(:id) hash["#{name}_id"] = value.id else hash[name] = value @@ -66,7 +67,7 @@ def build_instance end def set_attributes - _attributes.each do |k,v| + _attributes.each do |k, v| _instance.send("#{k}=", v) end end @@ -92,12 +93,11 @@ def persist end def process_attributes(attributes) - self._transient_attributes = Hash.new + self._transient_attributes = ({}) attributes.each do |attribute| _attributes[attribute.name] = attribute.processed_value(_attributes) _transient_attributes[attribute.name] = _attributes[attribute.name] if attribute.transient? end _attributes.reject! { |k| _transient_attributes.keys.include?(k) } end - end diff --git a/lib/fabrication/generator/data_mapper.rb b/lib/fabrication/generator/data_mapper.rb index 39fc4d39..73d24bd0 100644 --- a/lib/fabrication/generator/data_mapper.rb +++ b/lib/fabrication/generator/data_mapper.rb @@ -1,5 +1,4 @@ class Fabrication::Generator::DataMapper < Fabrication::Generator::Base - def self.supports?(klass) defined?(DataMapper) && klass.ancestors.include?(DataMapper::Hook) end @@ -13,5 +12,4 @@ def build_instance def persist _instance.save end - end diff --git a/lib/fabrication/generator/mongoid.rb b/lib/fabrication/generator/mongoid.rb index f15da65a..06261d2a 100644 --- a/lib/fabrication/generator/mongoid.rb +++ b/lib/fabrication/generator/mongoid.rb @@ -1,15 +1,13 @@ class Fabrication::Generator::Mongoid < Fabrication::Generator::Base - def self.supports?(klass) defined?(Mongoid) && klass.ancestors.include?(Mongoid::Document) end def build_instance - if _klass.respond_to?(:protected_attributes) - self._instance = _klass.new(_attributes, without_protection: true) - else - self._instance = _klass.new(_attributes) - end + self._instance = if _klass.respond_to?(:protected_attributes) + _klass.new(_attributes, without_protection: true) + else + _klass.new(_attributes) + end end - end diff --git a/lib/fabrication/generator/sequel.rb b/lib/fabrication/generator/sequel.rb index 2e6b6836..a7544cbb 100644 --- a/lib/fabrication/generator/sequel.rb +++ b/lib/fabrication/generator/sequel.rb @@ -1,5 +1,4 @@ class Fabrication::Generator::Sequel < Fabrication::Generator::Base - def initialize(klass) super load_instance_hooks @@ -32,5 +31,4 @@ def load_instance_hooks klass = _klass.respond_to?(:cti_base_model) ? _klass.cti_models.first : _klass klass.plugin :instance_hooks unless klass.new.respond_to? :after_save_hook end - end diff --git a/lib/fabrication/railtie.rb b/lib/fabrication/railtie.rb index 37d85028..95fe8533 100644 --- a/lib/fabrication/railtie.rb +++ b/lib/fabrication/railtie.rb @@ -9,9 +9,7 @@ class Railtie < Rails::Railtie config.generators end - unless generators.rails.has_key?(:fixture_replacement) - generators.fixture_replacement :fabrication - end + generators.fixture_replacement :fabrication unless generators.rails.key?(:fixture_replacement) end end end diff --git a/lib/fabrication/schematic/attribute.rb b/lib/fabrication/schematic/attribute.rb index 54b033b5..2172d1ec 100644 --- a/lib/fabrication/schematic/attribute.rb +++ b/lib/fabrication/schematic/attribute.rb @@ -1,9 +1,8 @@ class Fabrication::Schematic::Attribute - attr_accessor :klass, :name, :value attr_writer :params - def initialize(klass, name, value, params={}, &block) + def initialize(klass, name, value, params = {}, &block) self.klass = klass self.name = name self.params = params @@ -32,8 +31,13 @@ def processed_value(processed_attributes) end end - def value_static?; !value_proc? end - def value_proc?; Proc === value end + def value_static? + !value_proc? + end + + def value_proc? + value.is_a?(Proc) + end private @@ -61,5 +65,4 @@ def rand def rand_range Kernel.rand((params[:start_range]..params[:end_range])) if params[:start_range] && params[:end_range] end - end diff --git a/lib/fabrication/schematic/definition.rb b/lib/fabrication/schematic/definition.rb index 1016dacd..618d89cd 100644 --- a/lib/fabrication/schematic/definition.rb +++ b/lib/fabrication/schematic/definition.rb @@ -1,5 +1,4 @@ class Fabrication::Schematic::Definition - GENERATORS = [ Fabrication::Generator::ActiveRecord, Fabrication::Generator::DataMapper, @@ -9,7 +8,8 @@ class Fabrication::Schematic::Definition ] attr_accessor :name, :options, :block - def initialize(name, options={}, &block) + + def initialize(name, options = {}, &block) self.name = name self.options = options self.block = block @@ -23,9 +23,11 @@ def attribute(name) attributes.detect { |a| a.name == name } end - def append_or_update_attribute(attribute_name, value, params={}, &block) + def append_or_update_attribute(attribute_name, value, params = {}, &block) attribute = Fabrication::Schematic::Attribute.new(klass, attribute_name, value, params, &block) - if index = attributes.index { |a| a.name == attribute.name } + index = attributes.index { |a| a.name == attribute.name } + + if index attribute.transient! if attributes[index].transient? attributes[index] = attribute else @@ -33,13 +35,13 @@ def append_or_update_attribute(attribute_name, value, params={}, &block) end end - attr_writer :attributes + attr_writer :attributes, :callbacks + def attributes load_body @attributes ||= [] end - attr_writer :callbacks def callbacks load_body @callbacks ||= {} @@ -53,7 +55,7 @@ def sorted_attributes attributes.select(&:value_static?) + attributes.select(&:value_proc?) end - def build(overrides={}, &block) + def build(overrides = {}, &block) Fabrication.manager.prevent_recursion! if Fabrication.manager.to_params_stack.any? to_params(overrides, &block) @@ -69,7 +71,7 @@ def build(overrides={}, &block) end end - def fabricate(overrides={}, &block) + def fabricate(overrides = {}, &block) Fabrication.manager.prevent_recursion! if Fabrication.manager.build_stack.any? build(overrides, &block) @@ -87,7 +89,7 @@ def fabricate(overrides={}, &block) end end - def to_params(overrides={}, &block) + def to_params(overrides = {}, &block) Fabrication.manager.prevent_recursion! Fabrication.manager.to_params_stack << name merge(overrides, &block).instance_eval do @@ -97,7 +99,7 @@ def to_params(overrides={}, &block) Fabrication.manager.to_params_stack.pop end - def to_attributes(overrides={}, &block) + def to_attributes(overrides = {}, &block) merge(overrides, &block).instance_eval do generator.new(klass).to_hash(sorted_attributes, callbacks) end @@ -121,7 +123,7 @@ def generate_value(name, params) end end - def merge(overrides={}, &block) + def merge(overrides = {}, &block) clone.tap do |definition| definition.process_block(&block) overrides.each do |name, value| @@ -133,7 +135,7 @@ def merge(overrides={}, &block) def klass @klass ||= Fabrication::Support.class_for( options[:class_name] || - (parent && parent.klass) || + parent&.klass || options[:from] || name ) @@ -147,6 +149,7 @@ def loaded? def load_body return if loaded? + @loaded = true if parent diff --git a/lib/fabrication/schematic/evaluator.rb b/lib/fabrication/schematic/evaluator.rb index d7c3d293..be90eba5 100644 --- a/lib/fabrication/schematic/evaluator.rb +++ b/lib/fabrication/schematic/evaluator.rb @@ -1,5 +1,4 @@ class Fabrication::Schematic::Evaluator < BasicObject - def process(definition, &block) @_definition = definition instance_eval(&block) @@ -61,7 +60,7 @@ def init_with(*args) def transient(*field_names) field_names.each do |field_name| - if field_name.kind_of?(::Hash) + if field_name.is_a?(::Hash) field_name.each_pair { |name, value| @_definition.append_or_update_attribute(name, value, transient: true) } else @_definition.append_or_update_attribute(field_name, nil, transient: true) diff --git a/lib/fabrication/schematic/manager.rb b/lib/fabrication/schematic/manager.rb index 0f630189..206907cc 100644 --- a/lib/fabrication/schematic/manager.rb +++ b/lib/fabrication/schematic/manager.rb @@ -16,8 +16,13 @@ def schematics @schematics ||= {} end - def clear; schematics.clear end - def empty?; schematics.empty? end + def clear + schematics.clear + end + + def empty? + schematics.empty? + end def freeze @initializing = false @@ -54,15 +59,13 @@ def load_definitions end end end - rescue Exception => e - raise e ensure freeze end def prevent_recursion! (create_stack + build_stack + to_params_stack).group_by(&:to_sym).each do |name, values| - raise Fabrication::InfiniteRecursionError.new(name) if values.length > Fabrication::Config.recursion_limit + raise Fabrication::InfiniteRecursionError, name if values.length > Fabrication::Config.recursion_limit end end @@ -76,5 +79,4 @@ def store(name, aliases, options, &block) schematic = schematics[name] = Fabrication::Schematic::Definition.new(name, options, &block) aliases.each { |as| schematics[as.to_sym] = schematic } end - end diff --git a/lib/fabrication/schematic/runner.rb b/lib/fabrication/schematic/runner.rb index 6d73d459..f15b3212 100644 --- a/lib/fabrication/schematic/runner.rb +++ b/lib/fabrication/schematic/runner.rb @@ -1,12 +1,11 @@ class Fabrication::Schematic::Runner - attr_accessor :klass def initialize(klass) self.klass = klass end - def sequence(name=Fabrication::Sequencer::DEFAULT, start=nil, &block) + def sequence(name = Fabrication::Sequencer::DEFAULT, start = nil, &block) name = "#{klass.to_s.downcase.gsub(/::/, '_')}_#{name}" Fabrication::Sequencer.sequence(name, start, &block) end diff --git a/lib/fabrication/sequencer.rb b/lib/fabrication/sequencer.rb index 8a8ecfc2..cc006179 100644 --- a/lib/fabrication/sequencer.rb +++ b/lib/fabrication/sequencer.rb @@ -1,13 +1,12 @@ class Fabrication::Sequencer - DEFAULT = :_default - def self.sequence(name=DEFAULT, start=nil, &block) + def self.sequence(name = DEFAULT, start = nil, &block) idx = sequences[name] ||= start || Fabrication::Config.sequence_start if block_given? sequence_blocks[name] = block.to_proc else - sequence_blocks[name] ||= lambda { |i| i } + sequence_blocks[name] ||= ->(i) { i } end.call(idx).tap do sequences[name] += 1 end diff --git a/lib/fabrication/support.rb b/lib/fabrication/support.rb index f153a6f4..2e31d9c3 100644 --- a/lib/fabrication/support.rb +++ b/lib/fabrication/support.rb @@ -1,7 +1,5 @@ class Fabrication::Support - class << self - def fabricatable?(name) Fabrication.manager[name] || class_for(name) end @@ -9,8 +7,8 @@ def fabricatable?(name) def class_for(class_or_to_s) class_name = variable_name_to_class_name(class_or_to_s) constantize(class_name) - rescue NameError => original_error - raise Fabrication::UnfabricatableError.new(class_or_to_s, original_error) + rescue NameError => e + raise Fabrication::UnfabricatableError.new(class_or_to_s, e) end def constantize(camel_cased_word) @@ -24,9 +22,11 @@ def constantize(camel_cased_word) candidate = constant.const_get(name) next candidate if constant.const_defined?(name, false) next candidate unless Object.const_defined?(name) + constant = constant.ancestors.inject do |const, ancestor| break const if ancestor == Object break ancestor if ancestor.const_defined?(name, false) + const end constant.const_get(name, false) @@ -39,11 +39,14 @@ def extract_options!(args) end def variable_name_to_class_name(name) - name.to_s.gsub(/\/(.?)/){"::#{$1.upcase}"}.gsub(/(?:^|_)(.)/){$1.upcase} + name.to_s.gsub(%r{/(.?)}) do + "::#{Regexp.last_match(1).upcase}" + end.gsub(/(?:^|_)(.)/) { Regexp.last_match(1).upcase } end def find_definitions - puts "DEPRECATION WARNING: Fabrication::Support.find_definitions has been replaced by Fabrication.manager.load_definitions and will be removed in 3.0.0." + puts 'DEPRECATION WARNING: Fabrication::Support.find_definitions has ' \ + 'been replaced by Fabrication.manager.load_definitions and will be removed in 3.0.0.' Fabrication.manager.load_definitions end @@ -53,18 +56,16 @@ def hash_class def singularize(string) string.singularize - rescue + rescue StandardError string.end_with?('s') ? string[0..-2] : string end def underscore(string) - string.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase + string.gsub(/::/, '/') + .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2') + .gsub(/([a-z\d])([A-Z])/, '\1_\2') + .tr('-', '_') + .downcase end - end - end diff --git a/lib/fabrication/syntax/make.rb b/lib/fabrication/syntax/make.rb index 0a3204b5..423291f7 100644 --- a/lib/fabrication/syntax/make.rb +++ b/lib/fabrication/syntax/make.rb @@ -1,6 +1,5 @@ module Fabrication module Syntax - # Extends Fabrication to provide make/make! class methods, which are # shortcuts for Fabricate.build/Fabricate. # diff --git a/lib/fabrication/transform.rb b/lib/fabrication/transform.rb index 28e5e736..62620870 100644 --- a/lib/fabrication/transform.rb +++ b/lib/fabrication/transform.rb @@ -1,10 +1,8 @@ class Fabrication::Transform - class << self - def apply_to(schematic, attributes_hash) Fabrication.manager.load_definitions if Fabrication.manager.empty? - attributes_hash.inject({}) {|h,(k,v)| h.update(k => apply_transform(schematic, k, v)) } + attributes_hash.inject({}) { |h, (k, v)| h.update(k => apply_transform(schematic, k, v)) } end def clear_all @@ -31,9 +29,7 @@ def apply_transform(schematic, attribute, value) end def transforms - @transforms ||= Hash.new(lambda {|value| value}) + @transforms ||= Hash.new(->(value) { value }) end - end - end diff --git a/lib/rails/generators/fabrication/cucumber_steps/cucumber_steps_generator.rb b/lib/rails/generators/fabrication/cucumber_steps/cucumber_steps_generator.rb index 635d3007..cbc006c3 100644 --- a/lib/rails/generators/fabrication/cucumber_steps/cucumber_steps_generator.rb +++ b/lib/rails/generators/fabrication/cucumber_steps/cucumber_steps_generator.rb @@ -3,13 +3,12 @@ module Fabrication module Generators class CucumberStepsGenerator < Rails::Generators::Base - def generate - template 'fabrication_steps.rb', "features/step_definitions/fabrication_steps.rb" + template 'fabrication_steps.rb', 'features/step_definitions/fabrication_steps.rb' end def self.source_root - @_fabrication_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates')) + @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates')) end end end diff --git a/lib/rails/generators/fabrication/cucumber_steps/templates/fabrication_steps.rb b/lib/rails/generators/fabrication/cucumber_steps/templates/fabrication_steps.rb index 3d323094..194d83fc 100644 --- a/lib/rails/generators/fabrication/cucumber_steps/templates/fabrication_steps.rb +++ b/lib/rails/generators/fabrication/cucumber_steps/templates/fabrication_steps.rb @@ -7,44 +7,44 @@ def with_ivars(fabricator) model = @they.last.class.to_s.underscore instance_variable_set("@#{model.pluralize}", @they) instance_variable_set("@#{model.singularize}", @they.last) - Fabrication::Cucumber::Fabrications[model.singularize.gsub(/\W+/,'_').downcase] = @they.last + Fabrication::Cucumber::Fabrications[model.singularize.gsub(/\W+/, '_').downcase] = @they.last end -Given /^(\d+) ([^"]*)$/ do |count, model_name| +Given(/^(\d+) ([^"]*)$/) do |count, model_name| with_ivars Fabrication::Cucumber::StepFabricator.new(model_name) do |fab| fab.n(count.to_i) end end -Given /^the following ([^"]*):$/ do |model_name, table| +Given(/^the following ([^"]*):$/) do |model_name, table| with_ivars Fabrication::Cucumber::StepFabricator.new(model_name) do |fab| fab.from_table(table) end end -Given /^that ([^"]*) has the following ([^"]*):$/ do |parent, child, table| - with_ivars Fabrication::Cucumber::StepFabricator.new(child, :parent => parent) do |fab| +Given(/^that ([^"]*) has the following ([^"]*):$/) do |parent, child, table| + with_ivars Fabrication::Cucumber::StepFabricator.new(child, parent: parent) do |fab| fab.from_table(table) end end -Given /^that ([^"]*) has (\d+) ([^"]*)$/ do |parent, count, child| - with_ivars Fabrication::Cucumber::StepFabricator.new(child, :parent => parent) do |fab| +Given(/^that ([^"]*) has (\d+) ([^"]*)$/) do |parent, count, child| + with_ivars Fabrication::Cucumber::StepFabricator.new(child, parent: parent) do |fab| fab.n(count.to_i) end end -Given /^(?:that|those) (.*) belongs? to that (.*)$/ do |children, parent| +Given(/^(?:that|those) (.*) belongs? to that (.*)$/) do |children, parent| with_ivars Fabrication::Cucumber::StepFabricator.new(parent) do |fab| fab.has_many(children) end end -Then /^I should see (\d+) ([^"]*) in the database$/ do |count, model_name| +Then(/^I should see (\d+) ([^"]*) in the database$/) do |count, model_name| expect(Fabrication::Cucumber::StepFabricator.new(model_name).klass.count).to eq(count.to_i) end -Then /^I should see the following (.*) in the database:$/ do |model_name, table| +Then(/^I should see the following (.*) in the database:$/) do |model_name, table| klass = Fabrication::Cucumber::StepFabricator.new(model_name).klass expect(klass.where(table.rows_hash.symbolize_keys).count).to eq(1) end diff --git a/lib/rails/generators/fabrication/model/model_generator.rb b/lib/rails/generators/fabrication/model/model_generator.rb index 43dd430f..cc91bf5d 100644 --- a/lib/rails/generators/fabrication/model/model_generator.rb +++ b/lib/rails/generators/fabrication/model/model_generator.rb @@ -3,22 +3,23 @@ module Fabrication module Generators class ModelGenerator < Rails::Generators::NamedBase - argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" - class_option :dir, :type => :string, :default => "spec/fabricators", :desc => "The directory where the fabricators should go" - class_option :extension, :type => :string, :default => "rb", :desc => "file extension name" + argument :attributes, type: :array, default: [], banner: 'field:type field:type' + class_option :dir, type: :string, default: 'spec/fabricators', + desc: 'The directory where the fabricators should go' + class_option :extension, type: :string, default: 'rb', desc: 'file extension name' def create_fabrication_file copy_attributes_from_model if attributes.empty? template_file = File.join( options[:dir], class_path, - "#{file_name}_fabricator.#{options[:extension].to_s}" + "#{file_name}_fabricator.#{options[:extension]}" ) template 'fabricator.erb', template_file end def self.source_root - @_fabrication_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates')) + @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates')) end private @@ -26,14 +27,13 @@ def self.source_root def copy_attributes_from_model model = class_name.constantize if defined?(ActiveRecord) && model < ActiveRecord::Base - self.attributes = model.columns_hash.map { |name, column| + self.attributes = model.columns_hash.map do |name, column| Rails::Generators::GeneratedAttribute.new(name, column.type) - } + end end - rescue + rescue StandardError # no table? no problem! end - end end end diff --git a/lib/tasks/defined_fabricators.rake b/lib/tasks/defined_fabricators.rake index 031e661a..009fb78e 100644 --- a/lib/tasks/defined_fabricators.rake +++ b/lib/tasks/defined_fabricators.rake @@ -1,30 +1,30 @@ namespace :fabrication do - desc "Display all registered fabricators by class" - task :list => :environment do + desc 'Display all registered fabricators by class' + task list: :environment do Fabrication.manager.load_definitions if Fabrication.manager.empty? if Fabrication.manager.schematics.none? - puts "No fabricators found" + puts 'No fabricators found' next end - groups = Fabrication.manager.schematics.group_by do |name, fabdef| + schematic_groups = Fabrication.manager.schematics.group_by do |_name, fabdef| fabdef.klass.name end fabricators = {} - groups.sort_by { |klass, _| klass }.each do |klass, groups| - fabricators[klass] = groups.map(&:first).sort.join(", ") + schematic_groups.sort_by { |klass, _| klass }.each do |klass, groups| + fabricators[klass] = groups.map(&:first).sort.join(', ') end - class_width = fabricators.keys.max_by { |v| v.size }.size + 3 # padding - names_width = fabricators.values.max_by { |v| v.size }.size + class_width = fabricators.keys.max_by(&:size).size + 3 # padding + names_width = fabricators.values.max_by(&:size).size say = lambda do |f1, f2| printf "%-#{class_width}s%-#{names_width}s\n", f1, f2 end - say["Class", "Fabricator"] - puts "-" * (names_width + class_width) - fabricators.each { |klass, names| say[klass,names] } + say['Class', 'Fabricator'] + puts '-' * (names_width + class_width) + fabricators.each { |klass, names| say[klass, names] } end end diff --git a/spec/fabricate_spec.rb b/spec/fabricate_spec.rb index 1c582629..60ecd589 100644 --- a/spec/fabricate_spec.rb +++ b/spec/fabricate_spec.rb @@ -1,59 +1,59 @@ require 'spec_helper' describe Fabricate do - describe ".times" do - it "fabricates an object X times" do - objects = Fabricate.times(3, :parent_ruby_object) + describe '.times' do + it 'fabricates an object X times' do + objects = described_class.times(3, :parent_ruby_object) expect(objects.length).to eq 3 expect(objects.all?(&:persisted?)).to be true end - it "delegates overrides and blocks properly" do - object = Fabricate.times(1, :parent_ruby_object, string_field: 'different').first + it 'delegates overrides and blocks properly' do + object = described_class.times(1, :parent_ruby_object, string_field: 'different').first expect(object.string_field).to eql('different') - object = Fabricate.times(1, :parent_ruby_object) { string_field 'other' }.first + object = described_class.times(1, :parent_ruby_object) { string_field 'other' }.first expect(object.string_field).to eql('other') end end - describe ".build_times" do - it "fabricates an object X times" do - objects = Fabricate.build_times(3, :parent_ruby_object) + describe '.build_times' do + it 'fabricates an object X times' do + objects = described_class.build_times(3, :parent_ruby_object) expect(objects.length).to eq 3 expect(objects.all?(&:persisted?)).to be false end - it "delegates overrides and blocks properly" do - object = Fabricate.build_times(1, :parent_ruby_object, string_field: 'different').first + it 'delegates overrides and blocks properly' do + object = described_class.build_times(1, :parent_ruby_object, string_field: 'different').first expect(object.string_field).to eql('different') - object = Fabricate.build_times(1, :parent_ruby_object) { string_field 'other' }.first + object = described_class.build_times(1, :parent_ruby_object) { string_field 'other' }.first expect(object.string_field).to eql('other') end end - describe ".attributes_for_times" do - it "fabricates an object X times" do - objects = Fabricate.attributes_for_times(3, :parent_ruby_object) + describe '.attributes_for_times' do + it 'fabricates an object X times' do + objects = described_class.attributes_for_times(3, :parent_ruby_object) expect(objects.length).to eq 3 expect(objects).to all be_a_kind_of(Hash) end - it "delegates overrides and blocks properly" do - object = Fabricate.attributes_for_times(1, :parent_ruby_object, string_field: 'different').first + it 'delegates overrides and blocks properly' do + object = described_class.attributes_for_times(1, :parent_ruby_object, string_field: 'different').first expect(object[:string_field]).to eql('different') - object = Fabricate.attributes_for_times(1, :parent_ruby_object) { string_field 'other' }.first + object = described_class.attributes_for_times(1, :parent_ruby_object) { string_field 'other' }.first expect(object[:string_field]).to eql('other') end end - describe ".to_params", depends_on: :active_record do - subject { Fabricate.to_params(:parent_active_record_model_with_children) } + describe '.to_params', depends_on: :active_record do + let(:as_params) { described_class.to_params(:parent_active_record_model_with_children) } - it do - should == { + it 'correctly serializes' do + expect(as_params).to eq( 'dynamic_field' => nil, 'nil_field' => nil, 'number_field' => 5, @@ -63,12 +63,12 @@ 'child_active_record_models' => [ { 'number_field' => 10 }, { 'number_field' => 10 } ] - } + ) end it 'is accessible as symbols' do - expect(subject[:number_field]).to eq(5) - expect(subject[:child_active_record_models].first[:number_field]).to eq(10) + expect(as_params[:number_field]).to eq(5) + expect(as_params[:child_active_record_models].first[:number_field]).to eq(10) end end end diff --git a/spec/fabrication/config_spec.rb b/spec/fabrication/config_spec.rb index 6792eb0a..bd8edee1 100644 --- a/spec/fabrication/config_spec.rb +++ b/spec/fabrication/config_spec.rb @@ -1,17 +1,18 @@ require 'spec_helper' describe Fabrication::Config do - subject { Fabrication::Config } - after { Fabrication::Config.reset_defaults } + subject { described_class } - context "default configs" do + after { described_class.reset_defaults } + + context 'with default configs' do its(:fabricator_path) { should == ['test/fabricators', 'spec/fabricators'] } its(:path_prefix) { should == ['.'] } its(:sequence_start) { should == 0 } end - describe ".fabricator_path" do - context "with a single folder" do + describe '.fabricator_path' do + context 'with a single folder' do before do Fabrication.configure do |config| config.fabricator_path = 'lib' @@ -21,19 +22,19 @@ its(:fabricator_path) { should == ['lib'] } end - context "with multiple folders" do + context 'with multiple folders' do before do Fabrication.configure do |config| - config.fabricator_path = %w(lib support) + config.fabricator_path = %w[lib support] end end - its(:fabricator_path) { should == ['lib', 'support'] } + its(:fabricator_path) { should == %w[lib support] } end end - describe ".path_prefix" do - context "with a single folder" do + describe '.path_prefix' do + context 'with a single folder' do before do Fabrication.configure do |config| config.path_prefix = '/path/to/app' @@ -43,10 +44,10 @@ its(:path_prefix) { should == ['/path/to/app'] } end - context "with multiple folders" do + context 'with multiple folders' do before do Fabrication.configure do |config| - config.path_prefix = %w(/path/to/app /path/to/gem/fabricators) + config.path_prefix = %w[/path/to/app /path/to/gem/fabricators] end end @@ -54,7 +55,7 @@ end end - describe ".register_generator" do + describe '.register_generator' do before do Fabrication.configure do |config| config.generators << ImmutableGenerator diff --git a/spec/fabrication/cucumber/step_fabricator_spec.rb b/spec/fabrication/cucumber/step_fabricator_spec.rb index a9d2b9fa..034e933c 100644 --- a/spec/fabrication/cucumber/step_fabricator_spec.rb +++ b/spec/fabrication/cucumber/step_fabricator_spec.rb @@ -5,116 +5,124 @@ describe '#klass' do context 'with a schematic for class "Boom"' do - subject { Fabrication::Cucumber::StepFabricator.new(name).klass } + subject { described_class.new(name).klass } + let(:fabricator_name) { :dog } before do - allow(Fabricate).to receive(:schematic).with(fabricator_name).and_return(double(klass: "Boom")) + allow(Fabricate).to receive(:schematic).with(fabricator_name).and_return(double(klass: 'Boom')) end - it { should == "Boom" } + it { should == 'Boom' } - context "given a human name" do - let(:name) { "weiner dogs" } + context 'with a human name' do + let(:name) { 'weiner dogs' } let(:fabricator_name) { :weiner_dog } - it { should == "Boom" } + + it { should == 'Boom' } end - context "given a titlecase human name" do - let(:name) { "Weiner Dog" } + context 'with a titlecase human name' do + let(:name) { 'Weiner Dog' } let(:fabricator_name) { :weiner_dog } - it { should == "Boom" } + + it { should == 'Boom' } end end end - describe "#n" do + describe '#n' do let(:n) { 3 } - let(:fabricator) { Fabrication::Cucumber::StepFabricator.new(name) } + let(:fabricator) { described_class.new(name) } - it "fabricates n times" do + it 'fabricates n times' do expect(Fabricate).to receive(:create).with(:dog, {}).exactly(n).times fabricator.n n end - it "fabricates with attrs" do - expect(Fabricate).to receive(:create). - with(:dog, :collar => 'red').at_least(1) - fabricator.n n, :collar => 'red' + it 'fabricates with attrs' do + expect(Fabricate).to receive(:create) + .with(:dog, collar: 'red').at_least(1) + fabricator.n n, collar: 'red' end context 'with a plural subject' do let(:name) { 'dogs' } + it 'remembers' do - allow(Fabricate).to receive(:create).and_return("dog1", "dog2", "dog3") + allow(Fabricate).to receive(:create).and_return('dog1', 'dog2', 'dog3') fabricator.n n - expect(Fabrication::Cucumber::Fabrications[name]).to eq(["dog1", "dog2", "dog3"]) + expect(Fabrication::Cucumber::Fabrications[name]).to eq(%w[dog1 dog2 dog3]) end end context 'with a singular subject' do let(:name) { 'dog' } + it 'remembers' do - allow(Fabricate).to receive(:create).and_return("dog1") + allow(Fabricate).to receive(:create).and_return('dog1') fabricator.n 1 expect(Fabrication::Cucumber::Fabrications[name]).to eq('dog1') end end - end describe '#from_table' do it 'maps column names to attribute names' do table = double(hashes: [{ 'Favorite Color' => 'pink' }]) - expect(Fabricate).to receive(:create).with(:bear, :favorite_color => 'pink') - Fabrication::Cucumber::StepFabricator.new('bears').from_table(table) + expect(Fabricate).to receive(:create).with(:bear, favorite_color: 'pink') + described_class.new('bears').from_table(table) end context 'with table transforms' do let(:table) { double(hashes: [{ 'some' => 'thing' }]) } + before { allow(Fabricate).to receive(:create) } it 'applies transforms' do - expect(Fabrication::Transform).to receive(:apply_to). - with('bears', {:some => 'thing'}).and_return({}) - Fabrication::Cucumber::StepFabricator.new('bears').from_table(table) + expect(Fabrication::Transform).to receive(:apply_to) + .with('bears', { some: 'thing' }).and_return({}) + described_class.new('bears').from_table(table) end end context 'with a plural subject' do - let(:table) { double("ASTable", :hashes => hashes) } + let(:table) { double('ASTable', hashes: hashes) } let(:hashes) do - [{'some' => 'thing'}, - {'some' => 'panother'}] + [{ 'some' => 'thing' }, + { 'some' => 'panother' }] end + it 'fabricates with each rows attributes' do - expect(Fabricate).to receive(:create).with(:dog, {:some => 'thing'}) - expect(Fabricate).to receive(:create).with(:dog, {:some => 'panother'}) - Fabrication::Cucumber::StepFabricator.new(name).from_table(table) + expect(Fabricate).to receive(:create).with(:dog, { some: 'thing' }) + expect(Fabricate).to receive(:create).with(:dog, { some: 'panother' }) + described_class.new(name).from_table(table) end + it 'remembers' do allow(Fabricate).to receive(:create).and_return('dog1', 'dog2') - Fabrication::Cucumber::StepFabricator.new(name).from_table(table) - expect(Fabrication::Cucumber::Fabrications[name]).to eq(["dog1", "dog2"]) + described_class.new(name).from_table(table) + expect(Fabrication::Cucumber::Fabrications[name]).to eq(%w[dog1 dog2]) end end - context 'singular' do + context 'when singular' do let(:name) { 'dog' } - let(:table) { double("ASTable", :rows_hash => rows_hash) } + let(:table) { double('ASTable', rows_hash: rows_hash) } let(:rows_hash) do - {'some' => 'thing'} + { 'some' => 'thing' } end + it 'fabricates with each row as an attribute' do - expect(Fabricate).to receive(:create).with(:dog, {:some => 'thing'}) - Fabrication::Cucumber::StepFabricator.new(name).from_table(table) + expect(Fabricate).to receive(:create).with(:dog, { some: 'thing' }) + described_class.new(name).from_table(table) end + it 'remembers' do allow(Fabricate).to receive(:create).and_return('dog1') - Fabrication::Cucumber::StepFabricator.new(name).from_table(table) - expect(Fabrication::Cucumber::Fabrications[name]).to eq("dog1") + described_class.new(name).from_table(table) + expect(Fabrication::Cucumber::Fabrications[name]).to eq('dog1') end end end - end diff --git a/spec/fabrication/generator/active_record_spec.rb b/spec/fabrication/generator/active_record_spec.rb index 08b5a33c..813ca9c9 100644 --- a/spec/fabrication/generator/active_record_spec.rb +++ b/spec/fabrication/generator/active_record_spec.rb @@ -1,82 +1,76 @@ require 'spec_helper' -describe Fabrication::Generator::ActiveRecord do - describe ".supports?" do - subject { Fabrication::Generator::ActiveRecord } - - # Defines a fakey ActiveRecord module that doesn't also have - # ActiveRecord::Base such as those written by instrumentation - # platforms e.g. Honeycomb - module ActiveRecord; end - - let(:active_record_fake) { ActiveRecord } - - it "returns false for active record objects without ar::base" do - expect(subject.supports?(active_record_fake)).to be false - end - end -end - describe Fabrication::Generator::ActiveRecord, depends_on: :active_record do - - describe ".supports?" do - subject { Fabrication::Generator::ActiveRecord } - - it "returns true for active record objects" do - expect(subject.supports?(ParentActiveRecordModel)).to be true - end - - it "returns false for non-active record objects" do - expect(subject.supports?(ParentRubyObject)).to be false + context 'when ActiveRecord is erroneously defined' do + describe '.supports?' do + # Defines a fakey ActiveRecord module that doesn't also have + # ActiveRecord::Base such as those written by instrumentation + # platforms e.g. Honeycomb + module ActiveRecord; end + + let(:active_record_fake) { ActiveRecord } + + it 'returns false for active record objects without ar::base' do + expect(described_class.supports?(active_record_fake)).to be false + end end end - describe "#persist" do - let(:instance) { double } - let(:generator) { Fabrication::Generator::ActiveRecord.new(ParentActiveRecordModel) } - - before { generator.send(:_instance=, instance) } + context 'when ActiveRecord is correctly defined', depends_on: :active_record do + describe '.supports?' do + it 'returns true for active record objects' do + expect(described_class.supports?(ParentActiveRecordModel)).to be true + end - it "saves" do - expect(instance).to receive(:save!) - generator.send(:persist) - end - end - - describe "#create" do - - let(:attributes) do - Fabrication::Schematic::Definition.new(ParentActiveRecordModel) do - string_field 'Different Content' - number_field { |attrs| attrs[:string_field].length } - child_active_record_models(count: 2) { |attrs, i| ChildActiveRecordModel.new(number_field: i) } - end.attributes + it 'returns false for non-active record objects' do + expect(described_class.supports?(ParentRubyObject)).to be false + end end - let(:generator) { Fabrication::Generator::ActiveRecord.new(ParentActiveRecordModel) } - let!(:parent_active_record_model) { generator.create(attributes, {}) } - let(:child_active_record_models) { parent_active_record_model.child_active_record_models } + describe '#persist' do + let(:instance) { double } + let(:generator) { described_class.new(ParentActiveRecordModel) } - it 'passes the object to blocks' do - expect(parent_active_record_model.number_field).to eq 17 - end + before { generator.send(:_instance=, instance) } - it 'passes the object and count to blocks' do - expect(child_active_record_models.map(&:number_field)).to eq [1, 2] + it 'saves' do + expect(instance).to receive(:save!) + generator.send(:persist) + end end - it 'persists the company upon creation' do - expect(ParentActiveRecordModel.where(string_field: 'Different Content').count).to eq 1 + describe '#create' do + let(:attributes) do + Fabrication::Schematic::Definition.new(ParentActiveRecordModel) do + string_field 'Different Content' + number_field { |attrs| attrs[:string_field].length } + child_active_record_models(count: 2) { |_attrs, i| ChildActiveRecordModel.new(number_field: i) } + end.attributes + end + + let(:generator) { described_class.new(ParentActiveRecordModel) } + let!(:parent_active_record_model) { generator.create(attributes, {}) } + let(:child_active_record_models) { parent_active_record_model.child_active_record_models } + + it 'passes the object to blocks' do + expect(parent_active_record_model.number_field).to eq 17 + end + + it 'passes the object and count to blocks' do + expect(child_active_record_models.map(&:number_field)).to eq [1, 2] + end + + it 'persists the company upon creation' do + expect(ParentActiveRecordModel.where(string_field: 'Different Content').count).to eq 1 + end + + it 'generates the divisions' do + expect(child_active_record_models.count).to eq 2 + end + + it 'persists the divisions' do + expect(ChildActiveRecordModel.where(parent_active_record_model_id: parent_active_record_model.id).count).to eq 2 + end end - - it 'generates the divisions' do - expect(child_active_record_models.count).to eq 2 - end - - it 'persists the divisions' do - expect(ChildActiveRecordModel.where(parent_active_record_model_id: parent_active_record_model.id).count).to eq 2 - end - end - end diff --git a/spec/fabrication/generator/base_spec.rb b/spec/fabrication/generator/base_spec.rb index 7d04157e..7905c8d8 100644 --- a/spec/fabrication/generator/base_spec.rb +++ b/spec/fabrication/generator/base_spec.rb @@ -1,22 +1,19 @@ require 'spec_helper' describe Fabrication::Generator::Base do - - describe ".supports?" do - subject { Fabrication::Generator::Base } - it "supports any object" do - expect(subject.supports?(Object)).to be true + describe '.supports?' do + it 'supports any object' do + expect(described_class.supports?(Object)).to be true end end - describe "#build" do - - let(:generator) { Fabrication::Generator::Base.new(ParentRubyObject) } + describe '#build' do + let(:generator) { described_class.new(ParentRubyObject) } let(:attributes) do Fabrication::Schematic::Definition.new('ParentRubyObject') do string_field 'different content' - extra_fields(count: 4) { |attrs, index| "field #{index}" } + extra_fields(count: 4) { |_attrs, index| "field #{index}" } end.attributes end @@ -27,17 +24,17 @@ end it 'passes the object and count to blocks' do - expect(parent_ruby_object.extra_fields).to eq (1..4).map { |i| "field #{i}" } + expect(parent_ruby_object.extra_fields).to eq((1..4).map { |i| "field #{i}" }) end it 'sets the static value' do expect(parent_ruby_object.instance_variable_get(:@string_field)).to eq 'different content' end - context "with on_init block" do - subject { schematic.fabricate } + context 'with on_init block' do + let(:fabricated_object) { schematic.fabricate } - context "using init_with" do + context 'when using init_with' do let(:schematic) do Fabrication::Schematic::Definition.new('ClassWithInit') do on_init { init_with(:a, :b) } @@ -45,76 +42,77 @@ end it "sends the return value of the block to the klass' initialize method" do - expect(subject.arg1).to eq(:a) - expect(subject.arg2).to eq(:b) + expect(fabricated_object.arg1).to eq(:a) + expect(fabricated_object.arg2).to eq(:b) end end - context "not using init_with" do + context 'when not using init_with' do let(:schematic) do Fabrication::Schematic::Definition.new('ClassWithInit') do - on_init { [ :a, :b ] } + on_init { %i[a b] } end end it "sends the return value of the block to the klass' initialize method" do - expect(subject.arg1).to eq(:a) - expect(subject.arg2).to eq(:b) + expect(fabricated_object.arg1).to eq(:a) + expect(fabricated_object.arg2).to eq(:b) end - end end - context "with initialize_with block" do - subject { schematic.fabricate } + context 'with initialize_with block' do + let(:fabricated_object) { schematic.fabricate } - context "using only raw values" do + context 'when using only raw values' do let(:schematic) do Fabrication::Schematic::Definition.new('ClassWithInit') do initialize_with { Struct.new(:arg1, :arg2).new(:fixed_value) } end end - it "saves the return value of the block as instance" do - expect(subject.arg1).to eq(:fixed_value) - expect(subject.arg2).to eq(nil) + it 'saves the return value of the block as instance' do + expect(fabricated_object.arg1).to eq(:fixed_value) + expect(fabricated_object.arg2).to eq(nil) end end - context "using attributes inside block" do + context 'when using attributes inside block' do let(:schematic) do - Fabrication::Schematic::Definition.new('ClassWithInit') do - arg1 10 - initialize_with { Struct.new(:arg1, :arg2).new(arg1, arg1.to_i + 10) } + Fabrication::Schematic::Definition.new('ClassWithInit') do + arg1 10 + initialize_with { Struct.new(:arg1, :arg2).new(arg1, arg1.to_i + 10) } end end - context "without override" do - it "saves the return value of the block as instance" do - expect(subject.arg1).to eq(10) - expect(subject.arg2).to eq(20) + context 'without override' do + it 'saves the return value of the block as instance' do + expect(fabricated_object.arg1).to eq(10) + expect(fabricated_object.arg2).to eq(20) end end - context "with override" do - subject { schematic.fabricate(arg1: 30) } - it "saves the return value of the block as instance" do - expect(subject.arg1).to eq(30) - expect(subject.arg2).to eq(40) + context 'with override' do + let(:fabricated_object) { schematic.fabricate(arg1: 30) } + + it 'saves the return value of the block as instance' do + expect(fabricated_object.arg1).to eq(30) + expect(fabricated_object.arg2).to eq(40) end end - context "with nil override" do - subject { schematic.fabricate(arg1: nil) } - it "saves the return value of the block as instance" do - expect(subject.arg1).to eq(nil) - expect(subject.arg2).to eq(10) + context 'with nil override' do + let(:fabricated_object) { schematic.fabricate(arg1: nil) } + + it 'saves the return value of the block as instance' do + expect(fabricated_object.arg1).to eq(nil) + expect(fabricated_object.arg2).to eq(10) end end end end - context "using an after_create hook" do + context 'when using an after_create hook' do let(:schematic) do Fabrication::Schematic::Definition.new('ParentRubyObject') do string_field 'something' @@ -122,25 +120,27 @@ end end - it "calls after_create when generated with saving" do + it 'calls after_create when generated with saving' do expect(schematic.fabricate.string_field).to eq 'SOMETHING' end - it "does not call after_create when generated without saving" do + it 'does not call after_create when generated without saving' do expect(schematic.build.string_field).to eq 'something' end end - context 'all the callbacks' do + context 'with all the callbacks' do subject { schematic.build } + let(:schematic) do Fabrication::Schematic::Definition.new('ParentRubyObject') do - string_field "" + string_field '' after_build { |k| k.string_field += '1' } before_validation { |k| k.string_field += '2' } after_validation { |k| k.string_field += '3' } end end + its(:string_field) { should == '1' } end @@ -155,7 +155,7 @@ Fabrication::Config.reset_defaults end - it "uses custom generator" do + it 'uses custom generator' do user = Fabricate(:immutable_user, name: 'foo') expect(user.name).to eq('foo') end @@ -163,11 +163,12 @@ end describe '#create' do - context 'all the callbacks' do + context 'with all the callbacks' do subject { schematic.fabricate } + let(:schematic) do Fabrication::Schematic::Definition.new('ParentRubyObject') do - string_field "" + string_field '' after_build { |k| k.string_field += '1' } before_validation { |k| k.string_field += '2' } after_validation { |k| k.string_field += '3' } @@ -177,13 +178,14 @@ after_save { |k| k.string_field += '7' } end end + its(:string_field) { should == '1234567' } end end - describe "#persist" do + describe '#persist' do let(:instance) { double } - let(:generator) { Fabrication::Generator::Base.new(Object) } + let(:generator) { described_class.new(Object) } before { generator.send(:_instance=, instance) } @@ -195,9 +197,8 @@ describe 'robustness tests' do it 'maintains valid state on exceptions while building' do - expect { Fabricate.build(:troublemaker, raise_exception: true) }.to raise_exception "Troublemaker exception" + expect { Fabricate.build(:troublemaker, raise_exception: true) }.to raise_exception 'Troublemaker exception' expect(Fabricate(:parent_ruby_object)).to be_persisted end end - end diff --git a/spec/fabrication/generator/data_mapper_spec.rb b/spec/fabrication/generator/data_mapper_spec.rb index c0670b56..e5b54e04 100644 --- a/spec/fabrication/generator/data_mapper_spec.rb +++ b/spec/fabrication/generator/data_mapper_spec.rb @@ -2,14 +2,12 @@ describe Fabrication::Generator::DataMapper, depends_on: :data_mapper do describe '.supports?' do - subject { Fabrication::Generator::DataMapper } - it 'returns true for datamapper objects' do - expect(subject.supports?(ParentDataMapperModel)).to be true + expect(described_class.supports?(ParentDataMapperModel)).to be true end it 'returns false for non-datamapper objects objects' do - expect(subject.supports?(ParentRubyObject)).to be false + expect(described_class.supports?(ParentRubyObject)).to be false end end end diff --git a/spec/fabrication/schematic/attribute_spec.rb b/spec/fabrication/schematic/attribute_spec.rb index a0017d2d..175f796d 100644 --- a/spec/fabrication/schematic/attribute_spec.rb +++ b/spec/fabrication/schematic/attribute_spec.rb @@ -1,68 +1,72 @@ require 'spec_helper' describe Fabrication::Schematic::Attribute do - - describe ".new" do - context "with name, params, and a static value" do + describe '.new' do + context 'with name, params, and a static value' do subject do - Fabrication::Schematic::Attribute.new(Object, "a", "c", {:b => 1}) + described_class.new(Object, 'a', 'c', { b: 1 }) end its(:klass) { should == Object } - its(:name) { should == "a" } - its(:params) { should == {:b => 1} } - its(:value) { should == "c" } + its(:name) { should == 'a' } + its(:params) { should == { b: 1 } } + its(:value) { should == 'c' } it { should_not be_transient } end - context "with a block value" do - subject do - Fabrication::Schematic::Attribute.new(Object, "a", Proc.new { "c" }) + context 'with a block value' do + let(:attribute) do + described_class.new(Object, 'a', proc { 'c' }) end - it "has a proc for a value" do - expect(Proc).to be === subject.value + it 'has a proc for a value' do + expect(attribute.value).to be_a(Proc) end end - context "with nils" do - subject { Fabrication::Schematic::Attribute.new(Object, "a", nil) } + context 'with nils' do + subject { described_class.new(Object, 'a', nil) } + its(:params) { should == {} } its(:value) { should be_nil } end end describe '#transient?' do - subject { Fabrication::Schematic::Attribute.new(Object, "a", nil, transient: true) } + subject { described_class.new(Object, 'a', nil, transient: true) } + it { should be_transient } end describe '#processed_value' do subject { attribute.processed_value({}) } - context 'singular value' do - let(:attribute) { Fabrication::Schematic::Attribute.new(Object, "a", "something") } + context 'with a singular value' do + let(:attribute) { described_class.new(Object, 'a', 'something') } + it { should == 'something' } end - context 'singular block' do + context 'with a singular block' do let(:attribute) do - Fabrication::Schematic::Attribute.new(Object, "a", nil, {}) { 'something' } + described_class.new(Object, 'a', nil, {}) { 'something' } end + it { should == 'something' } end - context 'collection block' do + context 'with a collection block' do let(:attribute) do - Fabrication::Schematic::Attribute.new(Object, "a", nil, {count: 2}) { 'something' } + described_class.new(Object, 'a', nil, { count: 2 }) { 'something' } end - it { should == %w(something something) } + + it { should == %w[something something] } end - context 'collection block with random amount' do + context 'with a collection block with random amount' do let(:random_amount) { 3 } let(:attribute) do - Fabrication::Schematic::Attribute.new(Object, "a", nil, {rand: random_amount}) { 'something' } + described_class.new(Object, 'a', nil, { rand: random_amount }) { 'something' } end it 'returns random number of items in collection with a max of passed in value' do @@ -70,10 +74,10 @@ end end - context 'collection block with random amount given as range' do + context 'with a collection block with random amount given as range' do let(:random_amount_range) { 10..21 } let(:attribute) do - Fabrication::Schematic::Attribute.new(Object, "a", nil, {rand: random_amount_range}) { 'something' } + described_class.new(Object, 'a', nil, { rand: random_amount_range }) { 'something' } end it 'returns random number of items in collection with a max of passed in value' do @@ -81,11 +85,13 @@ end end - context 'collection block with random amount within a range' do + context 'with a collection block with random amount within a range' do let(:range_start) { 10 } let(:range_end) { 21 } let(:attribute) do - Fabrication::Schematic::Attribute.new(Object, "a", nil, {start_range: range_start, end_range: range_end}) { 'something' } + described_class.new(Object, 'a', nil, { start_range: range_start, end_range: range_end }) do + 'something' + end end it 'returns random number of items in collection with a min and max of passed in value' do diff --git a/spec/fabrication/schematic/definition_spec.rb b/spec/fabrication/schematic/definition_spec.rb index 2cad845b..52df61b7 100644 --- a/spec/fabrication/schematic/definition_spec.rb +++ b/spec/fabrication/schematic/definition_spec.rb @@ -1,181 +1,184 @@ require 'spec_helper' describe Fabrication::Schematic::Definition do - let(:schematic) do - Fabrication::Schematic::Definition.new('OpenStruct') do - name "Orgasmo" - something(:param => 2) { "hi!" } + described_class.new('OpenStruct') do + name 'Orgasmo' + something(param: 2) { 'hi!' } another_thing { 25 } end end - describe "generator selection" do - subject { Fabrication::Schematic::Definition.new(klass).generator } + describe 'generator selection' do + subject { described_class.new(klass).generator } - context "for an activerecord object", depends_on: :active_record do + context 'with an activerecord object', depends_on: :active_record do let(:klass) { 'ParentActiveRecordModel' } + it { should == Fabrication::Generator::ActiveRecord } end - context "for a mongoid object", depends_on: :mongoid do + context 'with a mongoid object', depends_on: :mongoid do let(:klass) { 'ParentMongoidDocument' } + it { should == Fabrication::Generator::Mongoid } end - context "for a sequel object", depends_on: :sequel do + context 'with a sequel object', depends_on: :sequel do let(:klass) { 'ParentSequelModel' } + it { should == Fabrication::Generator::Sequel } end end - describe ".new" do - it "stores the name" do + describe '.new' do + it 'stores the name' do expect(schematic.name).to eq('OpenStruct') end - it "stores the generator" do + + it 'stores the generator' do expect(schematic.generator).to eq(Fabrication::Generator::Base) end - it "stores the attributes" do + + it 'stores the attributes' do expect(schematic.attributes.size).to eq(3) end end - describe "#attribute" do - it "returns the requested attribute if it exists" do + describe '#attribute' do + it 'returns the requested attribute if it exists' do expect(schematic.attribute(:name).name).to eq(:name) end - it "returns nil if it does not exist" do + + it 'returns nil if it does not exist' do expect(schematic.attribute(:not_there)).to be_nil end end - describe "#attributes" do - it "loads the fabricator body" do + describe '#attributes' do + it 'loads the fabricator body' do schematic.attributes = nil expect(schematic).to receive(:load_body) expect(schematic.attributes).to eq([]) end end - describe "#callbacks" do - it "loads the fabricator body" do + describe '#callbacks' do + it 'loads the fabricator body' do schematic.callbacks = nil expect(schematic).to receive(:load_body) expect(schematic.callbacks).to eq({}) end end - describe "#fabricate" do - context "an instance" do - it "generates a new instance" do + describe '#fabricate' do + context 'with an instance' do + it 'generates a new instance' do expect(schematic.fabricate).to be_kind_of(OpenStruct) end end end - describe "#to_attributes" do + describe '#to_attributes' do let(:hash) { schematic.to_attributes } it "generates a hash with the object's attributes" do expect(hash).to be_kind_of(Hash) end - it "has the correct attributes" do + it 'has the correct attributes' do expect(hash.size).to eq(3) expect(hash[:name]).to eq('Orgasmo') - expect(hash[:something]).to eq("hi!") + expect(hash[:something]).to eq('hi!') expect(hash[:another_thing]).to eq(25) end end - describe "#merge" do - - context "without inheritance" do - - subject { schematic.merge } + describe '#merge' do + context 'without inheritance' do + let(:merged_schematic) { schematic.merge } - it { should_not == schematic } + it 'creates a new schematic' do + expect(merged_schematic).not_to eq(schematic) + end it "stored 'name' correctly" do - attribute = subject.attribute(:name) + attribute = merged_schematic.attribute(:name) expect(attribute.name).to eq(:name) expect(attribute.params).to eq({}) - expect(attribute.value).to eq("Orgasmo") + expect(attribute.value).to eq('Orgasmo') end it "stored 'something' correctly" do - attribute = subject.attribute(:something) + attribute = merged_schematic.attribute(:something) expect(attribute.name).to eq(:something) - expect(attribute.params).to eq({ :param => 2 }) - expect(Proc).to be === attribute.value - expect(attribute.value.call).to eq("hi!") + expect(attribute.params).to eq({ param: 2 }) + expect(attribute.value).to be_a(Proc) + expect(attribute.value.call).to eq('hi!') end it "stored 'another_thing' correctly" do - attribute = subject.attribute(:another_thing) + attribute = merged_schematic.attribute(:another_thing) expect(attribute.name).to eq(:another_thing) expect(attribute.params).to eq({}) - expect(Proc).to be === attribute.value + expect(attribute.value).to be_a(Proc) expect(attribute.value.call).to eq(25) end - end - context "with inheritance" do - - subject do + context 'with inheritance' do + let(:merged_schematic) do schematic.merge do - name { "Willis" } - something "Else!" - another_thing(:thats_what => 'she_said') { "Boo-ya!" } + name { 'Willis' } + something 'Else!' + another_thing(thats_what: 'she_said') { 'Boo-ya!' } end end - it { should_not == schematic } + it 'creates a new schematic' do + expect(merged_schematic).not_to eq(schematic) + end it "stored 'name' correctly" do - attribute = subject.attribute(:name) + attribute = merged_schematic.attribute(:name) expect(attribute.name).to eq(:name) expect(attribute.params).to eq({}) - expect(Proc).to be === attribute.value - expect(attribute.value.call).to eq("Willis") + expect(attribute.value).to be_a(Proc) + expect(attribute.value.call).to eq('Willis') end it "stored 'something' correctly" do - attribute = subject.attribute(:something) + attribute = merged_schematic.attribute(:something) expect(attribute.name).to eq(:something) expect(attribute.params).to eq({}) - expect(attribute.value).to eq("Else!") + expect(attribute.value).to eq('Else!') end it "stored 'another_thing' correctly" do - attribute = subject.attribute(:another_thing) + attribute = merged_schematic.attribute(:another_thing) expect(attribute.name).to eq(:another_thing) - expect(attribute.params).to eq({ :thats_what => 'she_said' }) - expect(Proc).to be === attribute.value - expect(attribute.value.call).to eq("Boo-ya!") + expect(attribute.params).to eq({ thats_what: 'she_said' }) + expect(attribute.value).to be_a(Proc) + expect(attribute.value.call).to eq('Boo-ya!') end - end - end - describe "#on_init" do - let(:init_block) { lambda {} } + describe '#on_init' do + let(:init_block) { -> {} } let(:init_schematic) do block = init_block - Fabrication::Schematic::Definition.new('OpenStruct') do + described_class.new('OpenStruct') do on_init(&block) end end - it "stores the on_init callback" do + it 'stores the on_init callback' do expect(init_schematic.callbacks[:on_init]).to eq(init_block) end - context "with inheritance" do - let(:child_block) { lambda {} } + context 'with inheritance' do + let(:child_block) { -> {} } let(:child_schematic) do block = child_block init_schematic.merge do @@ -183,27 +186,27 @@ end end - it "overwrites the on_init callback" do + it 'overwrites the on_init callback' do expect(child_schematic.callbacks[:on_init]).to eq(child_block) end end end - describe "#initialize_with" do - let(:init_block) { lambda {} } + describe '#initialize_with' do + let(:init_block) { -> {} } let(:init_schematic) do block = init_block - Fabrication::Schematic::Definition.new('OpenStruct') do + described_class.new('OpenStruct') do initialize_with(&block) end end - it "stores the initialize_with callback" do + it 'stores the initialize_with callback' do expect(init_schematic.callbacks[:initialize_with]).to eq(init_block) end - context "with inheritance" do - let(:child_block) { lambda {} } + context 'with inheritance' do + let(:child_block) { -> {} } let(:child_schematic) do block = child_block init_schematic.merge do @@ -211,7 +214,7 @@ end end - it "overwrites the initialize_with callback" do + it 'overwrites the initialize_with callback' do expect(child_schematic.callbacks[:initialize_with]).to eq(child_block) end end @@ -219,8 +222,8 @@ describe '#transient' do let(:definition) do - Fabrication::Schematic::Definition.new('OpenStruct') do - transient :one, :two => 'with a default value', :three => 200 + described_class.new('OpenStruct') do + transient :one, two: 'with a default value', three: 200 end end @@ -228,7 +231,7 @@ expect(definition.attributes.map(&:transient?)).to eq([true, true, true]) end - it "accept default value" do + it 'accept default value' do expect(definition.attributes[1].name).to eq(:two) expect(definition.attributes[1].value).to eq('with a default value') expect(definition.attributes[2].name).to eq(:three) @@ -236,26 +239,29 @@ end end - context "when overriding" do - it "symbolizes attribute keys" do + context 'when overriding' do + it 'symbolizes attribute keys' do expect(Fabricate.build(:parent_ruby_object, 'string_field' => 'valid').string_field).to eq 'valid' end end describe '#sorted_attributes' do subject { definition.sorted_attributes.map(&:name) } + let(:definition) do - Fabrication::Schematic::Definition.new('OpenStruct') do + described_class.new('OpenStruct') do three { nil } one '' transient :two end end - it { should == [:one, :two, :three] } + + it { should == %i[one two three] } end describe '#klass' do subject { schematic.klass } + it { should be OpenStruct } end end diff --git a/spec/fabrication/schematic/evaluator_spec.rb b/spec/fabrication/schematic/evaluator_spec.rb index 16c1a9ac..9f4bab10 100644 --- a/spec/fabrication/schematic/evaluator_spec.rb +++ b/spec/fabrication/schematic/evaluator_spec.rb @@ -2,10 +2,11 @@ describe Fabrication::Schematic::Evaluator do let(:definition) { Fabrication::Schematic::Definition.new(ParentRubyObject) } - let(:evaluator) { Fabrication::Schematic::Evaluator.new } + let(:evaluator) { described_class.new } describe 'attribute handling' do - subject { definition.attributes.first } + let(:first_attribute) { definition.attributes.first } + before { evaluator.process(definition, &block) } context 'without a count' do @@ -14,9 +15,13 @@ dynamic_field { Fabricate(:child_ruby_object) } end end - its(:name) { should == :dynamic_field } + + it 'stores the name' do + expect(first_attribute.name).to eq(:dynamic_field) + end + it 'the attribute produces the correct value' do - expect(subject.processed_value({})).to be_kind_of(ChildRubyObject) + expect(first_attribute.processed_value({})).to be_kind_of(ChildRubyObject) end end @@ -26,9 +31,13 @@ dynamic_field(count: 2) { Fabricate(:child_ruby_object) } end end - its(:name) { should == :dynamic_field } + + it 'stores the name' do + expect(first_attribute.name).to eq(:dynamic_field) + end + it 'the attribute produces the correct value' do - expect(subject.processed_value({}).first).to be_kind_of(ChildRubyObject) + expect(first_attribute.processed_value({}).first).to be_kind_of(ChildRubyObject) end end end diff --git a/spec/fabrication/schematic/manager_spec.rb b/spec/fabrication/schematic/manager_spec.rb index ea66816c..03e4f93f 100644 --- a/spec/fabrication/schematic/manager_spec.rb +++ b/spec/fabrication/schematic/manager_spec.rb @@ -1,59 +1,59 @@ require 'spec_helper' describe Fabrication::Schematic::Manager do + let(:manager) { described_class.instance } - let(:manager) { Fabrication::Schematic::Manager.instance } before { manager.clear } - describe "#register" do - subject { manager } - - let(:options) { { aliases: ["thing_one", :thing_two] } } + describe '#register' do + let(:options) { { aliases: ['thing_one', :thing_two] } } before do manager.register(:open_struct, options) do - first_name "Joe" - last_name { "Schmoe" } + first_name 'Joe' + last_name { 'Schmoe' } end end - it "creates a schematic" do - expect(subject.schematics[:open_struct]).to be + it 'creates a schematic' do + expect(manager.schematics[:open_struct]).to be_present end - it "infers the correct class" do - expect(subject.schematics[:open_struct].send(:klass)).to eq(OpenStruct) + it 'infers the correct class' do + expect(manager.schematics[:open_struct].send(:klass)).to eq(OpenStruct) end - it "has the attributes" do - expect(subject.schematics[:open_struct].attributes.size).to eq(2) + it 'has the attributes' do + expect(manager.schematics[:open_struct].attributes.size).to eq(2) end - context "with an alias" do - it "recognizes the aliases" do - expect(subject.schematics[:thing_one]).to eq(subject.schematics[:open_struct]) - expect(subject.schematics[:thing_two]).to eq(subject.schematics[:open_struct]) + context 'with an alias' do + it 'recognizes the aliases' do + expect(manager.schematics[:thing_one]).to eq(manager.schematics[:open_struct]) + expect(manager.schematics[:thing_two]).to eq(manager.schematics[:open_struct]) end end - end describe '#[]' do subject { manager[key] } + before { manager.schematics[:some] = 'thing' } context 'with a symbol' do let(:key) { :some } + it { should == 'thing' } end context 'with a string' do let(:key) { 'some' } + it { should == 'thing' } end end - describe ".load_definitions" do + describe '.load_definitions' do before { Fabrication.clear_definitions } context 'with multiple path_prefixes and fabricator_paths' do @@ -64,10 +64,10 @@ end end - context 'happy path' do - it "loaded definitions" do + context 'with the happy path' do + it 'loaded definitions' do Fabrication.manager.load_definitions - expect(Fabrication.manager[:parent_ruby_object]).to be + expect(Fabrication.manager[:parent_ruby_object]).to be_present end end @@ -79,5 +79,4 @@ end end end - end diff --git a/spec/fabrication/sequencer_spec.rb b/spec/fabrication/sequencer_spec.rb index a1e07e44..c75f3f10 100644 --- a/spec/fabrication/sequencer_spec.rb +++ b/spec/fabrication/sequencer_spec.rb @@ -1,18 +1,17 @@ require 'spec_helper' describe Fabrication::Sequencer do - context 'with no arguments' do - subject { Fabrication::Sequencer.sequence } + subject { described_class.sequence } it { should == 0 } + it 'creates a default sequencer' do - expect(Fabrication::Sequencer.sequences[:_default]).to eq(1) + expect(described_class.sequences[:_default]).to eq(1) end end context 'with only a name' do - it 'starts with 0' do expect(Fabricate.sequence(:incr)).to eq(0) end @@ -30,11 +29,9 @@ expect(Fabricate.sequence(:number)).to eq(2) expect(Fabricate.sequence(:number)).to eq(3) end - end context 'with a name and starting number' do - it 'starts with the number provided' do expect(Fabricate.sequence(:higher, 69)).to eq(69) end @@ -45,44 +42,45 @@ expect(Fabricate.sequence(:higher)).to eq(72) expect(Fabricate.sequence(:higher)).to eq(73) end - end context 'with a block' do - it 'yields the number to the block and returns the value' do expect(Fabricate.sequence(:email) do |i| "user#{i}@example.com" - end).to eq("user0@example.com") + end).to eq('user0@example.com') end it 'increments by one with each call' do expect(Fabricate.sequence(:email) do |i| "user#{i}@example.com" - end).to eq("user1@example.com") + end).to eq('user1@example.com') expect(Fabricate.sequence(:email) do |i| "user#{i}@example.com" - end).to eq("user2@example.com") + end).to eq('user2@example.com') end - context 'and then without a block' do + context 'without a block' do it 'remembers the original block' do Fabricate.sequence :changing_blocks do |i| i * 10 end expect(Fabricate.sequence(:changing_blocks)).to eq(10) end - context 'and then with a new block' do + + context 'with a new block' do it 'evaluates the new block' do - expect(Fabricate.sequence(:changing_blocks) { |i| i ** 2 }).to eq(4) + expect(Fabricate.sequence(:changing_blocks) { |i| i**2 }).to eq(4) end + it 'remembers the new block' do expect(Fabricate.sequence(:changing_blocks)).to eq(9) end end end end + context 'with two sequences declared with blocks' do it 'remembers both blocks' do Fabricate.sequence(:shapes) do |i| @@ -96,22 +94,22 @@ end end - context "with a default sequence start" do + context 'with a default sequence start' do before do - Fabrication::Sequencer.reset - Fabrication::Config.sequence_start = 10000 + described_class.reset + Fabrication::Config.sequence_start = 10_000 end - it "starts a new sequence at the default" do - expect(Fabricate.sequence(:default_test)).to eq(10000) + after do + described_class.reset end - it "respects start value passed as an argument" do - expect(Fabricate.sequence(:default_test2, 9)).to eq(9) + it 'starts a new sequence at the default' do + expect(Fabricate.sequence(:default_test)).to eq(10_000) end - after do - Fabrication::Sequencer.reset + it 'respects start value passed as an argument' do + expect(Fabricate.sequence(:default_test2, 9)).to eq(9) end end end diff --git a/spec/fabrication/support_spec.rb b/spec/fabrication/support_spec.rb index 983a0012..be471539 100644 --- a/spec/fabrication/support_spec.rb +++ b/spec/fabrication/support_spec.rb @@ -4,30 +4,30 @@ describe '.class_for' do context 'with a class that exists' do it 'returns the class for a class' do - expect(Fabrication::Support.class_for(Object)).to eq(Object) + expect(described_class.class_for(Object)).to eq(Object) end it 'returns the class for a class name string' do - expect(Fabrication::Support.class_for('object')).to eq(Object) + expect(described_class.class_for('object')).to eq(Object) end it 'returns the class for a class name symbol' do - expect(Fabrication::Support.class_for(:object)).to eq(Object) + expect(described_class.class_for(:object)).to eq(Object) end end context "with a class that doesn't exist" do it 'returns nil for a class name string' do - expect { Fabrication::Support.class_for('your_mom') } + expect { described_class.class_for('your_mom') } .to raise_error(Fabrication::UnfabricatableError) end it 'returns nil for a class name symbol' do - expect { Fabrication::Support.class_for(:your_mom) } + expect { described_class.class_for(:your_mom) } .to raise_error(Fabrication::UnfabricatableError) end - context 'and custom const_missing is defined' do + context 'when custom const_missing is defined' do before do module Family def self.const_missing(_name) @@ -37,7 +37,7 @@ def self.const_missing(_name) end it 'raises an exception with the message from the original exception' do - expect { Fabrication::Support.class_for('Family::Mom') } + expect { described_class.class_for('Family::Mom') } .to raise_error(Fabrication::UnfabricatableError, /original message/) end end @@ -45,7 +45,7 @@ def self.const_missing(_name) end describe '.hash_class', depends_on: :active_support do - subject { Fabrication::Support.hash_class } + subject { described_class.hash_class } before do pending unless defined?(HashWithIndifferentAccess) @@ -58,12 +58,12 @@ def self.const_missing(_name) context 'without HashWithIndifferentAccess defined' do before do TempHashWithIndifferentAccess = HashWithIndifferentAccess - Fabrication::Support.instance_variable_set('@hash_class', nil) + described_class.instance_variable_set('@hash_class', nil) Object.send(:remove_const, :HashWithIndifferentAccess) end after do - Fabrication::Support.instance_variable_set('@hash_class', nil) + described_class.instance_variable_set('@hash_class', nil) HashWithIndifferentAccess = TempHashWithIndifferentAccess end diff --git a/spec/fabrication/syntax/make_spec.rb b/spec/fabrication/syntax/make_spec.rb index 3965404a..4353ac1b 100644 --- a/spec/fabrication/syntax/make_spec.rb +++ b/spec/fabrication/syntax/make_spec.rb @@ -2,58 +2,54 @@ require 'fabrication/syntax/make' describe Fabrication::Syntax::Make do - - describe "#make mongoid", depends_on: :mongoid do - it "should return a fabricated object" do + describe '#make mongoid', depends_on: :mongoid do + it 'returns a fabricated object' do expect(ParentMongoidDocument.make).to be_instance_of ParentMongoidDocument end - it "should overwrite options" do - expect(ParentMongoidDocument.make(string_field: "N.Rodrigues").string_field).to eql("N.Rodrigues") + it 'overwrites options' do + expect(ParentMongoidDocument.make(string_field: 'N.Rodrigues').string_field).to eql('N.Rodrigues') end - it "should treat a first non-hash argument as fabrication name suffix" do + it 'treats a first non-hash argument as fabrication name suffix' do Fabricator(:parent_mongoid_document_with_handle, from: :parent_mongoid_document) - expect(ParentMongoidDocument.make(:with_handle).string_field).to eql("content") + expect(ParentMongoidDocument.make(:with_handle).string_field).to eql('content') end - it "should work the same as Fabricate.build" do + it 'works the same as Fabricate.build' do expect(ParentMongoidDocument.make).to be_new_record end - it "bang should be the same as Fabricate" do + it 'bang should be the same as Fabricate' do expect(ParentMongoidDocument.make!).not_to be_new_record end end - describe "#make activerecord", depends_on: :active_record do - - it "should return a fabricated object" do + describe '#make activerecord', depends_on: :active_record do + it 'returns a fabricated object' do expect(ParentActiveRecordModel.make).to be_instance_of ParentActiveRecordModel end - it "should work the same as Fabricate.build" do + it 'works the same as Fabricate.build' do expect(ParentActiveRecordModel.make).to be_new_record end - it "bang should be the same as Fabricate" do + it 'bang should be the same as Fabricate' do expect(ParentActiveRecordModel.make!).not_to be_new_record end - end - describe "#make sequel", depends_on: :sequel do - it "should return a fabricated object" do + describe '#make sequel', depends_on: :sequel do + it 'returns a fabricated object' do expect(ParentSequelModel.make).to be_instance_of ParentSequelModel end - it "should be the same as Fabricate.build" do + it 'is the same as Fabricate.build' do expect(ParentSequelModel.make).to eql(Fabricate.build(:parent_sequel_model)) end - it "bang should be the same as Fabricate" do + it 'bang should be the same as Fabricate' do expect(ParentSequelModel.make!.id).not_to be_nil end end - end diff --git a/spec/fabrication/transform_spec.rb b/spec/fabrication/transform_spec.rb index 7b0aa38d..ea0e0374 100644 --- a/spec/fabrication/transform_spec.rb +++ b/spec/fabrication/transform_spec.rb @@ -1,67 +1,78 @@ require 'spec_helper' describe Fabrication::Transform do - before do Fabrication.clear_definitions - Fabrication::Transform.clear_all + described_class.clear_all end describe '.apply_to' do - context 'find definitions' do - context 'transforms are empty' do + context 'with find definitions' do + context 'when transforms are empty' do it 'loads the definitions' do expect(Fabrication.manager).to receive(:load_definitions) - Fabrication::Transform.apply_to(nil, :name => 'Shay') + described_class.apply_to(nil, name: 'Shay') end end - context 'transforms are not empty' do + context 'when transforms are not empty' do it 'does not load the definitions' do - Fabrication::Transform.apply_to(nil, :name => 'Shay') + described_class.apply_to(nil, name: 'Shay') expect(Fabrication.manager).not_to receive(:load_definitions) - Fabrication::Transform.apply_to(nil, :name => 'Gabriel') + described_class.apply_to(nil, name: 'Gabriel') end end end context 'when there is a generic transform for that column' do before do - Fabrication::Transform.define(:city, lambda {|value| value.split.first}) + described_class.define(:city, ->(value) { value.split.first }) end - context 'fabricating an instance that is described by the per fabricator transform' do + context 'when fabricating an instance that is described by the per fabricator transform' do before do - Fabrication::Transform.only_for(:address, :city, lambda {|value| value.upcase}) + described_class.only_for(:address, :city, ->(value) { value.upcase }) end it 'applies the transform to the specified types' do - expect(Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'})).to eq({:city => 'JACKSONVILLE BEACH'}) + expect(described_class.apply_to( + :address, + { city: 'Jacksonville Beach' } + )).to eq({ city: 'JACKSONVILLE BEACH' }) end end - context 'no override has been defined' do + context 'when no override has been defined' do it 'applies the generic transform' do - expect(Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'})).to eq({:city => 'Jacksonville'}) + expect(described_class.apply_to( + :address, + { city: 'Jacksonville Beach' } + )).to eq({ city: 'Jacksonville' }) end end end context 'when no generic transform has been defined' do it 'does not change value' do - expect(Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'})).to eq({:city => 'Jacksonville Beach'}) + expect(described_class.apply_to( + :address, + { city: 'Jacksonville Beach' } + )).to eq({ city: 'Jacksonville Beach' }) end end - context 'ensuring precedence' do - context 'override is done before generic transform' do + context 'when ensuring precedence' do + context 'when override is done before generic transform' do before do - Fabrication::Transform.only_for(:address, :city, lambda {|value| value.upcase}) - Fabrication::Transform.define(:city, lambda {|value| value.split.first}) + described_class.only_for(:address, :city, ->(value) { value.upcase }) + described_class.define(:city, ->(value) { value.split.first }) end it 'applies corretly' do - expect(Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'})).to eq({:city => 'JACKSONVILLE BEACH'}) + expect(described_class.apply_to( + :address, + { city: 'Jacksonville Beach' } + )).to eq({ city: 'JACKSONVILLE BEACH' }) end end end @@ -69,28 +80,27 @@ describe '.clear_all' do it 'clears all transforms' do - Fabrication::Transform.define(:name, lambda {|value| value}) - Fabrication::Transform.only_for(:address, :name, lambda {|value| value}) - Fabrication::Transform.clear_all - expect(Fabrication::Transform.send(:transforms)).to be_empty - expect(Fabrication::Transform.send(:overrides)).to be_empty + described_class.define(:name, ->(value) { value }) + described_class.only_for(:address, :name, ->(value) { value }) + described_class.clear_all + expect(described_class.send(:transforms)).to be_empty + expect(described_class.send(:overrides)).to be_empty end end describe '.define' do it 'registers transform' do - expect { - Fabrication::Transform.define(:name, lambda {|value| value}) - }.to change(Fabrication::Transform, :transforms) + expect do + described_class.define(:name, ->(value) { value }) + end.to change(described_class, :transforms) end end describe '.only_for' do it 'registers an override transform for provided model' do - expect { - Fabrication::Transform.only_for(:address, :name, lambda {|value| value}) - }.to change(Fabrication::Transform, :overrides) + expect do + described_class.only_for(:address, :name, ->(value) { value }) + end.to change(described_class, :overrides) end end - end diff --git a/spec/fabricators/active_record_fabricator.rb b/spec/fabricators/active_record_fabricator.rb index 9bb179aa..0678ab30 100644 --- a/spec/fabricators/active_record_fabricator.rb +++ b/spec/fabricators/active_record_fabricator.rb @@ -1,12 +1,12 @@ if defined?(ActiveRecord) Fabricator(:parent_active_record_model) do - transient :placeholder, :transient_with_default => 'my custom value' + transient :placeholder, transient_with_default: 'my custom value' dynamic_field { |attrs| attrs[:placeholder] } nil_field nil number_field 5 string_field 'content' false_field false - extra_fields { Hash.new } + extra_fields { {} } before_validation do |object, transients| object.extra_fields[:transient_value] = transients[:placeholder] end diff --git a/spec/fabricators/data_mapper_fabricator.rb b/spec/fabricators/data_mapper_fabricator.rb index 2031bbf5..0c536dc3 100644 --- a/spec/fabricators/data_mapper_fabricator.rb +++ b/spec/fabricators/data_mapper_fabricator.rb @@ -1,12 +1,12 @@ if defined?(DataMapper) Fabricator(:parent_data_mapper_model) do - transient :placeholder, :transient_with_default => 'my custom value' + transient :placeholder, transient_with_default: 'my custom value' dynamic_field { |attrs| attrs[:placeholder] } nil_field nil number_field 5 string_field 'content' false_field false - extra_fields { Hash.new } + extra_fields { {} } before_validation do |object, transients| object.extra_fields[:transient_value] = transients[:placeholder] end diff --git a/spec/fabricators/mongoid_fabricator.rb b/spec/fabricators/mongoid_fabricator.rb index b9514245..e6742b79 100644 --- a/spec/fabricators/mongoid_fabricator.rb +++ b/spec/fabricators/mongoid_fabricator.rb @@ -1,12 +1,12 @@ if defined?(Mongoid) Fabricator(:parent_mongoid_document) do - transient :placeholder, :transient_with_default => 'my custom value' + transient :placeholder, transient_with_default: 'my custom value' dynamic_field { |attrs| attrs[:placeholder] } nil_field nil number_field 5 string_field 'content' false_field false - extra_fields { Hash.new } + extra_fields { {} } before_validation do |object, transients| object.extra_fields[:transient_value] = transients[:placeholder] end diff --git a/spec/fabricators/plain_old_ruby_object_fabricator.rb b/spec/fabricators/plain_old_ruby_object_fabricator.rb index 09874b00..590a4595 100644 --- a/spec/fabricators/plain_old_ruby_object_fabricator.rb +++ b/spec/fabricators/plain_old_ruby_object_fabricator.rb @@ -1,18 +1,18 @@ Fabricator(:parent_ruby_object) do dynamic_field { |attrs| attrs[:placeholder] } - transient :placeholder, :transient_with_default => 'my custom value' + transient :placeholder, transient_with_default: 'my custom value' nil_field nil number_field 5 string_field 'content' false_field false - extra_fields { Hash.new } + extra_fields { {} } before_validation do |object, transients| object.extra_fields[:transient_value] = transients[:placeholder] end end Fabricator(:parent_ruby_object_with_children, from: :parent_ruby_object) do - child_ruby_objects(:count => 2) + child_ruby_objects(count: 2) end Fabricator(:child_ruby_object) do diff --git a/spec/fabricators/sequel_fabricator.rb b/spec/fabricators/sequel_fabricator.rb index 9ea75b95..65456853 100644 --- a/spec/fabricators/sequel_fabricator.rb +++ b/spec/fabricators/sequel_fabricator.rb @@ -1,12 +1,12 @@ if defined?(Sequel) Fabricator(:parent_sequel_model) do - transient :placeholder, :transient_with_default => 'my custom value' + transient :placeholder, transient_with_default: 'my custom value' dynamic_field { |attrs| attrs[:placeholder] } nil_field nil number_field 5 string_field 'content' false_field false - extra_fields { Hash.new } + extra_fields { {} } before_validation do |object, transients| object.extra_fields[:transient_value] = transients[:placeholder] end diff --git a/spec/fabricators/sequencer_fabricator.rb b/spec/fabricators/sequencer_fabricator.rb index ea412058..f19e2175 100644 --- a/spec/fabricators/sequencer_fabricator.rb +++ b/spec/fabricators/sequencer_fabricator.rb @@ -4,6 +4,6 @@ block_iterator { sequence(:block_iterator) { |i| "block#{i}" } } end -Fabricator("Sequencer::Namespaced") do +Fabricator('Sequencer::Namespaced') do iterator { sequence(:iterator) } end diff --git a/spec/fabricators/transforms.rb b/spec/fabricators/transforms.rb index 4762873a..16b65be7 100644 --- a/spec/fabricators/transforms.rb +++ b/spec/fabricators/transforms.rb @@ -1,3 +1,9 @@ -Fabrication::Transform.define(:parent_active_record_model, lambda{|string_field| ParentActiveRecordModel.find_by_string_field(string_field) }) -Fabrication::Transform.define(:parent_mongoid_document, lambda{|string_field| ParentMongoidDocument.where(string_field: string_field).one }) -Fabrication::Transform.define(:parent_sequel_model, lambda{|string_field| ParentSequelModel.where(string_field: string_field).first }) +Fabrication::Transform.define(:parent_active_record_model, lambda { |string_field| + ParentActiveRecordModel.find_by_string_field(string_field) +}) +Fabrication::Transform.define(:parent_mongoid_document, lambda { |string_field| + ParentMongoidDocument.where(string_field: string_field).one +}) +Fabrication::Transform.define(:parent_sequel_model, lambda { |string_field| + ParentSequelModel.where(string_field: string_field).first +}) diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb index e7b623ab..7204df1a 100644 --- a/spec/integration_spec.rb +++ b/spec/integration_spec.rb @@ -2,9 +2,10 @@ shared_examples 'something fabricatable' do subject { fabricated_object } + let(:fabricated_object) { Fabricate(fabricator_name, placeholder: 'dynamic content') } - context 'defaults from fabricator' do + context 'with defaults from fabricator' do its(:dynamic_field) { should == 'dynamic content' } its(:nil_field) { should be_nil } its(:number_field) { should == 5 } @@ -12,12 +13,12 @@ its(:false_field) { should == false } end - context 'model callbacks are fired' do + context 'when model callbacks are fired' do its(:before_validation_value) { should == 1 } its(:before_save_value) { should == 11 } end - context 'overriding at fabricate time' do + context 'when overriding at fabricate time' do let(:fabricated_object) do Fabricate( "#{fabricator_name}_with_children", @@ -35,30 +36,33 @@ its(:number_field) { should == 10 } its(:string_field) { should == 'new content' } - context 'child collections' do + context 'with child collections' do subject { fabricated_object.send(collection_field) } + its(:size) { should == 2 } its(:first) { should be_persisted } - its("first.number_field") { should == 10 } + its('first.number_field') { should == 10 } its(:last) { should be_persisted } - its("last.number_field") { should == 10 } + its('last.number_field') { should == 10 } end end - context 'state of the object' do + context 'with state of the object' do it 'generates a fresh object every time' do expect(Fabricate(fabricator_name)).not_to eq(subject) end + it { should be_persisted } end - context 'transient attributes' do + context 'with transient attributes' do it { should_not respond_to(:placeholder) } its(:extra_fields) { should == { transient_value: 'dynamic content' } } end - context 'build' do + context 'when build' do subject { Fabricate.build("#{fabricator_name}_with_children") } + it { should_not be_persisted } it 'cascades to child records' do @@ -68,24 +72,26 @@ end end - context 'attributes for' do + context 'when attributes for' do subject { Fabricate.attributes_for(fabricator_name) } + it { should be_kind_of(Fabrication::Support.hash_class) } + it 'serializes the attributes' do should include({ - :dynamic_field => nil, - :nil_field => nil, - :number_field => 5, - :string_field => 'content' - }) + dynamic_field: nil, + nil_field: nil, + number_field: 5, + string_field: 'content' + }) end end - context 'belongs_to associations' do + context 'with belongs_to associations' do subject { Fabricate("#{Fabrication::Support.singularize(collection_field.to_s)}_with_parent") } it 'sets the parent association' do - expect(subject.send(fabricator_name)).to be + expect(subject.send(fabricator_name)).to be_present end it 'sets the id of the associated object' do @@ -95,72 +101,80 @@ end describe Fabrication do - - context 'plain old ruby objects' do + context 'with plain old ruby objects' do let(:fabricator_name) { :parent_ruby_object } let(:collection_field) { :child_ruby_objects } - it_should_behave_like 'something fabricatable' + + it_behaves_like 'something fabricatable' end - context 'active_record models', depends_on: :active_record do + context 'with active_record models', depends_on: :active_record do let(:fabricator_name) { :parent_active_record_model } let(:collection_field) { :child_active_record_models } - it_should_behave_like 'something fabricatable' - context 'associations in attributes_for' do - let(:parent_model) { Fabricate(:parent_active_record_model) } + it_behaves_like 'something fabricatable' + + context 'with associations in attributes_for' do subject do Fabricate.attributes_for(:child_active_record_model, parent_active_record_model: parent_model) end + let(:parent_model) { Fabricate(:parent_active_record_model) } + it 'serializes the belongs_to as an id' do should include({ parent_active_record_model_id: parent_model.id }) end end - context 'association proxies' do + context 'with association proxies' do subject { parent_model.child_active_record_models.build } + let(:parent_model) { Fabricate(:parent_active_record_model_with_children) } + it { should be_kind_of(ChildActiveRecordModel) } end end - context 'data_mapper models', depends_on: :data_mapper do + context 'with data_mapper models', depends_on: :data_mapper do let(:fabricator_name) { :parent_data_mapper_model } let(:collection_field) { :child_data_mapper_models } - it_should_behave_like 'something fabricatable' + it_behaves_like 'something fabricatable' - context 'associations in attributes_for' do - let(:parent_model) { Fabricate(:parent_data_mapper_model) } + context 'with associations in attributes_for' do subject do Fabricate.attributes_for( :child_data_mapper_model, parent_data_mapper_model: parent_model ) end + let(:parent_model) { Fabricate(:parent_data_mapper_model) } + it 'serializes the belongs_to as an id' do should include({ parent_data_mapper_model_id: parent_model.id }) end end end - context 'referenced mongoid documents', depends_on: :mongoid do + context 'with referenced mongoid documents', depends_on: :mongoid do let(:fabricator_name) { :parent_mongoid_document } let(:collection_field) { :referenced_mongoid_documents } - it_should_behave_like 'something fabricatable' + + it_behaves_like 'something fabricatable' end - context 'embedded mongoid documents', depends_on: :mongoid do + context 'with embedded mongoid documents', depends_on: :mongoid do let(:fabricator_name) { :parent_mongoid_document } let(:collection_field) { :embedded_mongoid_documents } - it_should_behave_like 'something fabricatable' + + it_behaves_like 'something fabricatable' end - context 'sequel models', depends_on: :sequel do + context 'with sequel models', depends_on: :sequel do let(:fabricator_name) { :parent_sequel_model } let(:collection_field) { :child_sequel_models } - it_should_behave_like 'something fabricatable' + + it_behaves_like 'something fabricatable' context 'with class table inheritance' do before do @@ -178,40 +192,41 @@ end context 'when the class requires a constructor' do - before(:all) do - class CustomInitializer < Struct.new(:field1, :field2); end - Fabricator(:custom_initializer) - end - subject do Fabricate(:custom_initializer) do on_init { init_with('value1', 'value2') } end end - its(:field1) { should == 'value1' } + before do + CustomInitializer = Struct.new(:field1, :field2) + Fabricator(:custom_initializer) unless described_class.manager[:custom_initializer] + end + + its(:field1) { should == 'value1' } its(:field2) { should == 'value2' } end context 'with the generation parameter' do let(:parent_ruby_object) do - Fabricate(:parent_ruby_object, string_field: "Paul") do + Fabricate(:parent_ruby_object, string_field: 'Paul') do placeholder { |attrs| "#{attrs[:string_field]}#{attrs[:number_field]}" } number_field 50 end end it 'evaluates the fields in order of declaration' do - expect(parent_ruby_object.string_field).to eq("Paul") + expect(parent_ruby_object.string_field).to eq('Paul') end end context 'with a field named the same as an Object method' do subject { Fabricate(:predefined_namespaced_class, display: 'working') } + its(:display) { should == 'working' } end - context 'multiple instance' do + context 'with multiple instances' do let!(:parent_ruby_object1) { Fabricate(:parent_ruby_object, string_field: 'Jane') } let!(:parent_ruby_object2) { Fabricate(:parent_ruby_object, string_field: 'John') } @@ -224,7 +239,7 @@ class CustomInitializer < Struct.new(:field1, :field2); end end it 'they have different extra fields' do - expect(parent_ruby_object1.extra_fields).to_not equal(parent_ruby_object2.extra_fields) + expect(parent_ruby_object1.extra_fields).not_to equal(parent_ruby_object2.extra_fields) end end @@ -240,31 +255,33 @@ class CustomInitializer < Struct.new(:field1, :field2); end its(:string_field) { should == 'different' } end - context 'for namespaced classes' do - context 'the namespaced class' do + context 'with namespaced classes' do + context 'when the namespaced class' do subject { Fabricate('namespaced_classes/ruby_object', name: 'working') } + its(:name) { should eq('working') } it { should be_a(NamespacedClasses::RubyObject) } end - context 'descendant from namespaced class' do + context 'when descendant from namespaced class' do subject { Fabricate(:predefined_namespaced_class) } + its(:name) { should eq('aaa') } it { should be_a(NamespacedClasses::RubyObject) } end end context 'with a mongoid document', depends_on: :mongoid do - it "sets dynamic fields" do + it 'sets dynamic fields' do expect(Fabricate(:parent_mongoid_document, mongoid_dynamic_field: 50).mongoid_dynamic_field).to eq 50 end - it "sets lazy dynamic fields" do - expect(Fabricate(:parent_mongoid_document) { lazy_dynamic_field "foo" }.lazy_dynamic_field).to eq 'foo' + it 'sets lazy dynamic fields' do + expect(Fabricate(:parent_mongoid_document) { lazy_dynamic_field 'foo' }.lazy_dynamic_field).to eq 'foo' end - context "with disabled dynamic fields" do - it "raises NoMethodError for mongoid_dynamic_field=" do + context 'with disabled dynamic fields' do + it 'raises NoMethodError for mongoid_dynamic_field=' do if Mongoid.respond_to?(:allow_dynamic_fields=) Mongoid.allow_dynamic_fields = false expect do @@ -278,41 +295,51 @@ class CustomInitializer < Struct.new(:field1, :field2); end context 'with multiple callbacks' do subject { Fabricate(:multiple_callbacks) } - before(:all) do - Fabricator(:multiple_callbacks, from: OpenStruct) do - before_validation { |o| o.callback1 = 'value1' } - before_validation { |o| o.callback2 = 'value2' } + + before do + unless described_class.manager[:multiple_callbacks] + Fabricator(:multiple_callbacks, from: OpenStruct) do + before_validation { |o| o.callback1 = 'value1' } + before_validation { |o| o.callback2 = 'value2' } + end end end + its(:callback1) { should == 'value1' } its(:callback2) { should == 'value2' } end context 'with multiple, inherited callbacks' do subject { Fabricate(:multiple_inherited_callbacks) } - before(:all) do + + before do Fabricator(:multiple_inherited_callbacks, from: :multiple_callbacks) do before_validation { |o| o.callback3 = o.callback1 + o.callback2 } end end + its(:callback3) { 'value1value2' } end describe '.clear_definitions' do - before { Fabrication.clear_definitions } - subject { Fabrication.manager } + subject { described_class.manager } + + before { described_class.clear_definitions } + + after { described_class.manager.load_definitions } + it { should be_empty } - after { Fabrication.manager.load_definitions } end context 'when defining a fabricator twice' do it 'throws an error' do - expect { Fabricator(:parent_ruby_object) {} }.to raise_error(Fabrication::DuplicateFabricatorError) + expect { Fabricator(:parent_ruby_object) }.to raise_error(Fabrication::DuplicateFabricatorError) end end context "when fabricating class that doesn't exist" do before { Fabricator(:class_that_does_not_exist) } + it 'throws an error' do expect { Fabricate(:class_that_does_not_exist) }.to raise_error(Fabrication::UnfabricatableError) end @@ -324,36 +351,37 @@ class CustomInitializer < Struct.new(:field1, :field2); end end end - context 'defining a fabricator' do + context 'when defining a fabricator' do context 'without a block' do - before(:all) do + before do class Widget; end Fabricator(:widget) end it 'works fine' do - expect(Fabricate(:widget)).to be + expect(Fabricate(:widget)).to be_present end end end - describe "Fabricate with a sequence" do + describe 'Fabricate with a sequence' do subject { Fabricate(:sequencer) } its(:simple_iterator) { should == 0 } its(:param_iterator) { should == 10 } - its(:block_iterator) { should == "block2" } + its(:block_iterator) { should == 'block2' } - context "when namespaced" do - subject { Fabricate("Sequencer::Namespaced") } + context 'when namespaced' do + subject { Fabricate('Sequencer::Namespaced') } its(:iterator) { should == 0 } end end describe 'Fabricating while initializing' do - before { Fabrication.manager.preinitialize } - after { Fabrication.manager.freeze } + before { described_class.manager.preinitialize } + + after { described_class.manager.freeze } it 'throws an error' do expect { Fabricate(:your_mom) }.to raise_error(Fabrication::MisplacedFabricateError) @@ -363,31 +391,35 @@ class Widget; end describe 'using an actual class in options' do subject { Fabricate(:actual_class) } - context 'from' do + context 'with from' do before do Fabricator(:actual_class, from: OpenStruct) do name 'Hashrocket' end end - after { Fabrication.clear_definitions } + + after { described_class.clear_definitions } + its(:name) { should == 'Hashrocket' } it { should be_kind_of(OpenStruct) } end - context 'class_name' do + context 'with class_name' do before do Fabricator(:actual_class, class_name: OpenStruct) do name 'Hashrocket' end end - after { Fabrication.clear_definitions } + + after { described_class.clear_definitions } + its(:name) { should == 'Hashrocket' } it { should be_kind_of(OpenStruct) } end end describe 'accidentally an infinite recursion' do - context 'a single self-referencing fabricator' do + context 'with a single self-referencing fabricator' do before do Fabricator(:infinite_recursor, class_name: :child_ruby_object) do parent_ruby_object { Fabricate(:infinite_recursor) } @@ -404,7 +436,7 @@ class Widget; end end end - context 'a parent-child recursive scenario' do + context 'with a parent-child recursive scenario' do before do Fabricator(:parent_recursor, class_name: :parent_ruby_object) do child_ruby_objects(count: 1, fabricator: :child_recursor) @@ -427,7 +459,7 @@ class Widget; end end describe 'using the rand option' do - before { Fabrication.clear_definitions } + before { described_class.clear_definitions } context 'with an integer' do let!(:parent) do @@ -455,5 +487,4 @@ class Widget; end end end end - end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1773216b..6b1b1143 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -12,11 +12,9 @@ # Requires supporting files with custom matchers and macros, etc, # in ./support/ and its subdirectories. -Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','*.rb'))].each {|f| require f} +Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support', '*.rb'))].sort.each { |f| require f } -if defined?(I18n) - I18n.enforce_available_locales = false -end +I18n.enforce_available_locales = false if defined?(I18n) RSpec.configure do |config| config.raise_errors_for_deprecations! @@ -25,7 +23,7 @@ example.run if DEFINED_CLASSES.fetch(example.metadata[:depends_on], true) end - config.before(:each) do + config.before do TestMigration.up if DEFINED_CLASSES[:active_record] clear_mongodb end diff --git a/spec/support/active_record.rb b/spec/support/active_record.rb index b0780cf1..926f3520 100644 --- a/spec/support/active_record.rb +++ b/spec/support/active_record.rb @@ -1,23 +1,26 @@ if defined?(ActiveRecord) dbconfig = { - :adapter => 'sqlite3', - :database => ':memory:' + adapter: 'sqlite3', + database: ':memory:' } ActiveRecord::Base.establish_connection(dbconfig) ActiveRecord::Migration.verbose = false - migrationBaseClass = ActiveRecord.respond_to?(:version) && ActiveRecord.version.to_s >= "5.1.0" ? - ActiveRecord::Migration[5.1] : ActiveRecord::Migration + migration_base_class = if ActiveRecord.respond_to?(:version) && ActiveRecord.version.to_s >= '5.1.0' + ActiveRecord::Migration[5.1] + else + ActiveRecord::Migration + end - class TestMigration < migrationBaseClass + class TestMigration < migration_base_class def self.up - create_table :child_active_record_models, :force => true do |t| + create_table :child_active_record_models, force: true do |t| t.column :parent_active_record_model_id, :integer t.column :number_field, :integer end - create_table :parent_active_record_models, :force => true do |t| + create_table :parent_active_record_models, force: true do |t| t.column :before_validation_value, :integer, null: false, default: 0 t.column :before_save_value, :integer t.column :dynamic_field, :string diff --git a/spec/support/data_mapper.rb b/spec/support/data_mapper.rb index ebd4003c..a7135467 100644 --- a/spec/support/data_mapper.rb +++ b/spec/support/data_mapper.rb @@ -1,5 +1,5 @@ if defined?(DataMapper) - DataMapper.setup(:default, "sqlite3::memory:") + DataMapper.setup(:default, 'sqlite3::memory:') class ParentDataMapperModel include DataMapper::Resource diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index 2508c366..42dc0b6a 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -1,5 +1,5 @@ if defined?(Mongoid) - Mongoid.load!("spec/support/mongoid.yml", :test) + Mongoid.load!('spec/support/mongoid.yml', :test) Mongoid.logger.level = Logger::ERROR Mongo::Logger.logger.level = Logger::ERROR if defined?(Mongo) diff --git a/spec/support/plain_old_ruby_objects.rb b/spec/support/plain_old_ruby_objects.rb index 734ee442..2c58ba4e 100644 --- a/spec/support/plain_old_ruby_objects.rb +++ b/spec/support/plain_old_ruby_objects.rb @@ -4,6 +4,7 @@ class Persistable def persisted? @persisted ||= nil end + def save! @persisted = true end @@ -22,6 +23,7 @@ class ParentRubyObject < Persistable attr_writer :child_ruby_objects def initialize + super self.id = 23 self.before_save_value = 11 end @@ -62,7 +64,7 @@ class RubyObject < OpenStruct class Troublemaker def raise_exception=(value) - raise "Troublemaker exception" if value + raise 'Troublemaker exception' if value end end @@ -74,8 +76,7 @@ class Namespaced end end -class ClassWithInit < Struct.new(:arg1, :arg2) -end +ClassWithInit = Struct.new(:arg1, :arg2) class ImmutableUser def initialize(attributes) diff --git a/spec/support/sequel.rb b/spec/support/sequel.rb index 3699493f..280d9383 100644 --- a/spec/support/sequel.rb +++ b/spec/support/sequel.rb @@ -1,7 +1,7 @@ if defined?(Sequel) DB = Sequel.sqlite # in memory Sequel.extension :migration - Sequel::Migrator.run(DB, 'spec/support/sequel_migrations', :current => 0) + Sequel::Migrator.run(DB, 'spec/support/sequel_migrations', current: 0) Sequel::Model.strict_param_setting = true def clear_sequel_db @@ -12,7 +12,9 @@ def clear_sequel_db class ChildSequelModel < Sequel::Model many_to_one :parent_sequel_model - def persisted?; !new? end + def persisted? + !new? + end end class ParentSequelModel < Sequel::Model @@ -22,7 +24,9 @@ class ParentSequelModel < Sequel::Model attr_accessor :extra_fields - def persisted?; !new? end + def persisted? + !new? + end def before_validation self.before_validation_value ||= 0