cup 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cup (0.0.6)
4
+ cup (0.0.7)
5
5
  coffee-script
6
6
  rack (= 1.3.3)
7
7
  rake
@@ -2,6 +2,8 @@
2
2
 
3
3
  INSERT A PICTURE OF A CUP
4
4
 
5
+ `npm install uglify-js`: UglifyJS must be installed
6
+
5
7
  Command lines tools and a web application to help in developing javascript libraries and applications independently of anything else.
6
8
 
7
9
 
@@ -65,8 +67,6 @@ Sample Cupfile (ruby) with comments:
65
67
  'so/can/glob-like/patterns/**/*.js'] # happily, patterns and arrays can be used too.
66
68
  end
67
69
 
68
- uglifier_options :mangle => true # uglifier defaults can be overriden
69
-
70
70
  before_build do
71
71
  # whatever you want
72
72
  end
@@ -103,7 +103,7 @@ Visual specs help to facilitate the visual verifcation of behaviour which maybe
103
103
 
104
104
  To create a visual spec, add a slim template in the `spec/visual` directory. Any directory structure within `spec/visual` may be used to organise visual specs as you see fit. An index of available visual specs is available in the browser app.
105
105
 
106
- Each slim template under `spec/visual` is a partial and will be injected into the body of a page with the src, lib and vendor javascript loaded in the order specified by the Cupfile.
106
+ Each slim template under `spec/visual` is a partial and will be injected into the body of a page with the src, lib and vendor javascript loaded in the order specified by the Cupfile.
107
107
 
108
108
 
109
109
  Note: No style sheets are automatically loaded for visual specs.
@@ -60,16 +60,16 @@ module Cup
60
60
  end
61
61
 
62
62
  def concatenate!(options = {})
63
- process(options, :concatenated) do |input_file_content|
64
- input_file_content
63
+ process(options, :concatenated) do |input_file|
64
+ File.read(input_file)
65
65
  end
66
66
  end
67
67
 
68
68
  def minify!(options = {})
69
- uglifier_options = uglifier_defaults.merge directory.cupfile.uglifier_options
70
-
71
- process(options, :minified) do |input_file_content|
72
- Uglifier.compile input_file_content, uglifier_options
69
+ process(options, :minified) do |input_file|
70
+ result = `uglifyjs "#{input_file}"`
71
+ fail "FAILED: uglifyjs '#{input_file}'" unless $?.exitstatus == 0
72
+ result
73
73
  end
74
74
  end
75
75
 
@@ -85,21 +85,22 @@ module Cup
85
85
 
86
86
  build_directory = @build_directory.to_s
87
87
  mkdir build_directory unless Dir.exists?(build_directory)
88
- file = File.open(output_file, 'w')
89
88
 
90
- file.write(licence_header)
89
+ buffer = [licence_header, ';']
91
90
 
92
91
  input_files.each do |input_file|
93
- file.write(';')
94
- file.write(yield File.read(input_file))
95
- file.write(';')
92
+ buffer << (yield input_file)
93
+ buffer << ';'
96
94
  end
97
95
 
98
- cli.say("#{relative_output_file}: #{file.pos} bytes written.", :green)
96
+ buffer = buffer.join
99
97
 
100
- file.close
98
+ File.open(output_file, 'w') do |io|
99
+ io.write buffer
100
+ cli.say("#{relative_output_file}: #{io.pos} bytes written.", :green)
101
+ end
101
102
 
102
- File.read(output_file)
103
+ buffer
103
104
  end
104
105
  def cupfile
105
106
  directory.cupfile
@@ -114,6 +115,9 @@ module Cup
114
115
  def input_files
115
116
  directory.javascripts :build_input
116
117
  end
118
+ def uglifier_options
119
+ uglifier_defaults.merge directory.cupfile.uglifier_options
120
+ end
117
121
  def uglifier_defaults
