dry_scaffold 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/CHANGELOG.textile +55 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.textile +473 -0
  4. data/Rakefile +54 -0
  5. data/TODO.textile +36 -0
  6. data/bin/dmodel +3 -0
  7. data/bin/dry_model +3 -0
  8. data/bin/dry_scaffold +3 -0
  9. data/bin/dscaffold +3 -0
  10. data/config/scaffold.yml +33 -0
  11. data/generators/dmodel/dmodel_generator.rb +15 -0
  12. data/generators/dry_model/USAGE +9 -0
  13. data/generators/dry_model/dry_model_generator.rb +134 -0
  14. data/generators/dry_model/prototypes/active_record_migration.rb +17 -0
  15. data/generators/dry_model/prototypes/active_record_model.rb +9 -0
  16. data/generators/dry_model/prototypes/fixture_data/active_record_fixtures.yml +3 -0
  17. data/generators/dry_model/prototypes/fixture_data/factory_girl_factories.rb +4 -0
  18. data/generators/dry_model/prototypes/fixture_data/machinist_blueprints.rb +8 -0
  19. data/generators/dry_model/prototypes/tests/rspec/unit_test.rb +9 -0
  20. data/generators/dry_model/prototypes/tests/shoulda/unit_test.rb +20 -0
  21. data/generators/dry_model/prototypes/tests/test_unit/unit_test.rb +15 -0
  22. data/generators/dry_model/templates/models/active_record_migration.rb +23 -0
  23. data/generators/dry_model/templates/models/active_record_model.rb +15 -0
  24. data/generators/dry_model/templates/models/fixture_data/active_record_fixtures.yml +6 -0
  25. data/generators/dry_model/templates/models/fixture_data/factory_girl_factories.rb +5 -0
  26. data/generators/dry_model/templates/models/fixture_data/machinist_blueprints.rb +9 -0
  27. data/generators/dry_model/templates/models/tests/rspec/unit_test.rb +11 -0
  28. data/generators/dry_model/templates/models/tests/shoulda/unit_test.rb +23 -0
  29. data/generators/dry_model/templates/models/tests/test_unit/unit_test.rb +17 -0
  30. data/generators/dry_scaffold/USAGE +11 -0
  31. data/generators/dry_scaffold/dry_scaffold_generator.rb +410 -0
  32. data/generators/dry_scaffold/prototypes/controllers/action_controller.rb +135 -0
  33. data/generators/dry_scaffold/prototypes/controllers/inherited_resources_controller.rb +25 -0
  34. data/generators/dry_scaffold/prototypes/controllers/tests/rspec/functional_test.rb +57 -0
  35. data/generators/dry_scaffold/prototypes/controllers/tests/shoulda/functional_test.rb +99 -0
  36. data/generators/dry_scaffold/prototypes/controllers/tests/test_unit/functional_test.rb +70 -0
  37. data/generators/dry_scaffold/prototypes/helpers/helper.rb +3 -0
  38. data/generators/dry_scaffold/prototypes/helpers/tests/rspec/unit_test.rb +9 -0
  39. data/generators/dry_scaffold/prototypes/helpers/tests/shoulda/unit_test.rb +9 -0
  40. data/generators/dry_scaffold/prototypes/helpers/tests/test_unit/unit_test.rb +9 -0
  41. data/generators/dry_scaffold/prototypes/views/builder/index.atom.builder +20 -0
  42. data/generators/dry_scaffold/prototypes/views/builder/index.rss.builder +21 -0
  43. data/generators/dry_scaffold/prototypes/views/haml/_form.html.haml +3 -0
  44. data/generators/dry_scaffold/prototypes/views/haml/_item.html.haml +9 -0
  45. data/generators/dry_scaffold/prototypes/views/haml/edit.html.haml +10 -0
  46. data/generators/dry_scaffold/prototypes/views/haml/index.html.haml +17 -0
  47. data/generators/dry_scaffold/prototypes/views/haml/layout.html.haml +18 -0
  48. data/generators/dry_scaffold/prototypes/views/haml/new.html.haml +10 -0
  49. data/generators/dry_scaffold/prototypes/views/haml/show.html.haml +13 -0
  50. data/generators/dry_scaffold/templates/controllers/action_controller.rb +250 -0
  51. data/generators/dry_scaffold/templates/controllers/inherited_resources_controller.rb +26 -0
  52. data/generators/dry_scaffold/templates/controllers/tests/rspec/functional_test.rb +85 -0
  53. data/generators/dry_scaffold/templates/controllers/tests/shoulda/functional_test.rb +90 -0
  54. data/generators/dry_scaffold/templates/controllers/tests/test_unit/functional_test.rb +87 -0
  55. data/generators/dry_scaffold/templates/helpers/helper.rb +3 -0
  56. data/generators/dry_scaffold/templates/helpers/tests/rspec/unit_test.rb +9 -0
  57. data/generators/dry_scaffold/templates/helpers/tests/shoulda/unit_test.rb +9 -0
  58. data/generators/dry_scaffold/templates/helpers/tests/test_unit/unit_test.rb +9 -0
  59. data/generators/dry_scaffold/templates/views/builder/index.atom.builder +20 -0
  60. data/generators/dry_scaffold/templates/views/builder/index.rss.builder +21 -0
  61. data/generators/dry_scaffold/templates/views/haml/_form.html.haml +13 -0
  62. data/generators/dry_scaffold/templates/views/haml/_item.html.haml +10 -0
  63. data/generators/dry_scaffold/templates/views/haml/edit.html.haml +18 -0
  64. data/generators/dry_scaffold/templates/views/haml/index.html.haml +20 -0
  65. data/generators/dry_scaffold/templates/views/haml/layout.html.haml +19 -0
  66. data/generators/dry_scaffold/templates/views/haml/new.html.haml +18 -0
  67. data/generators/dry_scaffold/templates/views/haml/show.html.haml +13 -0
  68. data/generators/dscaffold/dscaffold_generator.rb +15 -0
  69. data/lib/dry_generator.rb +197 -0
  70. data/lib/dry_scaffold/tasks.rb +5 -0
  71. data/lib/setup_helper.rb +36 -0
  72. data/tasks/dry_scaffold.rake +95 -0
  73. metadata +140 -0
