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

registry[R]

Public Class Methods

lookup!(spec_type) click to toggle source

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
print_all_missing_spec_files(options = {}) click to toggle source
print_missing_controller_specs(options = {}) click to toggle source
print_missing_helper_specs(options = {}) click to toggle source
print_missing_job_specs(options = {}) click to toggle source
print_missing_mailer_specs(options = {}) click to toggle source
print_missing_model_specs(options = {}) click to toggle source
print_missing_route_specs(options = {}) click to toggle source
print_missing_serializer_specs(options = {}) click to toggle source
print_missing_view_specs(options = {}) click to toggle source
produce(*args) click to toggle source
# 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
produce_factories() click to toggle source
# File lib/spec_producer.rb, line 147
def self.produce_factories
  FactoriesProductionModule.produce_factories
end
produce_spec(spec_type) click to toggle source

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
produce_specs_for_all_types() click to toggle source
# 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
produce_specs_for_jobs() click to toggle source
# File lib/spec_producer.rb, line 137
def self.produce_specs_for_jobs
  SpecProductionModule.produce_specs_for_jobs

  run_spec_tests 'jobs'
end
produce_specs_for_mailers() click to toggle source
# File lib/spec_producer.rb, line 131
def self.produce_specs_for_mailers
  SpecProductionModule.produce_specs_for_mailers

  run_spec_tests 'mailers'
end
produce_specs_for_routes() click to toggle source
# File lib/spec_producer.rb, line 119
def self.produce_specs_for_routes
  SpecProductionModule.produce_specs_for_routes

  run_spec_tests 'routes'
end
produce_specs_for_views() click to toggle source
# File lib/spec_producer.rb, line 125
def self.produce_specs_for_views
  SpecProductionModule.produce_specs_for_views

  run_spec_tests 'views'
end
register(type_name, klass) click to toggle source
# File lib/spec_producer.rb, line 73
def register(type_name, klass)
  registry.register(type_name, klass)
end
run_spec_tests(type = nil) click to toggle source
# 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
set_up_necessities() click to toggle source
# File lib/spec_producer.rb, line 143
def self.set_up_necessities
  MissingGemsModule.set_up_necessities
end