rubigen 1.3.2 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/website/index.txt CHANGED
@@ -4,22 +4,15 @@ h1. Ruby Generator Framework
4
4
 
5
5
  h2. What
6
6
 
7
- A framework to allow Ruby applications to generate file/folder stubs
8
- (like the <code>rails</code> command does for Ruby on Rails, and the 'script/generate'
9
- command within a Rails application during development).
7
+ A framework to allow Ruby applications to generate file/folder stubs (like the <code>rails</code> command does for Ruby on Rails, and the 'script/generate' command within a Rails application during development).
10
8
 
11
9
  The RubyConf 2007 presentation is now "online":http://rubyconf2007.confreaks.com/d3t1p1_rubigen.html together with the theme from the A-Team.
12
10
 
13
11
  h2. Background
14
12
 
15
- RubiGen is originally extracted from Ruby on Rails (specifically the rails_generator
16
- from its railties gem).
13
+ RubiGen is originally extracted from Ruby on Rails (specifically the rails_generator from its railties gem).
17
14
 
18
- The rails_generator was hardcoded with Rails-specific dependencies (<code>RAILS_ROOT</code>),
19
- Rails generators ('app' = Rails application; 'model' = Rails model+tests+migration),
20
- and generally assumed it was the only generator framework within the Ruby world (it was).
21
- So, any RubyGem whose name ended with '_generator' was assumed to be a generator for
22
- a Rails application.
15
+ The rails_generator was hardcoded with Rails-specific dependencies (<code>RAILS_ROOT</code>), Rails generators ('app' = Rails application; 'model' = Rails model+tests+migration), and generally assumed it was the only generator framework within the Ruby world (it was). So, any RubyGem whose name ended with '_generator' was assumed to be a generator for a Rails application.
23
16
 
24
17
  But if you are developing a Merb application, then you may want a different set of generators.
25
18
  If you are developing a RubyGem, then you will want a different set of generators.
@@ -28,8 +21,7 @@ RubiGen exists to give different development environments their own generator fr
28
21
 
29
22
  h2. Installing
30
23
 
31
- RubiGen is only required at development time, and normally isn't required at deployment time
32
- (unless your application uses it to generate files etc for its users).
24
+ RubiGen is only required at development time, and normally isn't required at deployment time (unless your application uses it to generate files etc for its users).
33
25
 
34
26
  On your development machine:
35
27
 
@@ -37,8 +29,7 @@ On your development machine:
37
29
 
38
30
  h2. Usage
39
31
 
40
- RubiGen will be normally integrated into another RubyGem, such as <code>newgem</code> or <code>merb</code> or <code>camping</code>,
41
- rather than be used on its own.
32
+ RubiGen will be normally integrated into another RubyGem, such as <code>newgem</code> or <code>merb</code> or <code>camping</code>, rather than be used on its own.
42
33
 
43
34
  These frameworks might use RubiGen for two reasons:
44
35
 
@@ -121,7 +112,7 @@ require 'rubigen'
121
112
 
122
113
  if %w(-v --version).include? ARGV.first
123
114
  require 'newgem/version'
124
- puts "#{File.basename($0)} #{Newgem::VERSION::STRING}"
115
+ puts "#{File.basename($0)} #{Newgem::VERSION}"
125
116
  exit(0)
126
117
  end
127
118
 