@@ -0,0 +1,54 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ NAME = "dry_scaffold"
6
+ SUMMARY = %Q{A DRYer scaffold generator for Rails. Generates dry semantic and standards compliant views, and dry RESTful controllers.}
7
+ HOMEPAGE = "http://github.com/grimen/#{NAME}"
8
+ AUTHOR = "Jonas Grimfelt"
9
+ EMAIL = "grimen@gmail.com"
10
+ SUPPORT_FILES = %w(README.textile TODO.textile CHANGELOG.textile)
11
+
12
+ begin
13
+ require 'jeweler'
14
+ Jeweler::Tasks.new do |gemspec|
15
+ gemspec.name = NAME
16
+ gemspec.summary = SUMMARY
17
+ gemspec.description = SUMMARY
18
+ gemspec.homepage = HOMEPAGE
19
+ gemspec.author = AUTHOR
20
+ gemspec.email = EMAIL
21
+
22
+ gemspec.require_paths = %w{lib}
23
+ gemspec.files = %w(MIT-LICENSE Rakefile) << SUPPORT_FILES <<
24
+ Dir.glob(File.join('{bin,config,generators,lib,tasks}', '**', '*').to_s)
25
+ gemspec.executables = %w(dscaffold dry_scaffold dmodel dry_model)
26
+ gemspec.extra_rdoc_files = SUPPORT_FILES
27
+
28
+ gemspec.add_dependency 'haml'
29
+ end
30
+
31
+ Jeweler::GemcutterTasks.new
32
+ rescue LoadError
33
+ puts "Jeweler, or one of its dependencies, is not available. " <<
34
+ "Install it with: sudo gem install jeweler -s http://gemcutter.org"
35
+ end
36
+
37
+ desc %Q{Run unit tests for "#{NAME}".}
38
+ task :default => :test
39
+
40
+ desc %Q{Run unit tests for "#{NAME}".}
41
+ Rake::TestTask.new(:test) do |test|
42
+ test.libs << 'lib'
43
+ test.pattern = 'test/**/*_test.rb'
44
+ test.verbose = true
45
+ end
46
+
47
+ desc %Q{Generate documentation for "#{NAME}".}
48
+ Rake::RDocTask.new(:rdoc) do |rdoc|
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = NAME
51
+ rdoc.options << '--line-numbers' << '--inline-source' << '--charset=UTF-8'
52
+ rdoc.rdoc_files.include(SUPPORT_FILES)
53
+ rdoc.rdoc_files.include(File.join('lib', '**', '*.rb'))
54
+ end
@@ -0,0 +1,36 @@
1
+ h1. TODO
2
+
3
+ h2. Next
4
+
5
+ * Bug/Issue: InheritedResources functional testing issue.
6
+ * Feature: Check for overridden templates in: RAILS_ROOT/lib/dry_scaffold/templates/
7
+
8
+ h2. Maybe
9
+
10
+ * Feature: Handle belongs_to, i.e. specify MODEL --belongs-to PARENT_MODEL, which generates proper routes, proper before-filters if inherited_resources-controller, adding belongs_to-association in model, and correct form_for arguments.
11
+ * Feature: Builder for podcast-feed, similar to RSS/Atom-builders. http://wiki.github.com/radiant/radiant/host-a-podcast
12
+
13
+ h2. Issues
14
+
15
+ * Contact José regarding the InheritedResources-issue:
16
+
17
+ ActionController::RoutingError: parrot_url failed to generate from {:controller=>"parrots", :id=>#<Parrot id: nil, name: "Hello", created_at: "2009-07-21 18:53:25", updated_at: "2009-07-21 18:53:25">, :action=>"show"}, expected: {:controller=>"parrots", :action=>"show"}, diff: {:id=>#<Parrot id: nil, name: "Hello", created_at: "2009-07-21 18:53:25", updated_at: "2009-07-21 18:53:25">}
18
+ (eval):16:in `parrot_url'
19
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/url_helpers.rb:194:in `resource_url'
20
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/base_helpers.rb:311:in `send'
21
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/base_helpers.rb:311:in `parse_redirect_url'
22
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/base.rb:79:in `create'
23
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/respond_to.rb:301:in `call'
24
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/respond_to.rb:301:in `respond_any'
25
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/respond_to.rb:233:in `respond_to'
26
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/base_helpers.rb:283:in `respond_to_with_dual_blocks'
27
+ /opt/local/lib/ruby/gems/1.8/gems/josevalim-inherited_resources-0.7.3/lib/inherited_resources/base.rb:78:in `create'
28
+ haml (2.0.9) rails/./lib/sass/plugin/rails.rb:19:in `process'
29
+ /test/functional/donkeys_controller_test.rb:8:in `test_create'
30
+
31
+ test 'create' do
32
+ Donkey.any_instance.expects(:save).returns(true)
33
+ @donkey = donkeys(:basic)
34
+ post :create, :donkey => @donkey.attributes # <<<<<<<<<<<<< donkeys_controller_test.rb:8
35
+ assert_response :redirect
36
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ `ruby script/generate dmodel #{ARGV.join(' ')}`
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ `ruby script/generate dry_model #{ARGV.join(' ')}`
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ `ruby script/generate dry_scaffold #{ARGV.join(' ')}`
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ `ruby script/generate dscaffold #{ARGV.join(' ')}`
@@ -0,0 +1,33 @@
1
+ ---
2
+ dry_scaffold:
3
+ args:
4
+ actions: index,show,new,edit,create,update,destroy
5
+ formats: html,js,xml,json
6
+ options:
7
+ formtastic: true
8
+ resourceful: true
9
+ pagination: true
10
+ layout: false
11
+ views: true
12
+ helpers: true
13
+ tests: true
14
+ controller_tests: true
15
+ test_unit: true
16
+ shoulda: false
17
+ rspec: false
18
+ fixtures: true
19
+ fgirl: false
20
+ machinist: false
21
+ object_daddy: false
22
+ dry_model:
23
+ options:
24
+ migration: true
25
+ timestamps: true
26
+ tests: true
27
+ test_unit: true
28
+ shoulda: false
29
+ rspec: false
30
+ fixtures: true
31
+ fgirl: false
32
+ machinist: false
33
+ object_daddy: false
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'dry_model', 'dry_model_generator')
2
+
3
+ class DmodelGenerator < DryModelGenerator
4
+
5
+ def initialize(runtime_args, runtime_options = {})
6
+ super
7
+ # Make Rails look for templates within generator "dry_model" path
8
+ @source_root = options[:source] || File.join(spec.path, '..', 'dry_model', 'templates')
9
+ end
10
+
11
+ def usage_message
12
+ File.read(File.join(spec.path, '..', 'dry_model', 'USAGE')) rescue ''
13
+ end
14
+
15
+ end
@@ -0,0 +1,9 @@
1
+ NAME
2
+ dry_model/dmodel - A Rails scaffold generator that generates DRYer, cleaner, and more useful code - for models.
3
+
4
+ DESCRIPTION
5
+ A replacement for the Rails model generator - a part of the dry_generator toolset.
6
+
7
+ EXAMPLE
8
+ ./script/generate dmodel GoldFish name:string about:text _indexes:name --fgirl
9
+ ./script/generate dmodel Frog name:string about:text _indexes:name,name+about --fixtures
@@ -0,0 +1,134 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'dry_generator'))
2
+
3
+ class DryModelGenerator < DryGenerator
4
+
5
+ # Banner: Generator arguments and options.
6
+ BANNER_ARGS = [
7
+ "[_indexes:field,field+field,field,...]"
8
+ ].freeze
9
+ BANNER_OPTIONS = [
10
+ "[--skip-timestamps]",
11
+ "[--skip-migration]"
12
+ ].freeze
13
+
14
+ # Paths.
15
+ MODELS_PATH = File.join('app', 'models').freeze
16
+ MIGRATIONS_PATH = File.join('db', 'migrate').freeze
17
+
18
+ attr_reader :indexes,
19
+ :references
20
+
21
+ def initialize(runtime_args, runtime_options = {})
22
+ @options = DEFAULT_OPTIONS.merge(options)
23
+ super(runtime_args, runtime_options.merge(@options))
24
+
25
+ @attributes ||= []
26
+ args_for_model = []
27
+
28
+ @args.each do |arg|
29
+ arg_entities = arg.split(':')
30
+ if arg =~ /^#{NON_ATTR_ARG_KEY_PREFIX}/
31
+ if arg =~ /^#{NON_ATTR_ARG_KEY_PREFIX}index/
32
+ arg_indexes = arg_entities[1].split(',').compact.uniq
33
+ @indexes = arg_indexes.collect do |index|
34
+ if index =~ /\+/
35
+ index.split('+').collect { |i| i.downcase.to_sym }
36
+ else
37
+ index.downcase.to_sym
38
+ end
39
+ end
40
+ end
41
+ else
42
+ @attributes << Rails::Generator::GeneratedAttribute.new(*arg_entities)
43
+ args_for_model << arg
44
+ end
45
+ end
46
+
47
+ @args = args_for_model
48
+ @references = attributes.select(&:reference?)
49
+ end
50
+
51
+ def manifest
52
+ record do |m|
53
+ # Check for class naming collisions.
54
+ m.class_collisions class_name, "#{class_name}Test"
55
+
56
+ # Model.
57
+ m.directory File.join(MODELS_PATH, class_path)
58
+ m.template File.join('models', 'active_record_model.rb'),
59
+ File.join(MODELS_PATH, class_path, "#{file_name}.rb")
60
+
61
+ # Model Tests.
62
+ unless options[:skip_tests]
63
+ model_tests_path = File.join(TEST_PATHS[test_framework], UNIT_TESTS_PATH[test_framework])
64
+ m.directory File.join(model_tests_path, class_path)
65
+ m.template File.join('models', 'tests', "#{test_framework}", 'unit_test.rb'),
66
+ File.join(model_tests_path, class_path, "#{file_name}_#{TEST_POST_FIX[test_framework]}.rb")
67
+
68
+ # Fixtures/Factories.
69
+ if options[:fixtures]
70
+ fixtures_path = File.join(TEST_PATHS[test_framework], 'fixtures')
71
+ m.directory File.join(fixtures_path, class_path)
72
+ m.template File.join('models', 'fixture_data', 'active_record_fixtures.yml'),
73
+ File.join(fixtures_path, class_path, "#{table_name}.yml")
74
+ end
75
+ if options[:factory_girl]
76
+ factory_girl_path = File.join(TEST_PATHS[test_framework], 'factories')
77
+ m.directory File.join(factory_girl_path, class_path)
78
+ m.template File.join('models', 'fixture_data', 'factory_girl_factories.rb'),
79
+ File.join(factory_girl_path, class_path, "#{plural_name}.rb")
80
+ end
81
+ if options[:machinist]
82
+ machinist_path = File.join(TEST_PATHS[test_framework], 'blueprints')
83
+ m.directory File.join(machinist_path, class_path)
84
+ m.template File.join('models', 'fixture_data', 'machinist_blueprints.rb'),
85
+ File.join(machinist_path, class_path, "#{plural_name}.rb")
86
+ end
87
+ # NOTE: :object_daddy handled in model
88
+ end
89
+
90
+ # Migration.
91
+ unless options[:skip_migration]
92
+ m.migration_template File.join('models', 'active_record_migration.rb'), MIGRATIONS_PATH,
93
+ :assigns => {:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"},
94
+ :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
95
+ end
96
+ end
97
+ end
98
+
99
+ protected
100
+
101
+ def add_options!(opt)
102
+ super(opt)
103
+
104
+ opt.separator ' '
105
+ opt.separator 'Model Options:'
106
+
107
+ opt.on("--skip-timestamps", "Don't add timestamps to the migration file.") do |v|
108
+ options[:skip_timestamps] = v
109
+ end
110
+
111
+ opt.on("--skip-migration", "Skip generation of migration file.") do |v|
112
+ options[:skip_migration] = v
113
+ end
114
+
115
+ opt.on("--skip-tests", "Skip generation of tests.") do |v|
116
+ options[:skip_tests] = v
117
+ end
118
+
119
+ opt.separator ' '
120
+ end
121
+
122
+ def banner_args
123
+ [BANNER_ARGS, super].flatten.join(' ')
124
+ end
125
+
126
+ def banner_options
127
+ [BANNER_OPTIONS, super].flatten.join(' ')
128
+ end
129
+
130
+ def banner
131
+ [super, banner_args, banner_options].join(' ')
132
+ end
133
+
134
+ end
@@ -0,0 +1,17 @@
1
+ class CreateDucks < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :resources, :force => true do |t|
4
+ t.string :name
5
+ t.text :description
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :resources, :name
11
+ add_index :resources, [:name, :description]
12
+ end
13
+
14
+ def self.down
15
+ drop_table :resources
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ class Duck < ActiveRecord::Base
2
+
3
+ belongs_to :owner
4
+
5
+ # object_daddy
6
+ generator_for(:name) { "AString" }
7
+ generator_for(:description) { "SomeText" }
8
+
9
+ end
@@ -0,0 +1,3 @@
1
+ default:
2
+ name: "AString"
3
+ description: "SomeText"
@@ -0,0 +1,4 @@
1
+ Factory.define :duck, :class => Duck do |f|
2
+ f.name "AString"
3
+ f.description "SomeText"
4
+ end
@@ -0,0 +1,8 @@
1
+ Sham.define do
2
+
3
+ end
4
+
5
+ Resource.blueprint do
6
+ name { "AString" }
7
+ description { "SomeText" }
8
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe DuckTest do
4
+ fixtures :ducks
5
+
6
+ it "should be valid" do
7
+ DuckTest.new.should be_valid
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class DuckTest < ActiveRecord::TestCase
4
+
5
+ fixtures :ducks
6
+
7
+ should_have_db_column :name
8
+ should_have_db_column :description
9
+
10
+ context "A test context" do
11
+ setup do
12
+
13
+ end
14
+
15
+ should 'test something' do
16
+ assert true
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class DuckTest < ActiveRecord::TestCase
4
+
5
+ fixtures :ducks
6
+
7
+ setup do
8
+
9
+ end
10
+
11
+ test 'something' do
12
+ assert true
13
+ end
14
+
15
+ end
@@ -0,0 +1,23 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :<%= table_name %> do |t|
4
+ <% attributes.each do |attribute| -%>
5
+ t.<%= attribute.type %> :<%= attribute.name %>
6
+ <% end -%>
7
+
8
+ <% unless options[:skip_timestamps] -%>
9
+ t.timestamps
10
+ <% end -%>
11
+ end
12
+ <% unless indexes.blank? -%>
13
+
14
+ <% indexes.each do |index| -%>
15
+ add_index :<%= table_name %>, <%= index.is_a?(Array) ? "[:#{index.join(', :')}]" : ":#{index}" %>
16
+ <% end -%>
17
+ <% end -%>
18
+ end
19
+
20
+ def self.down
21
+ drop_table :<%= table_name %>
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ class <%= class_name %> < ActiveRecord::Base
2
+
3
+ <% unless references.empty? -%>
4
+ <% references.each do |attribute| -%>
5
+ belongs_to :<%= attribute.name %>
6
+ <% end -%>
7
+
8
+ <% end -%>
9
+ <% if options[:object_daddy] -%>
10
+ <% attributes.each do |attribute| -%>
11
+ generator_for(:<%= attribute.name %>) { <%= attribute.default_for_factory %> }
12
+ <% end -%>
13
+
14
+ <% end -%>
15
+ end