module SpecProducer
Base module that needs to be included and implemented by corresponding producers. Note: This module should be prepended and not included / extended.
Concrete subclasses need to implement 2 methods: call and resources We use the prepend and prepended callback in order to call Base#call method first and the invoke super which will call the corresponding concrete implementation to be executed. The call method on every concrete implementation will receive the resource that we currently iterate over.
Conrete implementation need to prepend this module and to provide resources method which returns a collection of resources that will be iterated in order to generate the specs for. the resource object should respond to name (ex. Some::User) and type ('models', 'controllers' etc) We need these values in order to generate the Describe 'Some::Person' in rspec files.
A minimal implementation could be
class SomeSpecProducer prepend Base def resources [Clas.new(Object), Class.new(Object)].map { |obj| Resource.new(obj, obj.name, 'models') } end def call(resource) builder.context 'Some context' do |b| resource.attributes.each do |attr| b.responds_to(attr) end end end end
The base class is also responsible to write for each spec file that we generate the top static lines requiring 'spec_helper' and the beginning of spec file:
require 'spec_helper' describe User, type: :model do # Other code omitted end
Each concrete instance is responsible to create the `body` of the spec file which includes its basic validations if any or any other info that we might get from ActiveRecord, ActionController etc.
Finally this class is responsible to write the generated spec to the corresponsing path (ex spec/models/user_spec.rb)
Constants
- VERSION
Attributes
Public Class Methods
Fetches the producer from the registry. Note: that the lookup method on registry instantiates and executes the producer to start generating the spec files. This execution is hidden in repository and the client is not aware of what is going on underneath. TODO: Refactor this so registry#lookup! does not executes the regitered Producer.
If no Producer is Found an ArgumentError exception is thown.
# File lib/spec_producer.rb, line 95 def lookup!(spec_type) registry.lookup!(spec_type) end
# File lib/spec_producer.rb, line 151 def self.print_all_missing_spec_files(options = {}) MissingFilesModule.print_missing_model_specs(options) MissingFilesModule.print_missing_controller_specs(options) MissingFilesModule.print_missing_helper_specs(options) MissingFilesModule.print_missing_view_specs(options) MissingFilesModule.print_missing_mailer_specs(options) MissingFilesModule.print_missing_job_specs(options) MissingFilesModule.print_missing_serializer_specs(options) MissingFilesModule.print_missing_route_specs(options) end
# File lib/spec_producer.rb, line 166 def self.print_missing_controller_specs(options = {}) MissingFilesModule.print_missing_controller_specs(options) end
# File lib/spec_producer.rb, line 170 def self.print_missing_helper_specs(options = {}) MissingFilesModule.print_missing_helper_specs(options) end
# File lib/spec_producer.rb, line 182 def self.print_missing_job_specs(options = {}) MissingFilesModule.print_missing_job_specs(options) end
# File lib/spec_producer.rb, line 178 def self.print_missing_mailer_specs(options = {}) MissingFilesModule.print_missing_mailer_specs(options) end
# File lib/spec_producer.rb, line 162 def self.print_missing_model_specs(options = {}) MissingFilesModule.print_missing_model_specs(options) end
# File lib/spec_producer.rb, line 190 def self.print_missing_route_specs(options = {}) MissingFilesModule.print_missing_route_specs(options) end
# File lib/spec_producer.rb, line 186 def self.print_missing_serializer_specs(options = {}) MissingFilesModule.print_missing_serializer_specs(options) end
# File lib/spec_producer.rb, line 174 def self.print_missing_view_specs(options = {}) MissingFilesModule.print_missing_view_specs(options) end
# File lib/spec_producer.rb, line 56 def produce(*args) opts = args.extract_options! spec_types = registry.types if only = opts[:only] spec_types &= Array(only).map(&:to_sym) elsif except = opts[:except] spec_types -= Array(except).map(&:to_sym) end # Produce the specs spec_types.each { |t| produce_spec(t) } # Run the specs run(spec_types) if opts[:run_specs] end
# File lib/spec_producer.rb, line 147 def self.produce_factories FactoriesProductionModule.produce_factories end
Produces a single spec type. For example
SpecProducer.produce_spec(:models)
Will fetch and execute the Producers::ModelsSpecProducer
# File lib/spec_producer.rb, line 83 def produce_spec(spec_type) lookup!(spec_type) end
# File lib/spec_producer.rb, line 110 def self.produce_specs_for_all_types SpecProductionModule.produce_specs_for_routes SpecProductionModule.produce_specs_for_views SpecProductionModule.produce_specs_for_mailers SpecProductionModule.produce_specs_for_jobs run_spec_tests end
# File lib/spec_producer.rb, line 137 def self.produce_specs_for_jobs SpecProductionModule.produce_specs_for_jobs run_spec_tests 'jobs' end
# File lib/spec_producer.rb, line 131 def self.produce_specs_for_mailers SpecProductionModule.produce_specs_for_mailers run_spec_tests 'mailers' end
# File lib/spec_producer.rb, line 119 def self.produce_specs_for_routes SpecProductionModule.produce_specs_for_routes run_spec_tests 'routes' end
# File lib/spec_producer.rb, line 125 def self.produce_specs_for_views SpecProductionModule.produce_specs_for_views run_spec_tests 'views' end
# File lib/spec_producer.rb, line 73 def register(type_name, klass) registry.register(type_name, klass) end
# File lib/spec_producer.rb, line 194 def self.run_spec_tests(type = nil) puts "\nRunning related spec tests...\n" if type.nil? system 'bundle exec rake' else command = case type when 'views' then 'bundle exec rspec spec/views' when 'mailers' then 'bundle exec rspec spec/mailers' when 'jobs' then 'bundle exec rspec spec/jobs' when 'routes' then 'bundle exec rspec spec/routes' else 'bundle exec rspec' end system command end end
# File lib/spec_producer.rb, line 143 def self.set_up_necessities MissingGemsModule.set_up_necessities end