@@ -1,5 +1,5 @@
1
1
  body {
2
- background-color: #F10B00;
2
+ background-color: #b33;
3
3
  font-family: "Georgia", sans-serif;
4
4
  font-size: 16px;
5
5
  line-height: 1.6em;
@@ -96,17 +96,20 @@ pre, code {
96
96
  .number { color: #F99; }
97
97
  .expr { color: #227; }
98
98
 
99
- #version {
99
+ .sidebar {
100
100
  float: right;
101
+ }
102
+
103
+ #version {
104
+ width: 170px;
105
+ padding: 15px 20px 10px 20px;
106
+ margin: 0 auto;
101
107
  text-align: right;
102
108
  font-family: sans-serif;
103
109
  font-weight: normal;
110
+ border: 3px solid #DDD;
104
111
  background-color: #468EFF;
105
112
  color: #EEE;
106
- padding: 15px 20px 10px 20px;
107
- margin: 0 auto;
108
- margin-top: 15px;
109
- border: 3px solid #DDD;
110
113
  }
111
114
 
112
115
  #version .numbers {
@@ -136,3 +139,17 @@ pre, code {
136
139
  cursor: hand;
137
140
  }
138
141
 
142
+ #twitter_search {
143
+ margin: 40px 0 10px 15px;
144
+ border: 3px solid #DDD;
145
+ background-color: #468EFF;
146
+ }
147
+
148
+ #twitter_search h3 {
149
+ margin-bottom: 0px;
150
+ }
151
+
152
+ #twitter_search center b {
153
+ display: none;
154
+ }
155
+
@@ -23,15 +23,35 @@
23
23
  }
24
24
  var versionBox = new curvyCorners(settings, document.getElementById("version"));
25
25
  versionBox.applyCornersToAll();
26
+
27
+ var twitterBox = new curvyCorners(settings, document.getElementById("twitter_search"));
28
+ twitterBox.applyCornersToAll();
26
29
  }
27
30
  </script>
28
31
  </head>
29
32
  <body>
30
33
  <div id="main">
31
34
  <h1><%= title %></h1>
32
- <div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
33
- <p>Get Version</p>
34
- <a href="<%= download %>" class="numbers"><%= version %></a>
35
+ <div class="sidebar">
36
+ <div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
37
+ <p>Get Version</p>
38
+ <a href="<%= download %>" class="numbers"><%= version %></a>
39
+ </div>
40
+
41
+ <div id="twitter_search">
42
+ <h3>Heard on twitter ('rubigen')...</h3>
43
+ <!-- HELP FILE - http://twitterwidget.jazzychad.com/tw/ -->
44
+ <script language = "javascript">
45
+ var jtw_search = 'rubigen';
46
+ var jtw_widget_background = 'd77';
47
+ var jtw_widget_border = '0';
48
+ var jtw_tweet_textcolor = 'fff';
49
+ var jtw_tweet_background = '000';
50
+ var jtw_tweet_border = '0px';
51
+ </script>
52
+ <script src="http://twitterwidget.jazzychad.com/tw/searchwidget.js" type="text/javascript"></script>
53
+ </div>
54
+
35
55
  </div>
36
56
  <%= body %>
37
57
  <p class="coda">
@@ -41,4 +61,4 @@
41
61
  </div>
42
62
  <!-- insert site tracking codes here, like Google Urchin -->
43
63
  </body>
44
- </html>
64
+ </html>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubigen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dr Nic Williams
@@ -10,11 +10,12 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-05-19 00:00:00 +10:00
13
+ date: 2008-10-26 00:00:00 +10:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
18
+ type: :runtime
18
19
  version_requirement:
19
20
  version_requirements: !ruby/object:Gem::Requirement
20
21
  requirements:
@@ -22,6 +23,16 @@ dependencies:
22
23
  - !ruby/object:Gem::Version
23
24
  version: 1.4.4
24
25
  version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: hoe
28
+ type: :development
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.8.0
35
+ version:
25
36
  description: "A framework to allow Ruby applications to generate file/folder stubs (like the rails command does for Ruby on Rails, and the \xE2\x80\x98script/generate\xE2\x80\x99 command within a Rails application during development)."
26
37
  email: drnicwilliams@gmail.com
27
38
  executables:
@@ -74,7 +85,6 @@ files:
74
85
  - lib/rubigen/scripts/update.rb
75
86
  - lib/rubigen/simple_logger.rb
76
87
  - lib/rubigen/spec.rb
77
- - lib/rubigen/version.rb
78
88
  - rubygems_generators/application_generator/USAGE
79
89
  - rubygems_generators/application_generator/application_generator_generator.rb
80
90
  - rubygems_generators/application_generator/templates/bin
@@ -94,14 +104,10 @@ files:
94
104
  - script/destroy
95
105
  - script/generate
96
106
  - script/txt2html
97
- - script/txt2js
98
107
  - setup.rb
99
108
  - tasks/deployment.rake
100
109
  - tasks/environment.rake
101
110
  - tasks/website.rake
102
- - test/examples_from_rails/generator_test_helper.rb
103
- - test/examples_from_rails/test_rails_resource_generator.rb
104
- - test/examples_from_rails/test_rails_scaffold_generator.rb
105
111
  - test/test_application_generator_generator.rb
106
112
  - test/test_component_generator_generator.rb
107
113
  - test/test_generate_builtin_application.rb
@@ -146,13 +152,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
152
  requirements: []
147
153
 
148
154
  rubyforge_project: rubigen
149
- rubygems_version: 1.1.1
155
+ rubygems_version: 1.3.0
150
156
  signing_key:
151
157
  specification_version: 2
152
158
  summary: "A framework to allow Ruby applications to generate file/folder stubs (like the rails command does for Ruby on Rails, and the \xE2\x80\x98script/generate\xE2\x80\x99 command within a Rails application during development)."
153
159
  test_files:
154
- - test/examples_from_rails/test_rails_resource_generator.rb
155
- - test/examples_from_rails/test_rails_scaffold_generator.rb
156
160
  - test/test_application_generator_generator.rb
157
161
  - test/test_component_generator_generator.rb
158
162
  - test/test_generate_builtin_application.rb
