mongo_mapper_generators 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Steve Agalloco
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,61 @@
1
+ = mongo_mapper_generators
2
+
3
+ MMG is intended for use with the MongoMapper rubygem. Use it to generate Document and EmbeddedDocument models. Also included is a generator for a rails initializer.
4
+
5
+ == Install
6
+
7
+ MongoMapperGenerators is only released on gemcutter. To install, you can setup gemcutter as your default gem source.
8
+
9
+ $ gem install gemcutter
10
+ $ gem tumble
11
+
12
+ Then you can install MMG:
13
+
14
+ $ gem install mongo_mapper_generators
15
+
16
+ You can also just declare the source:
17
+
18
+ $ gem install mongo_mapper_generators -s http://gemcutter.org
19
+
20
+ == Dependencies
21
+
22
+ * MongoMapper
23
+ * Rails
24
+
25
+ == Usage
26
+
27
+ Once you install the gem, the generators will be available to all Rails
28
+ applications on your system. If you run script/generate without any
29
+ additional arguments you should see the available generators listed.
30
+
31
+ To run the generator, go to your rails project directory and call it
32
+ using the script/generate or script/destroy command.
33
+
34
+ script/generate mongo_model Person name:string email:string age:integer
35
+
36
+ It will generate the model, a unit test and a factory.
37
+
38
+ Generators also exist for generating EmbeddedDocument models as well as a rails initializer.
39
+
40
+ == Note on Patches/Pull Requests
41
+
42
+ * Fork the project.
43
+ * Make your feature addition or bug fix.
44
+ * Add tests for it. This is important so I don't break it in a
45
+ future version unintentionally.
46
+ * Commit, do not mess with rakefile, version, or history.
47
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
48
+ * Send me a pull request. Bonus points for topic branches.
49
+
50
+ == Credits
51
+
52
+ I was inspired by a number of different sources, including:
53
+
54
+ * Blitz - http://github.com/dancroak/blitz
55
+ * NiftyGenerators - http://github.com/ryanb/nifty-generators
56
+ * ShouldaGenerator - http://github.com/technicalpickles/shoulda_generator
57
+ * John Nunemaker's rails initializer - http://gist.github.com/232953
58
+
59
+ == Copyright
60
+
61
+ Copyright (c) 2009 Steve Agalloco. See LICENSE for details.
@@ -0,0 +1,67 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "mongo_mapper_generators"
8
+ gem.summary = %Q{Generators for use with the MongoMapper rubygem}
9
+ gem.description = %Q{Generators for use with the MongoMapper rubygem. Use to generate Documents, EmbeddedDocuments, and Rails initializer.}
10
+ gem.email = "steve.agalloco@gmail.com"
11
+ gem.homepage = "http://github.com/spagalloco/mongo_mapper_generators"
12
+ gem.authors = ["Steve Agalloco"]
13
+ gem.files = FileList["[A-Z]*", "{lib,rails_generators,test}/**/*"]
14
+
15
+ gem.add_development_dependency "shoulda", ">= 2.10.2"
16
+ gem.add_development_dependency "cucumber", ">= 0.4.0"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/test_*.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/test_*.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ task :test => :check_dependencies
45
+
46
+ begin
47
+ require 'cucumber/rake/task'
48
+ Cucumber::Rake::Task.new(:features)
49
+
50
+ task :features => :check_dependencies
51
+ rescue LoadError
52
+ task :features do
53
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
54
+ end
55
+ end
56
+
57
+ task :default => :test
58
+
59
+ require 'rake/rdoctask'
60
+ Rake::RDocTask.new do |rdoc|
61
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
62
+
63
+ rdoc.rdoc_dir = 'rdoc'
64
+ rdoc.title = "mongo_mapper_generators #{version}"
65
+ rdoc.rdoc_files.include('README*')
66
+ rdoc.rdoc_files.include('lib/**/*.rb')
67
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,5 @@
1
+ module MongomapperGenerators
2
+ VERSION = '0.1.0'
3
+
4
+ # nothing to see here, the real action is under rails_generators
5
+ end
@@ -0,0 +1,24 @@
1
+ Description:
2
+ Stubs out a new model. Pass the model name, either CamelCased or
3
+ under_scored, and an optional list of attribute pairs as arguments.
4
+
5
+ Attribute pairs are key_name:mongo_type arguments specifying the
6
+ model's attributes. Timestamps and Userstamps are added by default.
7
+
8
+ Examples:
9
+ `./script/generate embedded_model account`
10
+
11
+ creates an Account model:
12
+ Model: app/models/account.rb
13
+
14
+ `./script/generate embedded_model post title:string body:string published:boolean`
15
+
16
+ creates a Post model with a string title, string body, published flag, timestamps! and userstamps!.
17
+
18
+ `./script/generate embedded_model post --skip-timestamps`
19
+
20
+ creates a Post model with no timestamps.
21
+
22
+ `./script/generate embedded_model post --skip-userstamps`
23
+
24
+ creates a Post model with no userstamps.
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), "..", "support", "generator_helper")
2
+
3
+ class EmbeddedModelGenerator < Rails::Generator::NamedBase
4
+ attr_accessor :belongs, :many, :timestamps, :userstamps
5
+
6
+ default_options :skip_factories => false, :skip_timestamps => false
7
+
8
+ def initialize(runtime_args, runtime_options = {})
9
+ super
10
+
11
+ parsed_attributes = []
12
+
13
+ @args.each do |arg|
14
+ if arg.include? ':'
15
+ parsed_attributes << MongoAttribute.new(*arg.split(":"))
16
+ end
17
+ end
18
+
19
+ @attributes = parsed_attributes.reject { |each| %w(many belongs_to).include? each.name }
20
+ @many = parsed_attributes.select { |each| each.name == 'many' }
21
+ @belongs = parsed_attributes.select { |each| each.name == 'belongs_to' }
22
+ @timestamps = !options[:skip_timestamps]
23
+ @userstamps = !options[:skip_userstamps]
24
+ end
25
+
26
+ def manifest
27
+ record do |m|
28
+ m.directory 'app/models'
29
+ m.template 'embedded_model.rb', File.join('app/models', class_path, "#{file_name}.rb")
30
+
31
+ m.directory 'test/unit'
32
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
33
+
34
+ unless options[:skip_factories]
35
+ m.directory 'test/factories'
36
+ m.template 'factory.rb', File.join('test/factories', "#{plural_name}.rb")
37
+ end
38
+ end
39
+ end
40
+
41
+ def factory_line(attribute, file_name)
42
+ "#{file_name}.#{attribute.name} #{attribute.default_for_factory}"
43
+ end
44
+
45
+ protected
46
+
47
+ def banner
48
+ "Usage: #{$0} #{spec.name} ModelName [field:type, field:type] --skip-factories --skip-timestamps --skip-userstamps"
49
+ end
50
+
51
+ def add_options!(opt)
52
+ opt.separator ''
53
+ opt.separator 'Options:'
54
+ opt.on("--skip-factories", "Don't generate a factory for this model") { |v|
55
+ options[:skip_factories] = v
56
+ }
57
+ opt.on("--skip-timestamps", "Don't add timestamps to this model") { |v|
58
+ options[:skip_timestamps] = v
59
+ }
60
+ opt.on("--skip-userstamps", "Don't add userstamps to this model") { |v|
61
+ options[:skip_userstamps] = v
62
+ }
63
+ end
64
+ end
@@ -0,0 +1,29 @@
1
+ class <%= class_name %>
2
+ include MongoMapper::EmbeddedDocument
3
+
4
+ <% if attributes.any? -%>
5
+ <% attributes.each do |attribute| -%>
6
+ key :<%= attribute.name %>, <%= attribute.type %>
7
+ <% end -%>
8
+ <% end -%>
9
+
10
+ <% if many.any? -%>
11
+ <% many.each do |each| -%>
12
+ many :<%= each.type %>
13
+ <% end -%>
14
+ <% end -%>
15
+
16
+ <% if belongs.any? -%>
17
+ <% belongs.each do |each| -%>
18
+ belongs_to :<%= each.type %>
19
+ <% end -%>
20
+ <% end -%>
21
+
22
+ <% if timestamps -%>
23
+ timestamps!
24
+ <% end -%>
25
+
26
+ <% if userstamps -%>
27
+ userstamps!
28
+ <% end -%>
29
+ end
@@ -0,0 +1,9 @@
1
+ Factory.define :<%= file_name %> do |<%= file_name %>|
2
+ <% attributes.each do |attribute| -%>
3
+ <%= factory_line(attribute, file_name) %>
4
+ <% end -%>
5
+ <% if timestamps %>
6
+ <%= factory_line(MongoAttribute.new('created_at', 'timestamp'), file_name) %>
7
+ <%= factory_line(MongoAttribute.new('updated_at', 'timestamp'), file_name) %>
8
+ <% end -%>
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ should "be valid with factory" do
5
+ assert_valid Factory.build(:<%= file_name -%>)
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ Description:
2
+ Creates a database.yml file and a rails initializer for use with MongoMapper.
3
+
4
+ Examples:
5
+ `./script/generate mongo_initializer`
6
+
7
+ creates an initializer:
8
+ Initializer: config/initializers/mongomapper.rb
9
+ Config: config/database.yml
10
+
11
+
12
+ `./script/generate mongo_initializer databasename`
13
+
14
+ generates the same files as above, and uses the databasename in the config file.
@@ -0,0 +1,18 @@
1
+ class MongoInitializerGenerator < Rails::Generator::Base
2
+ attr :file_name
3
+
4
+ def initialize(runtime_args, runtime_options = {})
5
+ super
6
+ @file_name = @args.first || 'default'
7
+ end
8
+
9
+ def manifest
10
+ record do |m|
11
+ m.directory 'config'
12
+ m.directory 'config/initializers'
13
+
14
+ m.file 'database.yml', "config/database.yml"
15
+ m.template 'initializer.rb', "config/initializers/mongomapper.rb"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ development: &global_settings
2
+ database: <%= file_name %>_development
3
+ host: 127.0.0.1
4
+ port: 27017
5
+
6
+ test:
7
+ database: <%= file_name %>_test
8
+ <<: *global_settings
9
+
10
+ production:
11
+ host: hostname
12
+ database: <%= file_name %>_production
13
+ username: username
14
+ password: password
15
+ <<: *global_settings
@@ -0,0 +1,25 @@
1
+ config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
2
+
3
+ MongoMapper.connection = Mongo::Connection.new(config['host'], config['port'], {
4
+ :logger => Rails.logger
5
+ })
6
+
7
+ MongoMapper.database = config['database']
8
+ if config['username'].present?
9
+ MongoMapper.database.authenticate(config['username'], config['password'])
10
+ end
11
+
12
+ Dir[Rails.root + 'app/models/**/*.rb'].each do |model_path|
13
+ File.basename(model_path, '.rb').classify.constantize
14
+ end
15
+ MongoMapper.ensure_indexes!
16
+
17
+ ActionController::Base.rescue_responses['MongoMapper::DocumentNotFound'] = :not_found
18
+
19
+ if defined?(PhusionPassenger)
20
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
21
+ # if using older than 0.6.5 of MM then you want database instead of connection
22
+ # MongoMapper.database.connect_to_master if forked
23
+ MongoMapper.connection.connect_to_master if forked
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ Description:
2
+ Stubs out a new model. Pass the model name, either CamelCased or
3
+ under_scored, and an optional list of attribute pairs as arguments.
4
+
5
+ Attribute pairs are key_name:mongo_type arguments specifying the
6
+ model's attributes. Timestamps and Userstamps are added by default.
7
+
8
+ Examples:
9
+ `./script/generate mongo_model account`
10
+
11
+ creates an Account model:
12
+ Model: app/models/account.rb
13
+
14
+ `./script/generate mongo_model post title:string body:string published:boolean`
15
+
16
+ creates a Post model with a string title, string body, published flag, timestamps! and userstamps!.
17
+
18
+ `./script/generate mongo_model post --skip-timestamps`
19
+
20
+ creates a Post model with no timestamps.
21
+
22
+ `./script/generate mongo_model post --skip-userstamps`
23
+
24
+ creates a Post model with no userstamps.
@@ -0,0 +1,64 @@
1
+ require File.join(File.dirname(__FILE__), "..", "support", "generator_helper")
2
+
3
+ class MongoModelGenerator < Rails::Generator::NamedBase
4
+ attr_accessor :belongs, :many, :timestamps, :userstamps
5
+
6
+ default_options :skip_factories => false, :skip_timestamps => false
7
+
8
+ def initialize(runtime_args, runtime_options = {})
9
+ super
10
+
11
+ parsed_attributes = []
12
+
13
+ @args.each do |arg|
14
+ if arg.include? ':'
15
+ parsed_attributes << MongoAttribute.new(*arg.split(":"))
16
+ end
17
+ end
18
+
19
+ @attributes = parsed_attributes.reject { |each| %w(many belongs_to).include? each.name }
20
+ @many = parsed_attributes.select { |each| each.name == 'many' }
21
+ @belongs = parsed_attributes.select { |each| each.name == 'belongs_to' }
22
+ @timestamps = !options[:skip_timestamps]
23
+ @userstamps = !options[:skip_userstamps]
24
+ end
25
+
26
+ def manifest
27
+ record do |m|
28
+ m.directory 'app/models'
29
+ m.template 'mongo_model.rb', "app/models/#{singular_name}.rb"
30
+
31
+ m.directory 'test/unit'
32
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{singular_name}_test.rb")
33
+
34
+ unless options[:skip_factories]
35
+ m.directory 'test/factories'
36
+ m.template 'factory.rb', File.join('test/factories', "#{plural_name}.rb")
37
+ end
38
+ end
39
+ end
40
+
41
+ def factory_line(attribute, file_name)
42
+ "#{file_name}.#{attribute.name} #{attribute.default_for_factory}"
43
+ end
44
+
45
+ protected
46
+
47
+ def banner
48
+ "Usage: #{$0} #{spec.name} ModelName [field:type, field:type] --skip-factories --skip-timestamps --skip-userstamps"
49
+ end
50
+
51
+ def add_options!(opt)
52
+ opt.separator ''
53
+ opt.separator 'Options:'
54
+ opt.on("--skip-factories", "Don't generate a factory for this model") { |v|
55
+ options[:skip_factories] = v
56
+ }
57
+ opt.on("--skip-timestamps", "Don't add timestamps to this model") { |v|
58
+ options[:skip_timestamps] = v
59
+ }
60
+ opt.on("--skip-userstamps", "Don't add userstamps to this model") { |v|
61
+ options[:skip_userstamps] = v
62
+ }
63
+ end
64
+ end
@@ -0,0 +1,9 @@
1
+ Factory.define :<%= file_name %> do |<%= file_name %>|
2
+ <% attributes.each do |attribute| -%>
3
+ <%= factory_line(attribute, file_name) %>
4
+ <% end -%>
5
+ <% if timestamps %>
6
+ <%= factory_line(MongoAttribute.new('created_at', 'timestamp'), file_name) %>
7
+ <%= factory_line(MongoAttribute.new('updated_at', 'timestamp'), file_name) %>
8
+ <% end -%>
9
+ end
@@ -0,0 +1,29 @@
1
+ class <%= class_name %>
2
+ include MongoMapper::Document
3
+
4
+ <% if attributes.any? -%>
5
+ <% attributes.each do |attribute| -%>
6
+ key :<%= attribute.name %>, <%= attribute.type %>
7
+ <% end -%>
8
+ <% end -%>
9
+
10
+ <% if many.any? -%>
11
+ <% many.each do |each| -%>
12
+ many :<%= each.type %>
13
+ <% end -%>
14
+ <% end -%>
15
+
16
+ <% if belongs.any? -%>
17
+ <% belongs.each do |each| -%>
18
+ belongs_to :<%= each.type %>
19
+ <% end -%>
20
+ <% end -%>
21
+
22
+ <% if timestamps -%>
23
+ timestamps!
24
+ <% end -%>
25
+
26
+ <% if userstamps -%>
27
+ userstamps!
28
+ <% end -%>
29
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ should "be valid with factory" do
5
+ assert_valid Factory.build(:<%= file_name -%>)
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ class MongoAttribute
2
+ attr_accessor :name, :type
3
+
4
+ def initialize(name, type)
5
+ @name, @type = name, type
6
+ end
7
+
8
+ def type
9
+ case @name
10
+ when 'many'
11
+ @type.tableize
12
+ when 'index', 'belongs_to'
13
+ @type.downcase
14
+ else
15
+ @type.capitalize
16
+ end
17
+ end
18
+
19
+ def default_for_factory
20
+ @default ||= case @type.downcase.to_sym
21
+ when :integer then "{ 1 }"
22
+ when :float then "{ 1.5 }"
23
+ when :decimal then "{ 9.99 }"
24
+ when :datetime, :timestamp, :time then "{ Time.now.to_s(:db) }"
25
+ when :date then "{ Date.today.to_s(:db) }"
26
+ when :string then "{ 'string' }"
27
+ when :text then "{ 'text' }"
28
+ when :boolean then "{ false }"
29
+ else
30
+ ""
31
+ end
32
+ end
33
+ end
@@ -0,0 +1 @@
1
+ # Logfile created on Tue Dec 22 00:34:12 -0500 2009 by logger.rb/22283
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'ruby-debug'
3
+ require 'active_support'
4
+ require 'active_record'
5
+ require 'action_controller'
6
+ require 'action_view'
7
+ require 'shoulda'
8
+
9
+ require File.join(File.dirname(__FILE__), 'shoulda_macros', 'generator_macros')
10
+ require File.join(File.dirname(__FILE__), 'stolen_from_railties')
11
+
12
+ unless defined?(RAILS_DEFAULT_LOGGER)
13
+ @test_log = File.join(RAILS_ROOT, 'test.log')
14
+ RAILS_DEFAULT_LOGGER = Logger.new(@test_log)
15
+ end
16
+
17
+ Rails::Generator::Base.prepend_sources Rails::Generator::PathSource.new(:mongo_mapper_generators, File.join(File.dirname(__FILE__), "..", "rails_generators"))
18
+
19
+ class GeneratorTestCase
20
+ def run_generator(name, params=[])
21
+ silence_generator do
22
+ build_generator(name, params).command(:create).invoke!
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ class Test::Unit::TestCase
2
+ class << self
3
+
4
+ def should_generate_file(file, &block)
5
+ should "generate file #{file}" do
6
+ yield("foo") if block_given?
7
+ assert_generated_file(file)
8
+ end
9
+ end
10
+
11
+ def should_not_generate_file(file)
12
+ should "not generate file #{file}" do
13
+ assert !File.exists?(file),"The file '#{file}' should not exist"
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,287 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+
4
+ # Mock out what we need from AR::Base
5
+ module ActiveRecord
6
+ class Base
7
+ class << self
8
+ attr_accessor :pluralize_table_names, :timestamped_migrations
9
+ end
10
+ self.pluralize_table_names = true
11
+ self.timestamped_migrations = true
12
+ end
13
+
14
+ module ConnectionAdapters
15
+ class Column
16
+ attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
17
+
18
+ def initialize(name, default, sql_type = nil)
19
+ @name = name
20
+ @default = default
21
+ @type = @sql_type = sql_type
22
+ end
23
+
24
+ def human_name
25
+ @name.humanize
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ # Mock up necessities from ActionView
32
+ module ActionView
33
+ module Helpers
34
+ module ActionRecordHelper; end
35
+ class InstanceTag; end
36
+ end
37
+ end
38
+
39
+ # Set RAILS_ROOT appropriately fixture generation
40
+ tmp_dir = "#{File.dirname(__FILE__)}/fixtures/tmp"
41
+
42
+ if defined? RAILS_ROOT
43
+ RAILS_ROOT.replace tmp_dir
44
+ else
45
+ RAILS_ROOT = tmp_dir
46
+ end
47
+ FileUtils.mkdir_p RAILS_ROOT
48
+
49
+ require 'initializer'
50
+
51
+ # Mocks out the configuration
52
+ module Rails
53
+ def self.configuration
54
+ Rails::Configuration.new
55
+ end
56
+ end
57
+
58
+ require 'rails_generator'
59
+
60
+ class GeneratorTestCase < Test::Unit::TestCase
61
+ include FileUtils
62
+
63
+ def setup
64
+ ActiveRecord::Base.pluralize_table_names = true
65
+
66
+ mkdir_p "#{RAILS_ROOT}/app/views/layouts"
67
+ mkdir_p "#{RAILS_ROOT}/config"
68
+ mkdir_p "#{RAILS_ROOT}/db"
69
+ mkdir_p "#{RAILS_ROOT}/test/fixtures"
70
+ mkdir_p "#{RAILS_ROOT}/public/stylesheets"
71
+
72
+ File.open("#{RAILS_ROOT}/config/routes.rb", 'w') do |f|
73
+ f << "ActionController::Routing::Routes.draw do |map|\n\nend"
74
+ end
75
+ end
76
+
77
+ def teardown
78
+ rm_rf "#{RAILS_ROOT}/app"
79
+ rm_rf "#{RAILS_ROOT}/test"
80
+ rm_rf "#{RAILS_ROOT}/config"
81
+ rm_rf "#{RAILS_ROOT}/db"
82
+ rm_rf "#{RAILS_ROOT}/public"
83
+ end
84
+
85
+ def test_truth
86
+ # don't complain, test/unit
87
+ end
88
+
89
+ # Instantiates the Generator.
90
+ def build_generator(name, params)
91
+ Rails::Generator::Base.instance(name, params)
92
+ end
93
+
94
+ # Runs the +create+ command (like the command line does).
95
+ def run_generator(name, params)
96
+ silence_generator do
97
+ build_generator(name, params).command(:create).invoke!
98
+ end
99
+ end
100
+
101
+ # Silences the logger temporarily and returns the output as a String.
102
+ def silence_generator
103
+ logger_original = Rails::Generator::Base.logger
104
+ myout = StringIO.new
105
+ Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(myout)
106
+ yield if block_given?
107
+ Rails::Generator::Base.logger = logger_original
108
+ myout.string
109
+ end
110
+
111
+ # Asserts that the given controller was generated.
112
+ # It takes a name or symbol without the <tt>_controller</tt> part and an optional super class.
113
+ # The contents of the class source file is passed to a block.
114
+ def assert_generated_controller_for(name, parent = "ApplicationController")
115
+ assert_generated_class "app/controllers/#{name.to_s.underscore}_controller", parent do |body|
116
+ yield body if block_given?
117
+ end
118
+ end
119
+
120
+ # Asserts that the given model was generated.
121
+ # It takes a name or symbol and an optional super class.
122
+ # The contents of the class source file is passed to a block.
123
+ def assert_generated_model_for(name, parent = "ActiveRecord::Base")
124
+ assert_generated_class "app/models/#{name.to_s.underscore}", parent do |body|
125
+ yield body if block_given?
126
+ end
127
+ end
128
+
129
+ # Asserts that the given helper was generated.
130
+ # It takes a name or symbol without the <tt>_helper</tt> part.
131
+ # The contents of the module source file is passed to a block.
132
+ def assert_generated_helper_for(name)
133
+ assert_generated_module "app/helpers/#{name.to_s.underscore}_helper" do |body|
134
+ yield body if block_given?
135
+ end
136
+ end
137
+
138
+ # Asserts that the given functional test was generated.
139
+ # It takes a name or symbol without the <tt>_controller_test</tt> part and an optional super class.
140
+ # The contents of the class source file is passed to a block.
141
+ def assert_generated_functional_test_for(name, parent = "ActionController::TestCase")
142
+ assert_generated_class "test/functional/#{name.to_s.underscore}_controller_test",parent do |body|
143
+ yield body if block_given?
144
+ end
145
+ end
146
+
147
+ # Asserts that the given unit test was generated.
148
+ # It takes a name or symbol without the <tt>_test</tt> part and an optional super class.
149
+ # The contents of the class source file is passed to a block.
150
+ def assert_generated_unit_test_for(name, parent = "ActiveSupport::TestCase")
151
+ assert_generated_class "test/unit/#{name.to_s.underscore}_test", parent do |body|
152
+ yield body if block_given?
153
+ end
154
+ end
155
+
156
+ # Asserts that the given file was generated.
157
+ # The contents of the file is passed to a block.
158
+ def assert_generated_file(path)
159
+ assert_file_exists(path)
160
+ File.open("#{RAILS_ROOT}/#{path}") do |f|
161
+ yield f.read if block_given?
162
+ end
163
+ end
164
+
165
+ # asserts that the given file exists
166
+ def assert_file_exists(path)
167
+ assert File.exist?("#{RAILS_ROOT}/#{path}"),
168
+ "The file '#{RAILS_ROOT}/#{path}' should exist"
169
+ end
170
+
171
+ # Asserts that the given class source file was generated.
172
+ # It takes a path without the <tt>.rb</tt> part and an optional super class.
173
+ # The contents of the class source file is passed to a block.
174
+ def assert_generated_class(path, parent = nil)
175
+ # FIXME: Sucky way to detect namespaced classes
176
+ if path.split('/').size > 3
177
+ path =~ /\/?(\d+_)?(\w+)\/(\w+)$/
178
+ class_name = "#{$2.camelize}::#{$3.camelize}"
179
+ else
180
+ path =~ /\/?(\d+_)?(\w+)$/
181
+ class_name = $2.camelize
182
+ end
183
+
184
+ assert_generated_file("#{path}.rb") do |body|
185
+ assert_match /class #{class_name}#{parent.nil? ? '':" < #{parent}"}/, body, "the file '#{path}.rb' should be a class"
186
+ yield body if block_given?
187
+ end
188
+ end
189
+
190
+ # Asserts that the given module source file was generated.
191
+ # It takes a path without the <tt>.rb</tt> part.
192
+ # The contents of the class source file is passed to a block.
193
+ def assert_generated_module(path)
194
+ # FIXME: Sucky way to detect namespaced modules
195
+ if path.split('/').size > 3
196
+ path =~ /\/?(\w+)\/(\w+)$/
197
+ module_name = "#{$1.camelize}::#{$2.camelize}"
198
+ else
199
+ path =~ /\/?(\w+)$/
200
+ module_name = $1.camelize
201
+ end
202
+
203
+ assert_generated_file("#{path}.rb") do |body|
204
+ assert_match /module #{module_name}/, body, "the file '#{path}.rb' should be a module"
205
+ yield body if block_given?
206
+ end
207
+ end
208
+
209
+ # Asserts that the given CSS stylesheet file was generated.
210
+ # It takes a path without the <tt>.css</tt> part.
211
+ # The contents of the stylesheet source file is passed to a block.
212
+ def assert_generated_stylesheet(path)
213
+ assert_generated_file("public/stylesheets/#{path}.css") do |body|
214
+ yield body if block_given?
215
+ end
216
+ end
217
+
218
+ # Asserts that the given YAML file was generated.
219
+ # It takes a path without the <tt>.yml</tt> part.
220
+ # The parsed YAML tree is passed to a block.
221
+ def assert_generated_yaml(path)
222
+ assert_generated_file("#{path}.yml") do |body|
223
+ yaml = YAML.load(body)
224
+ assert yaml, 'YAML data missing'
225
+ yield yaml if block_given?
226
+ end
227
+ end
228
+
229
+ # Asserts that the given fixtures YAML file was generated.
230
+ # It takes a fixture name without the <tt>.yml</tt> part.
231
+ # The parsed YAML tree is passed to a block.
232
+ def assert_generated_fixtures_for(name)
233
+ assert_generated_yaml "test/fixtures/#{name.to_s.underscore}" do |yaml|
234
+ yield yaml if block_given?
235
+ end
236
+ end
237
+
238
+ # Asserts that the given views were generated.
239
+ # It takes a controller name and a list of views (including extensions).
240
+ # The body of each view is passed to a block.
241
+ def assert_generated_views_for(name, *actions)
242
+ actions.each do |action|
243
+ assert_generated_file("app/views/#{name.to_s.underscore}/#{action}") do |body|
244
+ yield body if block_given?
245
+ end
246
+ end
247
+ end
248
+
249
+ def assert_generated_migration(name, parent = "ActiveRecord::Migration")
250
+ file = Dir.glob("#{RAILS_ROOT}/db/migrate/*_#{name.to_s.underscore}.rb").first
251
+ file = file.match(/db\/migrate\/[0-9]+_\w+/).to_s
252
+ assert_generated_class file, parent do |body|
253
+ assert_match /timestamps/, body, "should have timestamps defined"
254
+ yield body if block_given?
255
+ end
256
+ end
257
+
258
+ # Asserts that the given migration file was not generated.
259
+ # It takes the name of the migration as a parameter.
260
+ def assert_skipped_migration(name)
261
+ migration_file = "#{RAILS_ROOT}/db/migrate/001_#{name.to_s.underscore}.rb"
262
+ assert !File.exist?(migration_file), "should not create migration #{migration_file}"
263
+ end
264
+
265
+ # Asserts that the given resource was added to the routes.
266
+ def assert_added_route_for(name)
267
+ assert_generated_file("config/routes.rb") do |body|
268
+ assert_match /map.resources :#{name.to_s.underscore}/, body,
269
+ "should add route for :#{name.to_s.underscore}"
270
+ end
271
+ end
272
+
273
+ # Asserts that the given methods are defined in the body.
274
+ # This does assume standard rails code conventions with regards to the source code.
275
+ # The body of each individual method is passed to a block.
276
+ def assert_has_method(body, *methods)
277
+ methods.each do |name|
278
+ assert body =~ /^ def #{name}(\(.+\))?\n((\n| .*\n)*) end/, "should have method #{name}"
279
+ yield(name, $2) if block_given?
280
+ end
281
+ end
282
+
283
+ # Asserts that the given column is defined in the migration.
284
+ def assert_generated_column(body, name, type)
285
+ assert_match /t\.#{type.to_s} :#{name.to_s}/, body, "should have column #{name.to_s} defined"
286
+ end
287
+ end
@@ -0,0 +1,46 @@
1
+ require 'helper'
2
+
3
+ class TestMongoMapperGenerators < GeneratorTestCase
4
+
5
+ context "running the mongo_initializer generator" do
6
+ setup do
7
+ run_generator('mongo_initializer')
8
+ end
9
+
10
+ should_generate_file 'config/initializers/mongomapper.rb'
11
+ should_generate_file 'config/database.yml'
12
+ end
13
+
14
+ context "running the mongo_model generator" do
15
+
16
+ context "with factories" do
17
+ setup do
18
+ run_generator('mongo_model', %w(Person name:string email:string many:addresses index:email belongs_to:corporation))
19
+ end
20
+
21
+ should_generate_file 'app/models/person.rb'
22
+ should_generate_file 'test/unit/person_test.rb'
23
+ should_generate_file 'test/factories/people.rb'
24
+ end
25
+
26
+ context "without factories" do
27
+ setup do
28
+ run_generator('mongo_model', %w(Person name:string email:string many:addresses index:email belongs_to:corporation --skip-factories))
29
+ end
30
+
31
+ should_generate_file 'app/models/person.rb'
32
+ should_generate_file 'test/unit/person_test.rb'
33
+ should_not_generate_file 'test/factories/people.rb'
34
+ end
35
+ end
36
+
37
+ context "running the embedded_model generator" do
38
+ setup do
39
+ run_generator('embedded_model', %w(Address street:string state:integer city:string zip:string))
40
+ end
41
+
42
+ should_generate_file 'app/models/address.rb'
43
+ should_generate_file 'test/unit/address_test.rb'
44
+ should_generate_file 'test/factories/addresses.rb'
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo_mapper_generators
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Steve Agalloco
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-15 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.10.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: cucumber
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.0
34
+ version:
35
+ description: Generators for use with the MongoMapper rubygem. Use to generate Documents, EmbeddedDocuments, and Rails initializer.
36
+ email: steve.agalloco@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - LICENSE
46
+ - README.rdoc
47
+ - Rakefile
48
+ - VERSION
49
+ - lib/mongo_mapper_generators.rb
50
+ - rails_generators/embedded_model/USAGE
51
+ - rails_generators/embedded_model/embedded_model_generator.rb
52
+ - rails_generators/embedded_model/templates/embedded_model.rb
53
+ - rails_generators/embedded_model/templates/factory.rb
54
+ - rails_generators/embedded_model/templates/unit_test.rb
55
+ - rails_generators/mongo_initializer/USAGE
56
+ - rails_generators/mongo_initializer/mongo_initializer_generator.rb
57
+ - rails_generators/mongo_initializer/templates/database.yml
58
+ - rails_generators/mongo_initializer/templates/initializer.rb
59
+ - rails_generators/mongo_model/USAGE
60
+ - rails_generators/mongo_model/mongo_model_generator.rb
61
+ - rails_generators/mongo_model/templates/factory.rb
62
+ - rails_generators/mongo_model/templates/mongo_model.rb
63
+ - rails_generators/mongo_model/templates/unit_test.rb
64
+ - rails_generators/support/generator_helper.rb
65
+ - test/fixtures/tmp/test.log
66
+ - test/helper.rb
67
+ - test/shoulda_macros/generator_macros.rb
68
+ - test/stolen_from_railties.rb
69
+ - test/test_mongo_mapper_generators.rb
70
+ has_rdoc: true
71
+ homepage: http://github.com/spagalloco/mongo_mapper_generators
72
+ licenses: []
73
+
74
+ post_install_message:
75
+ rdoc_options:
76
+ - --charset=UTF-8
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ version:
91
+ requirements: []
92
+
93
+ rubyforge_project:
94
+ rubygems_version: 1.3.5
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Generators for use with the MongoMapper rubygem
98
+ test_files:
99
+ - test/helper.rb
100
+ - test/shoulda_macros/generator_macros.rb
101
+ - test/stolen_from_railties.rb
102
+ - test/test_mongo_mapper_generators.rb