118
122
  {
119
123
  :mangle => true, # Mangle variables names
@@ -3,7 +3,7 @@ module Cup
3
3
  class CupfileError < RuntimeError; end
4
4
 
5
5
  attr_accessor :path
6
- attr_reader :path, :validation_errors, :name, :version, :licence, :before_build, :after_build, :uglifier_options
6
+ attr_reader :path, :validation_errors, :name, :version, :licence, :before_build, :after_build
7
7
 
8
8
  def initialize path
9
9
 
@@ -85,7 +85,7 @@ module Cup
85
85
 
86
86
  ## DSL members
87
87
  ## setters
88
- %W{version name licence uglifier_options}.each do |m|
88
+ %W{version name licence}.each do |m|
89
89
  define_method m do |value|
90
90
  @cupfile.instance_variable_set "@#{m}", value
91
91
  end
@@ -37,7 +37,7 @@ module Cup
37
37
  set :public_folder, false #Cup::Directory.current.path.to_s
38
38
 
39
39
  def build
40
- @build_result = Cup.build
40
+ @build_result ||= Cup.build
41
41
  end
42
42
 
43
43
  def view_scope(javascripts_scheme=:debug)
@@ -46,7 +46,7 @@ module Cup
46
46
 
47
47
  def view (template, options={})
48
48
  build
49
-
49
+
50
50
  options = {
51
51
  :scope => view_scope(options.delete(:javascripts_scheme) || :debug),
52
52
  :layout => true
@@ -106,8 +106,8 @@ module Cup
106
106
  end
107
107
 
108
108
  get '/empty' do
109
- redirect '/' if view_scope.build_status == :failed
110
109
  view '', :layout => :blank
110
+ redirect '/' if view_scope.build_status == :failed
111
111
  end
112
112
 
113
113
  get '/spec' do
@@ -127,6 +127,8 @@ module Cup
127
127
  end
128
128
 
129
129
  get '/spec/visual/*' do |visual|
130
+ build
131
+
130
132
  visual = visuals[visual]
131
133
 
132
134
  pass if visual.nil? or not File.exist?(visual.full_path)
@@ -1,3 +1,3 @@
1
1
  module Cup
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
@@ -1,164 +1,145 @@
1
- require 'spec_helper'
2
-
3
- describe Cup::Builder do
4
-
5
- let(:directory) {Cup::Directory.current}
6
- let(:builder) {Cup::Builder.new(directory)}
7
- let(:options){Hash.new}
8
-
9
- describe '#build' do
10
-
11
- def build
12
- builder.build options
13
- end
14
-
15
- share_examples_for :building do
16
- it 'should call the before_build hook before building' do
17
- directory.cupfile.before_build.should_receive(:call)
18
- build
19
- end
20
-
21
- it 'should call the after_build after the build' do
22
- directory.cupfile.after_build.should_receive(:call)
23
- build
24
- end
25
-
26
- it 'should call the concatentate_variant' do
27
- builder.should_receive(concatentate_variant)
28
- build
29
- end
30
-
31
- it 'should call the minify_variant' do
32
- builder.should_receive(minify_variant)
33
- build
34
- end
35
-
36
- it 'should return a Hash with the results of both minification and concatenation' do
37
- result = build
38
- result[:concatenated].should be_instance_of Hash
39
- result[:minified].should be_instance_of Hash
40
- end
41
- end
42
-
43
- context 'when suppressing errors' do
44
- def build
45
- builder.build options
46
- end
47
- let(:concatentate_variant){:concatenate}
48
- let(:minify_variant){:minify}
49
- end
50
-
51
- context 'when not suppressing errors' do
52
- def build
53
- builder.build! options
54
- end
55
- let(:concatentate_variant){:concatenate!}
56
- let(:minify_variant){:minify!}
57
- end
58
- end
1
+ require 'uglifier'
2
+ require 'cup/noop_shell'
59
3
 
60
- share_examples_for 'javascript processing' do
4
+ module Cup
5
+ class Builder
6
+ include FileUtils
61
7
 
62
- it 'should create and write an output file by default' do
63
- process_scripts!
64
- File.should exist(output_file)
65
- end
66
-
67
- context 'when a licence file is specified' do
8
+ attr_reader :directory
68
9
 
69
- let(:licence){"\n\nLICENSE\nFILE\nCONTENT\n\n\n"}
70
- let(:licence_comment) {"/*\n" + licence + "\n*/"}
10
+ def initialize directory
11
+ @directory = directory
71
12
 
72
- before :each do
73
- cupfile = directory.cupfile
74
- cupfile.stub(:licence).and_return('licence.txt')
75
- File.should_receive(:read).with(/.*licence\.txt$/).and_return(licence)
13
+ @build_directory = @directory.path + 'build'
14
+ if File.exists? @build_directory
15
+ if File.file? @build_directory
16
+ raise "Cannot build, build directory is a file"
17
+ end
18
+ else
19
+ Dir.mkdir @build_directory
76
20
  end
77
21
 
78
- it 'should prepend the licence unaltered to the output' do
79
- process_scripts!
80
- File.read(output_file).start_with?(licence_comment).should be_true
81
- end
22
+ uglifier_options = uglifier_defaults.merge directory.cupfile.uglifier_options
23
+ @compiler = Uglifier.new(uglifier_options)
82
24
  end
83
25
 
84
- context 'when not suppressing exceptions' do
26
+ def build *params
85
27
 
86
- it 'should throw an exception if something goes wrong' do
87
- File.stub(:read).and_raise
28
+ cupfile.before_build.call
88
29
 
89
- expect {
90
- process_scripts!
91
- }.to raise_error
30
+ concatenated = concatenate *params
31
+ minified = minify *params
92
32
 
93
- end
33
+ cupfile.after_build.call
94
34
 
95
- it 'should return the output' do
96
- process_scripts!.should_not be_nil
97
- process_scripts!.length.should_not == 0
98
- end
35
+ {
36
+ :concatenated => concatenated,
37
+ :minified => minified
38
+ }
99
39
  end
100
40
 
101
- context 'when supressing exceptions' do
102
-
103
- context 'and there are errors' do
41
+ def build! *params
42
+ cupfile.before_build.call
43
+ concatenated = concatenate! *params
44
+ minified = minify! *params
45
+ cupfile.after_build.call
46
+ {
47
+ :concatenated => concatenated,
48
+ :minified => minified
49
+ }
50
+ end
104
51
 
105
- before :each do
106
- builder.stub(:process).and_raise 'and_raise ERROR'
107
- end
52
+ def concatenate *params
53
+ {:status => :ok, :output => (concatenate! *params)}
54
+ rescue Exception => e
55
+ {:status => :failed, :exception => e}
56
+ end
108
57
 
109
- it 'should return a Hash with failed status and an exception message' do
110
- process_scripts[:status].should == :failed
111
- process_scripts[:exception].should_not be_nil
112
- end
113
- end
58
+ def minify *params
59
+ {:status => :ok, :output => (minify! *params)}
60
+ rescue Exception => e
61
+ {:status => :failed, :exception => e}
62
+ end
114
63
 
115
- context 'and there are no errors' do
116
- it 'should return a Hash with ok status output and no exception message' do
117
- process_scripts[:status].should == :ok
118
- process_scripts[:exception].should be_nil
119
- process_scripts[:output].should_not be_nil
120
- end
64
+ def concatenate!(options = {})
65
+ process(options, :concatenated) do |input_file_content|
66
+ input_file_content
121
67
  end
122
68
  end
123
69
 
124
- context 'when a cli is specified' do
125
- it 'should report to the cli' do
126
- cli = stub
127
- options[:cli] = cli
128
- cli.should_receive(:say)
129
- process_scripts!
70
+ def minify!(options = {})
71
+ process(options, :minified) do |input_file_content|
72
+ @compiler.compile input_file_content
130
73
  end
131
74
  end
132
- end
133
75
 
134
- describe 'concatenating' do
76
+ private
135
77
 
136
- def process_scripts!
137
- builder.concatenate!(options)
138
- end
78
+ def process(options, output_file)
139
79
 
140
- def process_scripts
141
- builder.concatenate(options)
142
- end
80
+ relative_output_file = directory.send output_file, :relative => true
81
+ output_file = directory.send output_file
143
82
 
144
- let(:output_file){directory.concatenated}
83
+ options = default_options.merge options
84
+ cli = options[:cli]
145
85
 
146
- it_behaves_like 'javascript processing'
147
-
148
- end
86
+ build_directory = @build_directory.to_s
87
+ mkdir build_directory unless Dir.exists?(build_directory)
149
88
 
150
- describe 'minifying' do
89
+ buffer = StringIO.new
151
90
 
152
- def process_scripts!
153
- builder.minify!(options)
154
- end
91
+ input_files.each do |input_file|
92
+ buffer.write(';')
93
+ buffer.write(File.read(input_file))
94
+ buffer.write(';')
95
+ end
155
96
 
156
- def process_scripts
157
- builder.minify(options)
158
- end
97
+ buffer.rewind
98
+ processed = yield buffer.read
159
99
 
160
- let(:output_file){directory.minified}
100
+ file = File.open(output_file, 'w') do |io|
101
+ io.puts licence_header
102
+ io.puts ';'
103
+ io.write processed
104
+ io.puts ';'
105
+ cli.say("#{relative_output_file}: #{io.pos} bytes written.", :green)
106
+ end
161
107
 
162
- it_behaves_like 'javascript processing'
108
+ processed
109
+ end
110
+ def cupfile
111
+ directory.cupfile
112
+ end
113
+ def default_options
114
+ { :cli => NoopShell }
115
+ end
116
+ def licence_header
117
+ licence = File.read(directory.cupfile.licence) rescue nil
118
+ licence.nil? ? '' : "/*\n#{licence}\n*/"
119
+ end
120
+ def input_files
121
+ directory.javascripts :build_input
122
+ end
123
+ def uglifier_defaults
124
+ {
125
+ :mangle => true, # Mangle variables names
126
+ :toplevel => false, # Mangle top-level variable names
127
+ :except => [], # Variable names to be excluded from mangling
128
+ :max_line_length => 32 * 1024, # Maximum line length
129
+ :squeeze => true, # Squeeze code resulting in smaller, but less-readable code
130
+ :seqs => true, # Reduce consecutive statements in blocks into single statement
131
+ :dead_code => true, # Remove dead code (e.g. after return)
132
+ :unsafe => false, # Optimizations known to be unsafe in some situations
133
+ :copyright => true, # Show copyright message
134
+ :beautify => false, # Output indented code
135
+ :beautify_options => {
136
+ :indent_level => 2,
137
+ :indent_start => 0,
138
+ :quote_keys => false,
139
+ :space_colon => 0,
140
+ :ascii_only => false
141
+ }
142
+ }
143
+ end
163
144
  end
164
- end
145
+ end
@@ -191,17 +191,6 @@ describe Cup::Cupfile do
191
191
  cupfile.after_build.should equal proc
192
192
  end
193
193
 
194
- it 'should allow uglifier options to be specified' do
195
-
196
- uglifier_opts = Hash.new
197
-
198
- Cup::Cupfile::DSL.interpret cupfile do
199
- uglifier_options uglifier_opts
200
- end
201
-
202
- cupfile.uglifier_options.should equal uglifier_opts
203
- end
204
-
205
194
  describe Cup::Cupfile::DSL do
206
195
  describe Cup::Cupfile::DSL::JavascriptsDSL do
207
196
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-17 00:00:00.000000000Z
12
+ date: 2011-10-21 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &2151939960 !ruby/object:Gem::Requirement
16
+ requirement: &2158458560 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2151939960
24
+ version_requirements: *2158458560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &2151938000 !ruby/object:Gem::Requirement
27
+ requirement: &2158456920 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2151938000
35
+ version_requirements: *2158456920
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: therubyracer
38
- requirement: &2151932160 !ruby/object:Gem::Requirement
38
+ requirement: &2158453540 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2151932160
46
+ version_requirements: *2158453540
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: uglifier
49
- requirement: &2151929340 !ruby/object:Gem::Requirement
49
+ requirement: &2158453100 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2151929340
57
+ version_requirements: *2158453100
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sinatra
60
- requirement: &2151925780 !ruby/object:Gem::Requirement
60
+ requirement: &2158452540 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *2151925780
68
+ version_requirements: *2158452540
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: slim
71
- requirement: &2151922360 !ruby/object:Gem::Requirement
71
+ requirement: &2158451260 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *2151922360
79
+ version_requirements: *2158451260
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: sass
82
- requirement: &2151906040 !ruby/object:Gem::Requirement
82
+ requirement: &2158450240 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *2151906040
90
+ version_requirements: *2158450240
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: coffee-script
93
- requirement: &2151885320 !ruby/object:Gem::Requirement
93
+ requirement: &2158449540 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *2151885320
101
+ version_requirements: *2158449540
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: yard
104
- requirement: &2151879660 !ruby/object:Gem::Requirement
104
+ requirement: &2158449000 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :runtime
111
111
  prerelease: false
112
- version_requirements: *2151879660
112
+ version_requirements: *2158449000
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rack
115
- requirement: &2151864360 !ruby/object:Gem::Requirement
115
+ requirement: &2158448460 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - =
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: 1.3.3
121
121
  type: :runtime
122
122
  prerelease: false
123
- version_requirements: *2151864360
123
+ version_requirements: *2158448460
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: ruby-debug19
126
- requirement: &2151859040 !ruby/object:Gem::Requirement
126
+ requirement: &2158448040 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *2151859040
134
+ version_requirements: *2158448040
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: rspec
137
- requirement: &2151856060 !ruby/object:Gem::Requirement
137
+ requirement: &2158447540 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ! '>='
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: '0'
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *2151856060
145
+ version_requirements: *2158447540
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: shoulda
148
- requirement: &2151853820 !ruby/object:Gem::Requirement
148
+ requirement: &2158447040 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ! '>='
@@ -153,10 +153,10 @@ dependencies:
153
153
  version: '0'
154
154
  type: :development
155
155
  prerelease: false
156
- version_requirements: *2151853820
156
+ version_requirements: *2158447040
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: statemachine
159
- requirement: &2151850200 !ruby/object:Gem::Requirement
159
+ requirement: &2158437180 !ruby/object:Gem::Requirement
160
160
  none: false
161
161
  requirements:
162
162
  - - ! '>='
@@ -164,10 +164,10 @@ dependencies:
164
164
  version: '0'
165
165
  type: :development
166
166
  prerelease: false
167
- version_requirements: *2151850200
167
+ version_requirements: *2158437180
168
168
  - !ruby/object:Gem::Dependency
169
169
  name: rack-test
170
- requirement: &2151846300 !ruby/object:Gem::Requirement
170
+ requirement: &2158436500 !ruby/object:Gem::Requirement
171
171
  none: false
172
172
  requirements:
173
173
  - - ! '>='
@@ -175,10 +175,10 @@ dependencies:
175
175
  version: '0'
176
176
  type: :development
177
177
  prerelease: false
178
- version_requirements: *2151846300
178
+ version_requirements: *2158436500
179
179
  - !ruby/object:Gem::Dependency
180
180
  name: thin
181
- requirement: &2151841700 !ruby/object:Gem::Requirement
181
+ requirement: &2158435640 !ruby/object:Gem::Requirement
182
182
  none: false
183
183
  requirements:
184
184
  - - ! '>='
@@ -186,10 +186,10 @@ dependencies:
186
186
  version: '0'
187
187
  type: :development
188
188
  prerelease: false
189
- version_requirements: *2151841700
189
+ version_requirements: *2158435640
190
190
  - !ruby/object:Gem::Dependency
191
191
  name: sinatra-reloader
192
- requirement: &2151836120 !ruby/object:Gem::Requirement
192
+ requirement: &2158433620 !ruby/object:Gem::Requirement
193
193
  none: false
194
194
  requirements:
195
195
  - - ! '>='
@@ -197,7 +197,7 @@ dependencies:
197
197
  version: '0'
198
198
  type: :development
199
199
  prerelease: false
200
- version_requirements: *2151836120
200
+ version_requirements: *2158433620
201
201
  description:
202
202
  email:
203
203
  - sjltaylor@gmail.com
@@ -286,3 +286,4 @@ test_files:
286
286
  - spec/support/javascripts_matchers.rb
287
287
  - spec/support/macros.rb
288
288
  - spec/support/stub_helpers.rb
289
+ has_rdoc: