generator_spec-0.10.0/0000755000004100000410000000000014574727572014644 5ustar www-datawww-datagenerator_spec-0.10.0/.gitignore0000644000004100000410000000005214574727572016631 0ustar www-datawww-data*.gem .bundle pkg/* spec/tmp Gemfile.lock generator_spec-0.10.0/lib/0000755000004100000410000000000014574727572015412 5ustar www-datawww-datagenerator_spec-0.10.0/lib/generator_spec.rb0000644000004100000410000000047014574727572020740 0ustar www-datawww-datarequire 'rspec/core' require 'generator_spec/generator_example_group' RSpec::configure do |c| def c.escaped_path(*parts) Regexp.compile(parts.join('[\\\/]') + '[\\\/]') end c.include GeneratorSpec::GeneratorExampleGroup, :type => :generator, :file_path => c.escaped_path(%w[spec lib generators]) end generator_spec-0.10.0/lib/generator_spec/0000755000004100000410000000000014574727572020412 5ustar www-datawww-datagenerator_spec-0.10.0/lib/generator_spec/matcher.rb0000644000004100000410000000775414574727572022377 0ustar www-datawww-datamodule GeneratorSpec module Matcher # Taken (with permission) from beard by Yahuda Katz # https://github.com/carlhuda/beard class File def description 'file attributes and content' end def initialize(name, &block) @contents = [] @name = name @negative_contents = [] if block_given? instance_eval(&block) end end def contains(text) @contents << text end def does_not_contain(text) @negative_contents << text end def matches?(root) unless root.join(@name).exist? throw :failure, root.join(@name) end check_contents(root.join(@name)) end protected def check_contents(file) contents = ::File.read(file) @contents.each do |string| unless contents.include?(string) throw :failure, [file, string, contents] end end @negative_contents.each do |string| if contents.include?(string) throw :failure, [:not, file, string, contents] end end end end class Migration < File def description 'valid migration file' end def matches?(root) file_name = migration_file_name(root, @name) unless file_name && file_name.exist? throw :failure, @name end check_contents(file_name) end protected def migration_file_name(root, name) #:nodoc: directory, file_name = ::File.dirname(root.join(name)), ::File.basename(name).sub(/\.rb$/, '') migration = Dir.glob("#{directory}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first Pathname.new(migration) if migration end end class Directory attr_reader :tree def description 'has directory structure' end def initialize(root = nil, &block) @tree = {} @negative_tree = [] @root = root instance_eval(&block) if block_given? end def directory(name, &block) @tree[name] = block_given? && Directory.new(location(name), &block) end def file(name, &block) @tree[name] = File.new(location(name), &block) end def no_file(name) @negative_tree << name end def location(name) [@root, name].compact.join("/") end def migration(name, &block) @tree[name] = Migration.new(location(name), &block) end def matches?(root) @tree.each do |file, value| unless value unless root.join(location(file)).exist? throw :failure, "#{root}/#{location(file)}" end else value.matches?(root) end end @negative_tree.each do |file| if root.join(location(file)).exist? throw :failure, [:not, "unexpected #{root}/#{location(file)}"] end end nil end end class Root < Directory def description 'have specified directory structure' end def failure_message if @failure.is_a?(Array) && @failure[0] == :not if @failure.length > 2 "Structure should have #{@failure[1]} without #{@failure[2]}. It had:\n#{@failure[3]}" else "Structure should not have had #{@failure[1]}, but it did" end elsif @failure.is_a?(Array) "Structure should have #{@failure[0]} with #{@failure[1]}. It had:\n#{@failure[2]}" else "Structure should have #{@failure}, but it didn't" end end def matches?(root) root = Pathname.new(root) unless root.is_a?(Pathname) @failure = catch :failure do super end !@failure end end def have_structure(&block) error = 'You must pass a block to have_structure (Use {} instead of do/end!)' raise RuntimeError, error unless block_given? Root.new(&block) end end end generator_spec-0.10.0/lib/generator_spec/test_case.rb0000644000004100000410000000216514574727572022715 0ustar www-datawww-datarequire 'active_support/all' require 'rails/generators/test_case' require 'generator_spec/matcher' module GeneratorSpec module TestCase extend ActiveSupport::Concern include Matcher include FileUtils included do cattr_accessor :test_case, :test_case_instance self.test_case = Class.new(Rails::Generators::TestCase) do def fake_test_case; end def add_assertion; end end self.test_case_instance = self.test_case.new(:fake_test_case) self.test_case.tests described_class end module ClassMethods def tests(klass) self.test_case.generator_class = klass end def arguments(array) self.test_case.default_arguments = array end def destination(path) self.test_case.destination_root = path end end def method_missing(method_sym, *arguments, &block) self.test_case_instance.send(method_sym, *arguments, &block) end def respond_to?(method_sym, include_private = false) if self.test_case_instance.respond_to?(method_sym) true else super end end end end generator_spec-0.10.0/lib/generator_spec/generator_example_group.rb0000644000004100000410000000022614574727572025654 0ustar www-datawww-datarequire 'generator_spec/test_case' module GeneratorSpec::GeneratorExampleGroup extend ActiveSupport::Concern include GeneratorSpec::TestCase end generator_spec-0.10.0/lib/generator_spec/version.rb0000644000004100000410000000005614574727572022425 0ustar www-datawww-datamodule GeneratorSpec VERSION = '0.10.0' end generator_spec-0.10.0/spec/0000755000004100000410000000000014574727572015576 5ustar www-datawww-datagenerator_spec-0.10.0/spec/spec_helper.rb0000644000004100000410000000035214574727572020414 0ustar www-datawww-datarequire 'bundler/setup' require 'rspec' require 'generator_spec' Dir[Pathname.new(File.expand_path('../', __FILE__)).join('support/**/*.rb')].each {|f| require f} RSpec.configure do |config| config.include Helpers::FileSystem end generator_spec-0.10.0/spec/generator_spec/0000755000004100000410000000000014574727572020576 5ustar www-datawww-datagenerator_spec-0.10.0/spec/generator_spec/test_case_spec.rb0000644000004100000410000000326214574727572024112 0ustar www-datawww-datarequire 'spec_helper' class TestClass end describe GeneratorSpec::TestCase do before do @klass = Class.new do def self.described_class TestClass end include GeneratorSpec::TestCase end @klass.test_case_instance = double end it 'passes unknown messages on to test_case_instance' do expect(@klass.test_case_instance).to receive(:assert_file).with('test') @klass.new.assert_file('test') end it 'handles respond_to accordingly' do expect(@klass.test_case_instance).to receive(:respond_to?).with(:assert_no_file).and_return(true) expect(@klass.new.respond_to?(:assert_no_file)).to be_truthy end end describe TestGenerator, 'using normal assert methods', :type => 'generator' do destination File.expand_path('../../tmp', __FILE__) arguments %w(test --test) before(:all) do prepare_destination run_generator end it 'creates a test initializer' do assert_file 'config/initializers/test.rb', '# Initializer' end it 'creates a migration' do assert_migration 'db/migrate/create_tests.rb' end it 'removes files' do assert_no_file '.gitignore' end end describe TestGenerator, 'with contexts', :type => 'generator' do destination File.expand_path('../../tmp', __FILE__) before { prepare_destination } context 'with --test flag' do before { run_generator %w(test --test) } it 'creates a test initializer' do assert_file 'config/initializers/test.rb', '# Initializer' end end context 'without any flags' do before { run_generator %w(test) } it 'doesn\'t create a test initializer' do assert_no_file 'config/initializers/test.rb' end end end generator_spec-0.10.0/spec/generator_spec/generator_example_group_spec.rb0000644000004100000410000000024614574727572027054 0ustar www-datawww-datarequire 'spec_helper' module GeneratorSpec describe GeneratorExampleGroup do it { is_expected.to be_included_in_files_in('./spec/lib/generators/') } end end generator_spec-0.10.0/spec/generator_spec/matcher_spec.rb0000644000004100000410000002223014574727572023557 0ustar www-datawww-datarequire 'spec_helper' require 'tmpdir' TMP_ROOT = Pathname.new(Dir.mktmpdir('generator_spec')) describe TestGenerator, 'using custom matcher' do include GeneratorSpec::TestCase destination TMP_ROOT arguments %w(test --test) before do delete_directory(TMP_ROOT) prepare_destination run_generator end specify do expect(destination_root).to have_structure { no_file 'test.rb' directory 'config' do directory 'initializers' do file 'test.rb' do contains '# Initializer' end end end directory 'db' do directory 'migrate' do file '123_create_tests.rb' migration 'create_tests' do contains 'class TestMigration' end end end } end it 'fails when it doesnt match' do expect { expect(destination_root).to have_structure { directory 'db' do directory 'migrate' do no_file '123_create_tests.rb' end end } }.to raise_error RSpec::Expectations::ExpectationNotMetError end it 'fails when it doesnt match with do/end instead of {}' do expect { expect(destination_root).to have_structure do directory 'db' do directory 'migrate' do no_file '123_create_tests.rb' end end end }.to raise_error RuntimeError, /You must pass a block/ end end module GeneratorSpec module Matcher describe File do describe '#matches?' do before do delete_directory(TMP_ROOT) end let(:file) { File.new('test_file') } let(:location) { TMP_ROOT.join('test_file') } context 'with no contains' do it 'doesnt throw if the file exists' do write_file(location, '') expect { file.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws :failure if it doesnt exist' do expect { file.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end context 'with contains' do before do write_file(location, 'class CreatePosts') end it 'doesnt throw if the content includes the string' do file.contains 'CreatePosts' expect { file.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws :failure if the contents dont include the string' do file.contains 'PostsMigration' expect { file.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end context 'with does_not_contain' do before do write_file(location, 'class CreatePosts') end it 'doesnt throw if the contents dont include the string' do file.does_not_contain 'PostsMigration' expect { file.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws :failure if the contents include the string' do file.does_not_contain 'CreatePosts' expect { file.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end end end describe Migration do describe '#matches?' do before do delete_directory(TMP_ROOT) end let(:migration) { Migration.new('create_posts') } let(:location) { TMP_ROOT.join('123456_create_posts.rb') } context 'with no contains' do it 'doesnt throw if the migration exists' do write_file(location, 'class CreatePosts') expect { migration.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws :failure if it doesnt exist' do expect { migration.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end context 'with contains' do before do write_file(location, 'class CreatePosts') end it 'doesnt throw if the migration includes the given content' do migration.contains('CreatePosts') expect { migration.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws failure if the migration doesnt include the given content' do migration.contains('CreateNotes') expect { migration.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end context 'with does_not_contain' do before do write_file(location, 'class CreatePosts') end it 'doesnt throw if the migration doesnt include the given content' do migration.does_not_contain('CreateNotes') expect { migration.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws failure if the migration includes the given content' do migration.does_not_contain('CreatePosts') expect { migration.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end end end describe Directory do describe '#location' do it 'equals the full path' do expect(Directory.new('test').location('test_2')).to eq('test/test_2') end end describe '#directory' do context 'without a block' do it 'adds a directory name to the tree' do dir = Directory.new 'test' do directory 'dir' end expect(dir.tree['dir']).to eq(false) end end context 'with a block' do it 'add a directory object to the tree' do dir = Directory.new 'test' do directory 'dir' do directory 'test_2' end end expect(dir.tree['dir']).to be_an_instance_of(Directory) expect(dir.tree['dir'].tree['test_2']).to eq(false) end end end describe '#file' do it 'adds it to the tree' do dir = Directory.new 'test' do file 'test_file' end expect(dir.tree['test_file']).to be_an_instance_of(File) end end describe '#file' do it 'adds it to the tree' do dir = Directory.new 'test' do migration 'test_file' end expect(dir.tree['test_file']).to be_an_instance_of(Migration) expect(dir.tree['test_file'].instance_variable_get('@name')).to eq('test/test_file') end end describe '#matches?' do before do delete_directory(TMP_ROOT) end context 'with a directory name' do let(:dir) { Directory.new 'test' do directory 'test_2' end } it 'doesnt throw if the directory exists' do write_directory(TMP_ROOT.join('test/test_2')) expect { dir.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws :failure if it doesnt exist' do expect { dir.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end context 'with a directory object' do let(:dir) { Directory.new 'test' do directory 'test_2' do file 'test_file' end end } before do delete_directory(TMP_ROOT) write_directory(TMP_ROOT.join('test/test_2')) end it 'doesnt throw if the file exists' do write_file(TMP_ROOT.join('test/test_2/test_file'), '') expect { dir.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws :failure if it doesnt exist' do expect { dir.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end context '#no_file' do let(:dir) { Directory.new 'test' do no_file 'test_file' end } before do delete_directory(TMP_ROOT) write_directory(TMP_ROOT.join('test')) end it 'doesnt throw if the file exist' do expect { dir.matches?(TMP_ROOT) }.to_not throw_symbol end it 'throws if the file exists' do write_file(TMP_ROOT.join('test/test_file'), '') expect { dir.matches?(TMP_ROOT) }.to throw_symbol(:failure) end end end end describe Root do describe '#matches?' do before do delete_directory(TMP_ROOT) end let(:root) { Root.new 'test' do directory 'test_dir' end } it 'returns true on no failures' do write_directory(TMP_ROOT.join('test/test_dir')) expect(root.matches?(TMP_ROOT)).to be_truthy end it 'returns false on failures' do expect(root.matches?(TMP_ROOT)).to be_falsey end end end end end generator_spec-0.10.0/spec/support/0000755000004100000410000000000014574727572017312 5ustar www-datawww-datagenerator_spec-0.10.0/spec/support/test_generator/0000755000004100000410000000000014574727572022337 5ustar www-datawww-datagenerator_spec-0.10.0/spec/support/test_generator/test_generator.rb0000644000004100000410000000062614574727572025715 0ustar www-datawww-dataclass TestGenerator < Rails::Generators::Base argument :name, :type => :string class_option :test, :type => :boolean, :default => false source_root File.expand_path('../templates', __FILE__) def copy_initializer template "initializer.rb", "config/initializers/test.rb" if options[:test] end def create_migration template "migration.rb", "db/migrate/123_create_tests.rb" end end generator_spec-0.10.0/spec/support/test_generator/templates/0000755000004100000410000000000014574727572024335 5ustar www-datawww-datagenerator_spec-0.10.0/spec/support/test_generator/templates/migration.rb0000644000004100000410000000012614574727572026652 0ustar www-datawww-dataif defined?(ActiveRecord) class TestMigration < ActiveRecord::Migration end endgenerator_spec-0.10.0/spec/support/test_generator/templates/initializer.rb0000644000004100000410000000001514574727572027201 0ustar www-datawww-data# Initializergenerator_spec-0.10.0/spec/support/matchers.rb0000644000004100000410000000052014574727572021442 0ustar www-datawww-data# taken from https://raw.github.com/rspec/rspec-rails/master/spec/support/matchers.rb RSpec::Matchers::define :be_included_in_files_in do |path| match do |mod| stub_metadata( :file_path => "#{path}whatever_spec.rb:15" ) group = RSpec::Core::ExampleGroup.describe group.included_modules.include?(mod) end end generator_spec-0.10.0/spec/support/helpers.rb0000644000004100000410000000067614574727572021312 0ustar www-datawww-data# taken from https://github.com/rspec/rspec-rails/blob/master/spec/support/helpers.rb module Helpers def stub_metadata(additional_metadata) stub_metadata = metadata_with(additional_metadata) allow(RSpec::Core::ExampleGroup).to receive(:metadata) { stub_metadata } end def metadata_with(additional_metadata) ::RSpec.describe("example group").metadata.merge(additional_metadata) end RSpec.configure {|c| c.include self} end generator_spec-0.10.0/spec/support/file_system.rb0000644000004100000410000000051214574727572022160 0ustar www-datawww-datamodule Helpers module FileSystem def write_file(file_name, contents) write_directory(TMP_ROOT) ::File.open(file_name.to_s, 'w') {|f| f.write(contents) } end def write_directory(name) FileUtils.mkdir_p(name) end def delete_directory(name) FileUtils.rm_rf(name) end end end generator_spec-0.10.0/.rspec0000644000004100000410000000001114574727572015751 0ustar www-datawww-data--colour generator_spec-0.10.0/Rakefile0000644000004100000410000000021314574727572016305 0ustar www-datawww-datarequire 'bundler' Bundler::GemHelper.install_tasks require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task :default => :specgenerator_spec-0.10.0/MIT-LICENSE0000644000004100000410000000203614574727572016301 0ustar www-datawww-dataCopyright 2011 Steve Hodgkiss Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. generator_spec-0.10.0/generator_spec.gemspec0000644000004100000410000000167014574727572021215 0ustar www-datawww-data# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "generator_spec/version" Gem::Specification.new do |s| s.name = "generator_spec" s.version = GeneratorSpec::VERSION s.platform = Gem::Platform::RUBY s.authors = ["Steve Hodgkiss"] s.email = ["steve@hodgkiss.me.uk"] s.homepage = "https://github.com/stevehodgkiss/generator_spec" s.license = 'MIT' s.summary = %q{Test Rails generators with RSpec} s.description = %q{Test Rails generators with RSpec} s.rubyforge_project = "generator_spec" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] s.add_dependency 'activesupport', ['>= 3.0.0'] s.add_dependency 'railties', ['>= 3.0.0'] s.add_development_dependency 'rspec', '~> 3.0' end generator_spec-0.10.0/Gemfile0000644000004100000410000000017114574727572016136 0ustar www-datawww-datasource "http://rubygems.org" platforms :rbx do # gem 'rubysl', '~> 2.2' gem 'rubinius-developer_tools' end gemspec generator_spec-0.10.0/.travis.yml0000644000004100000410000000004414574727572016753 0ustar www-datawww-datalanguage: ruby rvm: - 2.4 - 2.3 generator_spec-0.10.0/README.md0000644000004100000410000000335314574727572016127 0ustar www-datawww-data# Generator Spec [![Build Status](https://travis-ci.org/stevehodgkiss/generator_spec.svg?branch=master)](https://travis-ci.org/stevehodgkiss/generator_spec) Test Rails generators with RSpec using the standard Rails::Generators::TestCase assertion methods. # Usage Gemfile: ```ruby group :test do gem "generator_spec" end ``` Spec (files in `spec/lib/generators` are recognized as generator type example group): ```ruby # spec/lib/generators/test/test_generator_spec.rb require "generator_spec" describe TestGenerator, type: :generator do destination File.expand_path("../../tmp", __FILE__) arguments %w(something) before(:all) do prepare_destination run_generator end it "creates a test initializer" do assert_file "config/initializers/test.rb", "# Initializer" end end ``` An RSpec file matching DSL is also provided, taken with permission from [beard](https://github.com/carlhuda/beard/blob/master/spec/support/matcher.rb) by [carlhuda](https://github.com/carlhuda). ```ruby describe TestGenerator, "using custom matcher", type: :generator do destination File.expand_path("../../tmp", __FILE__) before do prepare_destination run_generator end specify do expect(destination_root).to have_structure { no_file "test.rb" directory "config" do directory "initializers" do file "test.rb" do contains "# Initializer" does_not_contain "Something else" end end end directory "db" do directory "migrate" do file "123_create_tests.rb" migration "create_tests" do contains "class TestMigration" does_not_contain "Something else" end end end } end end ```