@@ -1,9 +0,0 @@
1
- module Rubigen #:nodoc:
2
- module VERSION #:nodoc:
3
- MAJOR = 1
4
- MINOR = 3
5
- TINY = 2
6
-
7
- STRING = [MAJOR, MINOR, TINY].join('.')
8
- end
9
- end
data/script/txt2js DELETED
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'redcloth'
5
- require 'syntax/convertors/html'
6
- require 'erb'
7
- require 'active_support'
8
- require File.dirname(__FILE__) + '/../lib/rubigen/version.rb'
9
-
10
- version = Rubigen::VERSION::STRING
11
- download = 'http://rubyforge.org/projects/rubigen'
12
-
13
- class Fixnum
14
- def ordinal
15
- # teens
16
- return 'th' if (10..19).include?(self % 100)
17
- # others
18
- case self % 10
19
- when 1: return 'st'
20
- when 2: return 'nd'
21
- when 3: return 'rd'
22
- else return 'th'
23
- end
24
- end
25
- end
26
-
27
- class Time
28
- def pretty
29
- return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
30
- end
31
- end
32
-
33
- def convert_syntax(syntax, source)
34
- return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
35
- end
36
-
37
- if ARGV.length >= 1
38
- src, template = ARGV
39
- template ||= File.dirname(__FILE__) + '/../website/template.js'
40
- else
41
- puts("Usage: #{File.split($0).last} source.txt [template.js] > output.html")
42
- exit!
43
- end
44
-
45
- template = ERB.new(File.open(template).read)
46
-
47
- title = nil
48
- body = nil
49
- File.open(src) do |fsrc|
50
- title_text = fsrc.readline
51
- body_text = fsrc.read
52
- title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
53
- body = RedCloth.new(body_text)
54
- end
55
- stat = File.stat(src)
56
- created = stat.ctime
57
- modified = stat.mtime
58
-
59
- $stdout << template.result(binding)
@@ -1,195 +0,0 @@
1
- module GeneratorTestHelper
2
- # Instatiates the Generator
3
- def build_generator(name,params)
4
- RubiGen::Base.instance(name,params)
5
- end
6
-
7
- # Runs the create command (like the command line does)
8
- def run_generator(name,params)
9
- silence_generator do
10
- build_generator(name,params).command(:create).invoke!
11
- end
12
- end
13
-
14
- # Silences the logger temporarily and returns the output as a String
15
- def silence_generator
16
- logger_original=RubiGen::Base.logger
17
- myout=StringIO.new
18
- RubiGen::Base.logger=RubiGen::SimpleLogger.new(myout)
19
- yield if block_given?
20
- RubiGen::Base.logger=logger_original
21
- myout.string
22
- end
23
-
24
- # asserts that the given controller was generated.
25
- # It takes a name or symbol without the <tt>_controller</tt> part and an optional super class.
26
- # The contents of the class source file is passed to a block.
27
- def assert_generated_controller_for(name,parent="ApplicationController")
28
- assert_generated_class "app/controllers/#{name.to_s.underscore}_controller",parent do |body|
29
- yield body if block_given?
30
- end
31
- end
32
-
33
- # asserts that the given model was generated.
34
- # It takes a name or symbol and an optional super class.
35
- # the contents of the class source file is passed to a block.
36
- def assert_generated_model_for(name,parent="ActiveRecord::Base")
37
- assert_generated_class "app/models/#{name.to_s.underscore}",parent do |body|
38
- yield body if block_given?
39
- end
40
- end
41
-
42
- # asserts that the given helper was generated.
43
- # It takes a name or symbol without the <tt>_helper</tt> part
44
- # the contents of the module source file is passed to a block.
45
- def assert_generated_helper_for(name)
46
- assert_generated_module "app/helpers/#{name.to_s.underscore}_helper" do |body|
47
- yield body if block_given?
48
- end
49
- end
50
-
51
- # asserts that the given functional test was generated.
52
- # It takes a name or symbol without the <tt>_controller_test</tt> part and an optional super class.
53
- # the contents of the class source file is passed to a block.
54
- def assert_generated_functional_test_for(name,parent="Test::Unit::TestCase")
55
- assert_generated_class "test/functional/#{name.to_s.underscore}_controller_test",parent do |body|
56
- yield body if block_given?
57
- end
58
- end
59
-
60
- # asserts that the given unit test was generated.
61
- # It takes a name or symbol without the <tt>_test</tt> part and an optional super class.
62
- # the contents of the class source file is passed to a block.
63
- def assert_generated_unit_test_for(name,parent="Test::Unit::TestCase")
64
- assert_generated_class "test/unit/#{name.to_s.underscore}_test",parent do |body|
65
- yield body if block_given?
66
- end
67
- end
68
-
69
- # asserts that the given file was generated.
70
- # the contents of the file is passed to a block.
71
- def assert_generated_file(path)
72
- assert_file_exists(path)
73
- File.open("#{RAILS_ROOT}/#{path}") do |f|
74
- yield f.read if block_given?
75
- end
76
- end
77
-
78
- # asserts that the given file exists
79
- def assert_file_exists(path)
80
- assert File.exists?("#{RAILS_ROOT}/#{path}"),"The file '#{path}' should exist"
81
- end
82
-
83
- # asserts that the given class source file was generated.
84
- # It takes a path without the <tt>.rb</tt> part and an optional super class.
85
- # the contents of the class source file is passed to a block.
86
- def assert_generated_class(path,parent=nil)
87
- path=~/\/?(\d+_)?(\w+)$/
88
- class_name=$2.camelize
89
- assert_generated_file("#{path}.rb") do |body|
90
- assert body=~/class #{class_name}#{parent.nil? ? '':" < #{parent}"}/,"the file '#{path}.rb' should be a class"
91
- yield body if block_given?
92
- end
93
- end
94
-
95
- # asserts that the given module source file was generated.
96
- # It takes a path without the <tt>.rb</tt> part.
97
- # the contents of the class source file is passed to a block.
98
- def assert_generated_module(path)
99
- path=~/\/?(\w+)$/
100
- module_name=$1.camelize
101
- assert_generated_file("#{path}.rb") do |body|
102
- assert body=~/module #{module_name}/,"the file '#{path}.rb' should be a module"
103
- yield body if block_given?
104
- end
105
- end
106
-
107
- # asserts that the given css stylesheet file was generated.
108
- # It takes a path without the <tt>.css</tt> part.
109
- # the contents of the stylesheet source file is passed to a block.
110
- def assert_generated_stylesheet(path)
111
- assert_generated_file("public/stylesheets/#{path}.css") do |body|
112
- yield body if block_given?
113
- end
114
- end
115
-
116
- # asserts that the given yaml file was generated.
117
- # It takes a path without the <tt>.yml</tt> part.
118
- # the parsed yaml tree is passed to a block.
119
- def assert_generated_yaml(path)
120
- assert_generated_file("#{path}.yml") do |body|
121
- assert yaml=YAML.load(body)
122
- yield yaml if block_given?
123
- end
124
- end
125
-
126
- # asserts that the given fixtures yaml file was generated.
127
- # It takes a fixture name without the <tt>.yml</tt> part.
128
- # the parsed yaml tree is passed to a block.
129
- def assert_generated_fixtures_for(name)
130
- assert_generated_yaml "test/fixtures/#{name.to_s.underscore}" do |yaml|
131
- assert_generated_timestamps(yaml)
132
- yield yaml if block_given?
133
- end
134
- end
135
-
136
- # asserts that the given views were generated.
137
- # It takes a controller name and a list of views (including extensions).
138
- # The body of each view is passed to a block
139
- def assert_generated_views_for(name,*actions)
140
- actions.each do |action|
141
- assert_generated_file("app/views/#{name.to_s.underscore}/#{action.to_s}") do |body|
142
- yield body if block_given?
143
- end
144
- end
145
- end
146
-
147
- # asserts that the given migration file was generated.
148
- # It takes the name of the migration as a parameter.
149
- # The migration body is passed to a block.
150
- def assert_generated_migration(name,parent="ActiveRecord::Migration")
151
- assert_generated_class "db/migrate/001_#{name.to_s.underscore}",parent do |body|
152
- assert body=~/timestamps/, "should have timestamps defined"
153
- yield body if block_given?
154
- end
155
- end
156
-
157
- # Asserts that the given migration file was not generated.
158
- # It takes the name of the migration as a parameter.
159
- def assert_skipped_migration(name)
160
- migration_file = "#{RAILS_ROOT}/db/migrate/001_#{name.to_s.underscore}.rb"
161
- assert !File.exists?(migration_file), "should not create migration #{migration_file}"
162
- end
163
-
164
- # asserts that the given resource was added to the routes.
165
- def assert_added_route_for(name)
166
- assert_generated_file("config/routes.rb") do |body|
167
- assert body=~/map.resources :#{name.to_s.underscore}/,"should add route for :#{name.to_s.underscore}"
168
- end
169
- end
170
-
171
- # asserts that the given methods are defined in the body.
172
- # This does assume standard rails code conventions with regards to the source code.
173
- # The body of each individual method is passed to a block.
174
- def assert_has_method(body,*methods)
175
- methods.each do |name|
176
- assert body=~/^ def #{name.to_s}\n((\n| .*\n)*) end/,"should have method #{name.to_s}"
177
- yield( name, $1 ) if block_given?
178
- end
179
- end
180
-
181
- # asserts that the given column is defined in the migration
182
- def assert_generated_column(body,name,type)
183
- assert body=~/t\.#{type.to_s} :#{name.to_s}/, "should have column #{name.to_s} defined"
184
- end
185
-
186
- private
187
- # asserts that the default timestamps are created in the fixture
188
- def assert_generated_timestamps(yaml)
189
- yaml.values.each do |v|
190
- ["created_at", "updated_at"].each do |field|
191
- assert v.keys.include?(field), "should have #{field} field by default"
192
- end
193
- end
194
- end
195
- end
@@ -1,106 +0,0 @@
1
- require 'test/unit'
2
-
3
- # Optionally load RubyGems
4
- begin
5
- require 'rubygems'
6
- rescue LoadError
7
- end
8
-
9
- # Mock out what we need from AR::Base
10
- module ActiveRecord
11
- class Base
12
- class << self
13
- attr_accessor :pluralize_table_names
14
- end
15
- self.pluralize_table_names = true
16
- end
17
-
18
- module ConnectionAdapters
19
- class Column
20
- attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
21
- def initialize(name, default, sql_type=nil)
22
- @namename
23
- @default=default
24
- @type=@sql_type=sql_type
25
- end
26
-
27
- def human_name
28
- @name.humanize
29
- end
30
- end
31
- end
32
- end
33
-
34
- # Mock up necessities from ActionView
35
- module ActionView
36
- module Helpers
37
- module ActionRecordHelper; end
38
- class InstanceTag; end
39
- end
40
- end
41
-
42
- # Set RAILS_ROOT appropriately fixture generation
43
- tmp_dir="#{File.dirname(__FILE__)}/../fixtures/tmp"
44
- if defined?(RAILS_ROOT)
45
- RAILS_ROOT.replace(tmp_dir)
46
- else
47
- RAILS_ROOT=tmp_dir
48
- end
49
- Dir.mkdir(RAILS_ROOT) unless File.exists?(RAILS_ROOT)
50
-
51
- $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
52
- require 'rails_generator'
53
- require "#{File.dirname(__FILE__)}/generator_test_helper"
54
-
55
- class RailsResourceGeneratorTest < Test::Unit::TestCase
56
- include GeneratorTestHelper
57
-
58
- def setup
59
- ActiveRecord::Base.pluralize_table_names = true
60
- Dir.mkdir("#{RAILS_ROOT}/app") unless File.exists?("#{RAILS_ROOT}/app")
61
- Dir.mkdir("#{RAILS_ROOT}/app/views") unless File.exists?("#{RAILS_ROOT}/app/views")
62
- Dir.mkdir("#{RAILS_ROOT}/app/views/layouts") unless File.exists?("#{RAILS_ROOT}/app/views/layouts")
63
- Dir.mkdir("#{RAILS_ROOT}/config") unless File.exists?("#{RAILS_ROOT}/config")
64
- Dir.mkdir("#{RAILS_ROOT}/db") unless File.exists?("#{RAILS_ROOT}/db")
65
- Dir.mkdir("#{RAILS_ROOT}/test") unless File.exists?("#{RAILS_ROOT}/test")
66
- Dir.mkdir("#{RAILS_ROOT}/test/fixtures") unless File.exists?("#{RAILS_ROOT}/test/fixtures")
67
- Dir.mkdir("#{RAILS_ROOT}/public") unless File.exists?("#{RAILS_ROOT}/public")
68
- Dir.mkdir("#{RAILS_ROOT}/public/stylesheets") unless File.exists?("#{RAILS_ROOT}/public/stylesheets")
69
- File.open("#{RAILS_ROOT}/config/routes.rb", 'w') do |f|
70
- f<<"ActionController::Routing::Routes.draw do |map|\n\nend\n"
71
- end
72
- end
73
-
74
- def teardown
75
- FileUtils.rm_rf "#{RAILS_ROOT}/app"
76
- FileUtils.rm_rf "#{RAILS_ROOT}/test"
77
- FileUtils.rm_rf "#{RAILS_ROOT}/config"
78
- FileUtils.rm_rf "#{RAILS_ROOT}/db"
79
- FileUtils.rm_rf "#{RAILS_ROOT}/public"
80
- end
81
-
82
- def test_resource_generates_resources
83
- run_generator('scaffold', %w(Product))
84
-
85
- assert_generated_controller_for :products
86
- assert_generated_model_for :product
87
- assert_generated_fixtures_for :products
88
- assert_generated_functional_test_for :products
89
- assert_generated_helper_for :products
90
- assert_generated_migration :create_products
91
- assert_added_route_for :products
92
- end
93
-
94
- def test_resource_skip_migration_skips_migration
95
- run_generator('resource', %w(Product --skip-migration))
96
-
97
- assert_generated_controller_for :products
98
- assert_generated_model_for :product
99
- assert_generated_fixtures_for :products
100
- assert_generated_functional_test_for :products
101
- assert_generated_helper_for :products
102
- assert_skipped_migration :create_products
103
- assert_added_route_for :products
104
- end
105
-
106
- end