shoulda_machinist_generator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +17 -0
  3. data/Rakefile +28 -0
  4. data/VERSION +1 -0
  5. data/rails_generators/shoulda_model/USAGE +27 -0
  6. data/rails_generators/shoulda_model/shoulda_model_generator.rb +70 -0
  7. data/rails_generators/shoulda_model/templates/blueprints.rb +24 -0
  8. data/rails_generators/shoulda_model/templates/migration.rb +16 -0
  9. data/rails_generators/shoulda_model/templates/model.rb +2 -0
  10. data/rails_generators/shoulda_model/templates/unit_test.rb +7 -0
  11. data/rails_generators/shoulda_scaffold/USAGE +34 -0
  12. data/rails_generators/shoulda_scaffold/shoulda_scaffold_generator.rb +166 -0
  13. data/rails_generators/shoulda_scaffold/templates/blueprint/ie.css +22 -0
  14. data/rails_generators/shoulda_scaffold/templates/blueprint/print.css +29 -0
  15. data/rails_generators/shoulda_scaffold/templates/blueprint/screen.css +226 -0
  16. data/rails_generators/shoulda_scaffold/templates/controller.rb +72 -0
  17. data/rails_generators/shoulda_scaffold/templates/erb/_form.html.erb +8 -0
  18. data/rails_generators/shoulda_scaffold/templates/erb/edit.html.erb +12 -0
  19. data/rails_generators/shoulda_scaffold/templates/erb/index.html.erb +22 -0
  20. data/rails_generators/shoulda_scaffold/templates/erb/layout.html.erb +22 -0
  21. data/rails_generators/shoulda_scaffold/templates/erb/new.html.erb +8 -0
  22. data/rails_generators/shoulda_scaffold/templates/erb/show.html.erb +12 -0
  23. data/rails_generators/shoulda_scaffold/templates/functional_test/basic.rb +107 -0
  24. data/rails_generators/shoulda_scaffold/templates/helper.rb +2 -0
  25. data/test/fixtures/about_yml_plugins/bad_about_yml/about.yml +1 -0
  26. data/test/fixtures/about_yml_plugins/bad_about_yml/init.rb +1 -0
  27. data/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb +1 -0
  28. data/test/fixtures/eager/zoo.rb +3 -0
  29. data/test/fixtures/eager/zoo/reptile_house.rb +2 -0
  30. data/test/fixtures/environment_with_constant.rb +1 -0
  31. data/test/fixtures/lib/generators/missing_class/missing_class_generator.rb +0 -0
  32. data/test/fixtures/lib/generators/working/working_generator.rb +2 -0
  33. data/test/fixtures/plugins/alternate/a/generators/a_generator/a_generator.rb +4 -0
  34. data/test/fixtures/plugins/default/gemlike/init.rb +1 -0
  35. data/test/fixtures/plugins/default/gemlike/lib/gemlike.rb +2 -0
  36. data/test/fixtures/plugins/default/gemlike/rails/init.rb +7 -0
  37. data/test/fixtures/plugins/default/plugin_with_no_lib_dir/init.rb +0 -0
  38. data/test/fixtures/plugins/default/stubby/about.yml +2 -0
  39. data/test/fixtures/plugins/default/stubby/generators/stubby_generator/stubby_generator.rb +4 -0
  40. data/test/fixtures/plugins/default/stubby/init.rb +7 -0
  41. data/test/fixtures/plugins/default/stubby/lib/stubby_mixin.rb +2 -0
  42. data/test/fixtures/tmp/test.log +1 -0
  43. data/test/rails_generators/shoulda_model_generator_test.rb +39 -0
  44. data/test/shoulda_macros/generator_macros.rb +36 -0
  45. data/test/stolen_from_railties.rb +288 -0
  46. data/test/test_helper.rb +41 -0
  47. metadata +120 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Dave Hrycyszyn
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,17 @@
1
+ = shoulda_machinist_generator
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (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)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2009 Dave Hrycyszyn. See LICENSE for details.
@@ -0,0 +1,28 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |s|
7
+ s.name = "shoulda_machinist_generator"
8
+ s.summary = "Generators which create tests using shoulda and machinist"
9
+ s.email = "dave.hrycyszyn@headlondon.com"
10
+ s.homepage = "http://github.com/futurechimp/shoulda_machinist_generator"
11
+ s.description = "Generators which create tests using shoulda and machinist"
12
+ s.authors = ["Dave Hrycyszyn", "Stuart Chinery"]
13
+ s.files = FileList["[A-Z]*", "{rails_generators,test}/**/*"]
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
18
+ end
19
+
20
+ Rake::TestTask.new do |t|
21
+ t.libs << 'lib'
22
+ t.pattern = 'test/**/*_test.rb'
23
+ t.verbose = false
24
+ end
25
+
26
+ desc 'Test by default'
27
+ task :default => :test
28
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,27 @@
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 column_name:sql_type arguments specifying the
6
+ model's attributes. Timestamps are added by default, so you don't have to
7
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
8
+
9
+ You don't have to think up every attribute up front, but it helps to
10
+ sketch out a few so you can start working with the model immediately.
11
+
12
+ This generates a model class in app/models, a unit test in test/unit,
13
+ a test fixture in test/fixtures/singular_name.yml, and a migration in
14
+ db/migrate.
15
+
16
+ Examples:
17
+ `./script/generate shoulda_model account`
18
+
19
+ creates an Account model, test, factory, and migration:
20
+ Model: app/models/account.rb
21
+ Test: test/unit/account_test.rb
22
+ Factory: test/factories/account_factory.rb
23
+ Migration: db/migrate/XXX_add_accounts.rb
24
+
25
+ `./script/generate shoulda_model post title:string body:text published:boolean`
26
+
27
+ creates a Post model with a string title, text body, and published flag.
@@ -0,0 +1,70 @@
1
+ class ShouldaModelGenerator < Rails::Generator::NamedBase
2
+ default_options :skip_timestamps => false, :skip_migration => false
3
+
4
+ def manifest
5
+ record do |m|
6
+ # Check for class naming collisions.
7
+ m.class_collisions class_path, class_name, "#{class_name}Test"
8
+
9
+ # Model, test, and fixture directories.
10
+ m.directory File.join('app/models', class_path)
11
+ m.directory File.join('test/unit', class_path)
12
+
13
+ # Model class, unit test, and blueprint.
14
+ m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
15
+ m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
16
+
17
+ unless options[:skip_migration]
18
+ m.migration_template 'migration.rb', 'db/migrate', :assigns => {
19
+ :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
20
+ }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
21
+ end
22
+
23
+ m.template 'blueprints.rb', File.join('test', "blueprints.rb")
24
+ m.blueprint_resources class_name
25
+ end
26
+ end
27
+
28
+ def factory_line(attribute)
29
+ "#{file_name}.#{attribute.name} '#{attribute.default}'"
30
+ end
31
+
32
+ protected
33
+ def banner
34
+ "Usage: #{$0} #{spec.name} ModelName [field:type, field:type]"
35
+ end
36
+
37
+ def add_options!(opt)
38
+ opt.separator ''
39
+ opt.separator 'Options:'
40
+ opt.on("--skip-timestamps",
41
+ "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
42
+ opt.on("--skip-migration",
43
+ "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
44
+ opt.on("--skip-factory",
45
+ "Don't generation a fixture file for this model") { |v| options[:skip_factory] = v}
46
+ end
47
+
48
+ # This inserts the routing declarations into the engine's routes file.
49
+ # Copied from Rails::Generator::Commands and modified to make it do what we want.
50
+ #
51
+ def blueprint_resources(class_name)
52
+ # Add the map.namespace(:admin) macro into the routes file unless it's already there.
53
+ #
54
+ sentinel = '# Model class blueprints'
55
+ gsub_file File.join('test', 'blueprints.rb'), /(#{Regexp.escape(sentinel)})/mi do |match|
56
+ "\n#{match}\n#{class_name}.blueprint do\nend"
57
+ end
58
+
59
+ end
60
+
61
+
62
+ # It's quite crude to copy and paste this in here, but it's working for the moment. It actually comes
63
+ # from Rails::Generator::Commands. This should be fixed.
64
+ #
65
+ def gsub_file(relative_destination, regexp, *args, &block)
66
+ path = destination_path(relative_destination)
67
+ content = File.read(path).gsub(regexp, *args, &block)
68
+ File.open(path, File::RDWR|File::CREAT) { |file| file.write(content) }
69
+ end
70
+ end
@@ -0,0 +1,24 @@
1
+ require 'machinist/active_record'
2
+ require 'sham'
3
+ require 'faker'
4
+
5
+ # Shams - generated filler values
6
+ #
7
+
8
+ chars = ['A'..'Z', 'a'..'z'].map{|r|r.to_a}.flatten
9
+
10
+ Sham.define do
11
+ # title { Faker::Lorem.words }
12
+ # person_name { Faker::Name.name }
13
+ # description { Faker::Lorem.words }
14
+ # # Make a fake username that passes validation
15
+ # login { Array.new(20).map{chars[rand(chars.size)]}.join }
16
+ # email { Faker::Internet.email}
17
+ # telephone { Faker::PhoneNumber.phone_number}
18
+ # client_id { Faker::PhoneNumber.phone_number }
19
+ end
20
+
21
+
22
+
23
+ # Model class blueprints
24
+
@@ -0,0 +1,16 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ <% for attribute in attributes -%>
5
+ t.<%= attribute.type %> :<%= attribute.name %>
6
+ <% end -%>
7
+ <% unless options[:skip_timestamps] %>
8
+ t.timestamps
9
+ <% end -%>
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :<%= table_name %>
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ class <%= class_name %> < ActiveRecord::Base
2
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ <% for attribute in attributes -%>
5
+ should_have_db_column :<%= attribute.name %>
6
+ <% end -%>
7
+ end
@@ -0,0 +1,34 @@
1
+ Description:
2
+ Scaffolds an entire resource, from model and migration to controller and
3
+ views, along with a full test suite. The resource is ready to use as a
4
+ starting point for your restful, resource-oriented application.
5
+
6
+ Pass the name of the model, either CamelCased or under_scored, as the first
7
+ argument, and an optional list of attribute pairs.
8
+
9
+ Attribute pairs are column_name:sql_type arguments specifying the
10
+ model's attributes. Timestamps are added by default, so you don't have to
11
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
12
+
13
+ You don't have to think up every attribute up front, but it helps to
14
+ sketch out a few so you can start working with the resource immediately.
15
+
16
+ For example, `scaffold post title:string body:text published:boolean`
17
+ gives you a model with those three attributes, a controller that handles
18
+ the create/show/update/destroy, forms to create and edit your posts, and
19
+ an index that lists them all, as well as a map.resources :posts
20
+ declaration in config/routes.rb.
21
+
22
+ You can override the default values for templating and
23
+ functional\_test\_style by placing a .shoulda\_generator file in your home
24
+ directory.
25
+
26
+ Here's an example `.shoulda_generator`:
27
+
28
+ :templating: erb # supported options: haml|erb
29
+ :functional_test_syle: basic # supported options: should_be_restful|basic
30
+
31
+ Examples:
32
+ `./script/generate shoulda_scaffold post` # no attributes, view will be anemic
33
+ `./script/generate shoulda_scaffold post title:string body:text published:boolean`
34
+ `./script/generate shoulda_scaffold purchase order_id:integer amount:decimal`
@@ -0,0 +1,166 @@
1
+ #--
2
+ # ShouldaScaffoldGeneratorConfig based on rubygems code.
3
+ # Thank you Chad Fowler, Rich Kilmer, Jim Weirich and others.
4
+ #++
5
+ class ShouldaScaffoldGeneratorConfig
6
+
7
+ DEFAULT_TEMPLATING = 'erb'
8
+ DEFAULT_FUNCTIONAL_TEST_STYLE = 'basic'
9
+
10
+ def initialize()
11
+ @config = load_file(config_file)
12
+
13
+ @templating = @config[:templating] || DEFAULT_TEMPLATING
14
+ @functional_test_style = @config[:functional_test_style] || DEFAULT_FUNCTIONAL_TEST_STYLE
15
+ end
16
+
17
+ attr_reader :templating, :functional_test_style
18
+
19
+ private
20
+
21
+ def load_file(filename)
22
+ begin
23
+ YAML.load(File.read(filename)) if filename and File.exist?(filename)
24
+ rescue ArgumentError
25
+ warn "Failed to load #{config_file_name}"
26
+ rescue Errno::EACCES
27
+ warn "Failed to load #{config_file_name} due to permissions problem."
28
+ end or {}
29
+ end
30
+
31
+ def config_file
32
+ File.join(find_home, '.shoulda_generator')
33
+ end
34
+
35
+ ##
36
+ # Finds the user's home directory.
37
+
38
+ def find_home
39
+ ['HOME', 'USERPROFILE'].each do |homekey|
40
+ return ENV[homekey] if ENV[homekey]
41
+ end
42
+
43
+ if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
44
+ return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
45
+ end
46
+
47
+ begin
48
+ File.expand_path("~")
49
+ rescue
50
+ if File::ALT_SEPARATOR then
51
+ "C:/"
52
+ else
53
+ "/"
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ class ShouldaScaffoldGenerator < Rails::Generator::NamedBase
60
+ default_options :skip_timestamps => false, :skip_migration => false, :skip_layout => true
61
+
62
+ attr_reader :controller_name,
63
+ :controller_class_path,
64
+ :controller_file_path,
65
+ :controller_class_nesting,
66
+ :controller_class_nesting_depth,
67
+ :controller_class_name,
68
+ :controller_underscore_name,
69
+ :controller_singular_name,
70
+ :controller_plural_name
71
+ alias_method :controller_file_name, :controller_underscore_name
72
+ alias_method :controller_table_name, :controller_plural_name
73
+
74
+ def initialize(runtime_args, runtime_options = {})
75
+ super
76
+
77
+ @configuration = ShouldaScaffoldGeneratorConfig.new
78
+
79
+ @controller_name = @name.pluralize
80
+
81
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
82
+ @controller_class_name_without_nesting, @controller_underscore_name, @controller_plural_name = inflect_names(base_name)
83
+ @controller_singular_name=base_name.singularize
84
+ if @controller_class_nesting.empty?
85
+ @controller_class_name = @controller_class_name_without_nesting
86
+ else
87
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
88
+ end
89
+ end
90
+
91
+ def manifest
92
+ record do |m|
93
+ # Check for class naming collisions.
94
+ m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
95
+ m.class_collisions(class_path, "#{class_name}")
96
+
97
+ # Controller, helper, views, and test directories.
98
+ m.directory(File.join('app/models', class_path))
99
+ m.directory(File.join('app/controllers', controller_class_path))
100
+ m.directory(File.join('app/helpers', controller_class_path))
101
+ m.directory(File.join('app/views', controller_class_path, controller_file_name))
102
+ m.directory(File.join('app/views/layouts', controller_class_path))
103
+ m.directory(File.join('test/functional', controller_class_path))
104
+ m.directory(File.join('test/unit', class_path))
105
+
106
+ m.directory('public/stylesheets/blueprint')
107
+
108
+ for view in scaffold_views
109
+ m.template(
110
+ "#{templating}/#{view}.html.#{templating}",
111
+ File.join('app/views', controller_class_path, controller_file_name, "#{view}.html.#{templating}")
112
+ )
113
+ end
114
+
115
+ # Layout and stylesheet.
116
+ m.template("#{templating}/layout.html.#{templating}", File.join('app/views/layouts', controller_class_path, "#{controller_file_name}.html.#{templating}"))
117
+
118
+ %w(print screen ie).each do |stylesheet|
119
+ m.template("blueprint/#{stylesheet}.css", "public/stylesheets/blueprint/#{stylesheet}.css")
120
+ end
121
+
122
+ m.template(
123
+ 'controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
124
+ )
125
+
126
+ m.template("functional_test/#{functional_test_style}.rb", File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
127
+ m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
128
+
129
+ m.route_resources controller_file_name
130
+
131
+ m.dependency 'shoulda_model', [name] + @args, :collision => :skip
132
+ end
133
+ end
134
+
135
+ def templating
136
+ options[:templating] || @configuration.templating
137
+ end
138
+
139
+ def functional_test_style
140
+ options[:functional_test_style] || @configuration.functional_test_style
141
+ end
142
+
143
+ protected
144
+ # Override with your own usage banner.
145
+ def banner
146
+ "Usage: #{$0} scaffold ModelName [field:type, field:type]"
147
+ end
148
+
149
+ def add_options!(opt)
150
+ opt.separator ''
151
+ opt.separator 'Options:'
152
+ opt.on("--skip-timestamps",
153
+ "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
154
+ opt.on("--skip-migration",
155
+ "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
156
+
157
+ end
158
+
159
+ def scaffold_views
160
+ %w[ index show new edit _form ]
161
+ end
162
+
163
+ def model_name
164
+ class_name.demodulize
165
+ end
166
+ end
@@ -0,0 +1,22 @@
1
+ /* -----------------------------------------------------------------------
2
+
3
+ Blueprint CSS Framework 0.7.1
4
+ http://blueprintcss.googlecode.com
5
+
6
+ * Copyright (c) 2007-2008. See LICENSE for more info.
7
+ * See README for instructions on how to use Blueprint.
8
+ * For credits and origins, see AUTHORS.
9
+ * This is a compressed file. See the sources in the 'src' directory.
10
+
11
+ ----------------------------------------------------------------------- */
12
+
13
+ /* ie.css */
14
+ body {text-align:center;}
15
+ .container {text-align:left;}
16
+ * html .column {overflow-x:hidden;}
17
+ * html legend {margin:-18px -8px 16px 0;padding:0;}
18
+ ol {margin-left:2em;}
19
+ sup {vertical-align:text-top;}
20
+ sub {vertical-align:text-bottom;}
21
+ html>body p code {*white-space:normal;}
22
+ hr {margin:-8px auto 11px;}