yard 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

Files changed (93) hide show
  1. data/ChangeLog +356 -0
  2. data/README.md +27 -5
  3. data/docs/GettingStarted.md +45 -6
  4. data/docs/Tags.md +16 -5
  5. data/docs/WhatsNew.md +60 -2
  6. data/lib/yard.rb +16 -37
  7. data/lib/yard/autoload.rb +5 -0
  8. data/lib/yard/cli/command.rb +18 -6
  9. data/lib/yard/cli/command_parser.rb +1 -0
  10. data/lib/yard/cli/config.rb +113 -0
  11. data/lib/yard/cli/gems.rb +16 -7
  12. data/lib/yard/cli/server.rb +30 -8
  13. data/lib/yard/cli/stats.rb +1 -1
  14. data/lib/yard/cli/yardoc.rb +16 -1
  15. data/lib/yard/code_objects/base.rb +7 -2
  16. data/lib/yard/code_objects/class_object.rb +1 -0
  17. data/lib/yard/code_objects/method_object.rb +1 -0
  18. data/lib/yard/code_objects/proxy.rb +8 -2
  19. data/lib/yard/config.rb +225 -0
  20. data/lib/yard/handlers/base.rb +29 -2
  21. data/lib/yard/handlers/processor.rb +1 -1
  22. data/lib/yard/handlers/ruby/class_handler.rb +6 -1
  23. data/lib/yard/handlers/ruby/constant_handler.rb +13 -15
  24. data/lib/yard/handlers/ruby/exception_handler.rb +1 -1
  25. data/lib/yard/handlers/ruby/extend_handler.rb +3 -0
  26. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +1 -0
  27. data/lib/yard/handlers/ruby/legacy/class_handler.rb +7 -1
  28. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +8 -10
  29. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -1
  30. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +3 -0
  31. data/lib/yard/handlers/ruby/legacy/method_handler.rb +1 -0
  32. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +13 -2
  33. data/lib/yard/handlers/ruby/method_handler.rb +1 -0
  34. data/lib/yard/handlers/ruby/mixin_handler.rb +14 -4
  35. data/lib/yard/handlers/ruby/struct_handler_methods.rb +10 -1
  36. data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
  37. data/lib/yard/parser/c_parser.rb +26 -11
  38. data/lib/yard/parser/ruby/legacy/statement_list.rb +26 -9
  39. data/lib/yard/parser/source_parser.rb +5 -2
  40. data/lib/yard/serializers/yardoc_serializer.rb +2 -2
  41. data/lib/yard/server.rb +11 -0
  42. data/lib/yard/server/commands/frames_command.rb +1 -1
  43. data/lib/yard/server/commands/library_command.rb +22 -13
  44. data/lib/yard/server/commands/library_index_command.rb +1 -0
  45. data/lib/yard/server/commands/search_command.rb +2 -0
  46. data/lib/yard/server/commands/static_file_command.rb +6 -1
  47. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +3 -3
  48. data/lib/yard/templates/helpers/html_helper.rb +1 -1
  49. data/lib/yard/templates/helpers/markup_helper.rb +13 -12
  50. data/lib/yard/verifier.rb +3 -1
  51. data/spec/cli/config_spec.rb +72 -0
  52. data/spec/cli/gems_spec.rb +81 -0
  53. data/spec/cli/server_spec.rb +35 -5
  54. data/spec/cli/stats_spec.rb +15 -0
  55. data/spec/cli/yardoc_spec.rb +39 -1
  56. data/spec/code_objects/base_spec.rb +2 -0
  57. data/spec/code_objects/method_object_spec.rb +5 -0
  58. data/spec/code_objects/proxy_spec.rb +20 -5
  59. data/spec/config_spec.rb +165 -0
  60. data/spec/handlers/alias_handler_spec.rb +7 -0
  61. data/spec/handlers/base_spec.rb +64 -0
  62. data/spec/handlers/class_condition_handler_spec.rb +13 -8
  63. data/spec/handlers/class_handler_spec.rb +54 -46
  64. data/spec/handlers/constant_handler_spec.rb +13 -0
  65. data/spec/handlers/examples/alias_handler_001.rb.txt +2 -0
  66. data/spec/handlers/examples/class_handler_001.rb.txt +12 -1
  67. data/spec/handlers/examples/constant_handler_001.rb.txt +6 -0
  68. data/spec/handlers/examples/exception_handler_001.rb.txt +8 -0
  69. data/spec/handlers/examples/method_handler_001.rb.txt +6 -0
  70. data/spec/handlers/examples/visibility_handler_001.rb.txt +3 -0
  71. data/spec/handlers/exception_handler_spec.rb +5 -0
  72. data/spec/handlers/extend_handler_spec.rb +4 -0
  73. data/spec/handlers/method_handler_spec.rb +5 -0
  74. data/spec/handlers/mixin_handler_spec.rb +10 -0
  75. data/spec/handlers/visibility_handler_spec.rb +4 -0
  76. data/spec/parser/base_spec.rb +1 -1
  77. data/spec/parser/c_parser_spec.rb +39 -1
  78. data/spec/parser/examples/override.c.txt +424 -0
  79. data/spec/parser/ruby/legacy/statement_list_spec.rb +11 -0
  80. data/spec/parser/source_parser_spec.rb +33 -1
  81. data/spec/server/commands/static_file_command_spec.rb +20 -3
  82. data/spec/server_spec.rb +10 -0
  83. data/spec/templates/examples/method001.html +33 -3
  84. data/spec/templates/examples/method001.txt +8 -1
  85. data/spec/templates/helpers/markup_helper_spec.rb +21 -26
  86. data/spec/templates/method_spec.rb +3 -1
  87. data/spec/verifier_spec.rb +5 -0
  88. data/templates/default/fulldoc/html/css/style.css +4 -1
  89. data/templates/default/fulldoc/html/js/app.js +1 -1
  90. data/templates/default/tags/html/option.erb +1 -3
  91. data/templates/default/tags/setup.rb +18 -15
  92. metadata +11 -4
  93. data/spec/yard_spec.rb +0 -55
@@ -1,5 +1,8 @@
1
1
  require 'stringio'
2
- require 'continuation' unless RUBY18
2
+
3
+ begin
4
+ require 'continuation'
5
+ rescue LoadError; end
3
6
 
4
7
  module YARD
5
8
  module Parser
@@ -236,7 +239,7 @@ module YARD
236
239
  # @since 0.5.3
237
240
  def convert_encoding(content)
238
241
  return content if RUBY18
239
- if content =~ /\A\s*#.*coding[:=]\s*(\S+)\s*$/
242
+ if content =~ /\A(?:\s*#*!.*\r?\n)?\s*#+.*coding\s*[:=]{1,2}\s*(\S+)/i
240
243
  content.force_encoding($1)
241
244
  else
242
245
  content
@@ -16,7 +16,7 @@ module YARD
16
16
 
17
17
  def method_missing(meth, *args, &block)
18
18
  return true if meth == :respond_to? && args.first == :_dump
19
- return Registry.at(@path).send(meth, *args, &block) if @transient
19
+ @object = nil if @transient
20
20
  @object ||= Registry.at(@path)
21
21
  @object.send(meth, *args, &block)
22
22
  rescue NoMethodError => e
@@ -84,7 +84,7 @@ module YARD
84
84
  def internal_dump(object, first_object = false)
85
85
  if !first_object && object.is_a?(CodeObjects::Base) &&
86
86
  !(Tags::OverloadTag === object)
87
- return StubProxy.new(object.path, true)
87
+ return StubProxy.new(object.path)
88
88
  end
89
89
 
90
90
  if object.is_a?(Hash) || object.is_a?(Array) ||
@@ -0,0 +1,11 @@
1
+ module YARD
2
+ module Server
3
+ # Registers a static path to be used in static asset lookup.
4
+ # @param [String] path the pathname to register
5
+ # @return [void]
6
+ # @since 0.6.2
7
+ def self.register_static_path(path)
8
+ Commands::StaticFileCommand::STATIC_PATHS.push(path)
9
+ end
10
+ end
11
+ end
@@ -5,7 +5,7 @@ module YARD
5
5
  include DocServerHelper
6
6
 
7
7
  def run
8
- main_url = request.path.gsub(/^(.+)?\/frames\/(#{path})$/, '\1/\2')
8
+ main_url = request.path.gsub(/^(.+)?\/frames(?:\/(#{path}))?$/, '\1/\2')
9
9
  if path =~ %r{^file/}
10
10
  page_title = "File: #{$'}"
11
11
  elsif !path.empty?
@@ -16,6 +16,10 @@ module YARD
16
16
 
17
17
  # @return [Boolean] whether to reparse data
18
18
  attr_accessor :incremental
19
+
20
+ # Needed to synchronize threads in {#setup_yardopts}
21
+ # @private
22
+ @@library_chdir_lock = Mutex.new
19
23
 
20
24
  def initialize(opts = {})
21
25
  super
@@ -23,6 +27,7 @@ module YARD
23
27
  end
24
28
 
25
29
  def call(request)
30
+ self.request = request
26
31
  self.options = SymbolHash.new(false).update(
27
32
  :serialize => false,
28
33
  :serializer => serializer,
@@ -35,32 +40,36 @@ module YARD
35
40
  setup_library
36
41
  super
37
42
  rescue LibraryNotPreparedError
38
- not_prepared(request)
43
+ not_prepared
39
44
  end
40
45
 
41
46
  private
42
47
 
43
48
  def setup_library
44
- library.prepare!
49
+ library.prepare! if request.xhr? && request.query['process']
45
50
  load_yardoc
46
51
  setup_yardopts
47
52
  true
48
53
  end
49
54
 
50
55
  def setup_yardopts
51
- Dir.chdir(library.source_path)
52
- yardoc = CLI::Yardoc.new
53
- if incremental
54
- yardoc.run('-c', '-n', '--no-stats')
55
- else
56
- yardoc.parse_arguments
56
+ @@library_chdir_lock.synchronize do
57
+ Dir.chdir(library.source_path) do
58
+ yardoc = CLI::Yardoc.new
59
+ if incremental
60
+ yardoc.run('-c', '-n', '--no-stats')
61
+ else
62
+ yardoc.parse_arguments
63
+ end
64
+ yardoc.options.delete(:serializer)
65
+ yardoc.options[:files].unshift(*Dir.glob('README*'))
66
+ options.update(yardoc.options.to_hash)
67
+ end
57
68
  end
58
- yardoc.options.delete(:serializer)
59
- yardoc.options[:files].unshift(*Dir.glob(library.source_path + '/README*'))
60
- options.update(yardoc.options.to_hash)
61
69
  end
62
70
 
63
71
  def load_yardoc
72
+ raise LibraryNotPreparedError unless library.yardoc_file
64
73
  if @@last_yardoc == library.yardoc_file
65
74
  log.debug "Reusing yardoc file: #{library.yardoc_file}"
66
75
  return
@@ -70,7 +79,7 @@ module YARD
70
79
  @@last_yardoc = library.yardoc_file
71
80
  end
72
81
 
73
- def not_prepared(request)
82
+ def not_prepared
74
83
  self.caching = false
75
84
  options.update(:path => request.path, :template => :doc_server, :type => :processing)
76
85
  [302, {'Content-Type' => 'text/html'}, [render]]
@@ -80,4 +89,4 @@ module YARD
80
89
  end
81
90
  end
82
91
  end
83
- end
92
+ end
@@ -1,6 +1,7 @@
1
1
  module YARD
2
2
  module Server
3
3
  module Commands
4
+ # Returns the index of libraries served by the server.
4
5
  class LibraryIndexCommand < Base
5
6
  attr_accessor :options
6
7
 
@@ -1,6 +1,8 @@
1
1
  module YARD
2
2
  module Server
3
3
  module Commands
4
+ # Performs a search over the objects inside of a library and returns
5
+ # the results as HTML or plaintext
4
6
  class SearchCommand < LibraryCommand
5
7
  attr_accessor :results, :query
6
8
 
@@ -3,11 +3,16 @@ require 'webrick/httputils'
3
3
  module YARD
4
4
  module Server
5
5
  module Commands
6
+ # Serves static content when no other router matches a request
6
7
  class StaticFileCommand < Base
7
8
  include WEBrick::HTTPUtils
8
9
 
9
10
  DefaultMimeTypes['js'] = 'text/javascript'
10
11
 
12
+ # Defines the paths used to search for static assets. To define an
13
+ # extra path, use {YARD::Server.register_static_path} rather than
14
+ # modifying this constant directly. Also note that files in the
15
+ # document root will always take precedence over these paths.
11
16
  STATIC_PATHS = [
12
17
  File.join(YARD::TEMPLATE_ROOT, 'default', 'fulldoc', 'html'),
13
18
  File.join(File.dirname(__FILE__), '..', 'templates', 'default', 'fulldoc', 'html')
@@ -15,7 +20,7 @@ module YARD
15
20
 
16
21
  def run
17
22
  path = File.cleanpath(request.path).gsub(%r{^(../)+}, '')
18
- ([adapter.document_root] + STATIC_PATHS).compact.each do |path_prefix|
23
+ ([adapter.document_root] + STATIC_PATHS.reverse).compact.each do |path_prefix|
19
24
  file = File.join(path_prefix, path)
20
25
  if File.exist?(file)
21
26
  ext = "." + (request.path[/\.(\w+)$/, 1] || "html")
@@ -7,8 +7,8 @@
7
7
  <link rel="stylesheet" href="/css/custom.css" type="text/css" media="screen" charset="utf-8" />
8
8
  <script type="text/javascript" charset="utf-8" src="/js/jquery.js"></script>
9
9
  <script type="text/javascript" charset="utf-8">
10
- function checkPage() {
11
- $.ajax({cache: false, url: "<%= @path %>", success: function() { window.location = "<%= @path %>"; } });
10
+ function checkPage(process) {
11
+ $.ajax({cache: false, url: "<%= @path %>" + (process ? "?process=true" : ""), success: function() { window.location = "<%= @path %>"; } });
12
12
  setTimeout('checkPage()', 2000);
13
13
  }
14
14
  function setFade() {
@@ -23,7 +23,7 @@
23
23
  $('#processing').css('left', ($(window).width() / 2 - $('#processing').width() / 2) + 'px');
24
24
  $('#processing').css('top', ($(window).height() / 2 - $('#processing').height() / 2) + 'px');
25
25
  }
26
- $(checkPage);
26
+ $(function() { checkPage(true); });
27
27
  $(setFade);
28
28
  </script>
29
29
  <style type="text/css" media="screen">
@@ -51,7 +51,7 @@ module YARD
51
51
  str = $1
52
52
  str = html_syntax_highlight(CGI.unescapeHTML(str)) unless options[:no_highlight]
53
53
  %Q{<pre class="code">#{str}</pre>}
54
- end
54
+ end unless markup == :text
55
55
  html
56
56
  end
57
57
 
@@ -9,7 +9,8 @@ module YARD
9
9
  {:lib => :bluecloth, :const => 'BlueCloth'},
10
10
  {:lib => :maruku, :const => 'Maruku'},
11
11
  {:lib => :"rpeg-markdown", :const => "PEGMarkdown"},
12
- {:lib => :rdiscount, :const => "RDiscount"}
12
+ {:lib => :rdiscount, :const => "RDiscount"},
13
+ {:lib => :kramdown, :const => "Kramdown::Document"}
13
14
  ],
14
15
  :textile => [
15
16
  {:lib => :redcloth, :const => 'RedCloth'}
@@ -47,8 +48,6 @@ module YARD
47
48
  require 'rdoc/markup/simple_markup/to_html'
48
49
  SimpleMarkup = SM::SimpleMarkup.new
49
50
  end
50
-
51
- private
52
51
 
53
52
  # Attempts to load the first valid markup provider in {MARKUP_PROVIDERS}.
54
53
  # If a provider is specified, immediately try to load it.
@@ -59,34 +58,36 @@ module YARD
59
58
  #
60
59
  # On failure this method will inform the user that no provider could be
61
60
  # found and exit the program.
61
+ #
62
+ # @return [Boolean] whether the markup provider was successfully loaded.
62
63
  def load_markup_provider(type = options[:markup])
63
- return if type == :rdoc || (@markup_cache && @markup_cache[type])
64
+ return true if type == :rdoc || (@markup_cache && @markup_cache[type])
64
65
  @markup_cache ||= {}
65
66
  @markup_cache[type] ||= {}
66
67
 
67
68
  providers = MARKUP_PROVIDERS[type]
68
- return if providers && providers.empty?
69
- if options[:markup_provider]
69
+ return true if providers && providers.empty?
70
+ if providers && options[:markup_provider]
70
71
  providers = providers.select {|p| p[:lib] == options[:markup_provider] }
71
72
  end
72
73
 
73
74
  if providers == nil || providers.empty?
74
- STDERR.puts "Invalid markup type '#{type}'"
75
- exit
75
+ log.error "Invalid markup type '#{type}' or markup provider is not registered."
76
+ return false
76
77
  end
77
78
 
78
79
  # Search for provider, return the library class name as const if found
79
80
  providers.each do |provider|
80
81
  begin require provider[:lib].to_s; rescue LoadError; next end
81
82
  @markup_cache[type][:provider] = provider[:lib] # Cache the provider
82
- @markup_cache[type][:class] = Kernel.const_get(provider[:const])
83
- return
83
+ @markup_cache[type][:class] = eval(provider[:const])
84
+ return false
84
85
  end
85
86
 
86
87
  # Show error message telling user to install first potential provider
87
88
  name, lib = providers.first[:const], providers.first[:lib]
88
- STDERR.puts "Missing #{name} gem for #{options[:markup].to_s.capitalize} formatting. Install it with `gem install #{lib}`"
89
- exit
89
+ log.error "Missing #{name} gem for #{options[:markup].to_s.capitalize} formatting. Install it with `gem install #{lib}`"
90
+ false
90
91
  end
91
92
 
92
93
  # Checks for a shebang or looks at the file extension to determine
@@ -67,11 +67,13 @@ module YARD
67
67
  end
68
68
  end
69
69
 
70
- # Tests the expressions on the object
70
+ # Tests the expressions on the object.
71
71
  #
72
+ # @note If the object is a {CodeObjects::Proxy} the result will always be true.
72
73
  # @param [CodeObjects::Base] object the object to verify
73
74
  # @return [Boolean] the result of the expressions
74
75
  def call(object)
76
+ return true if object.is_a?(CodeObjects::Proxy)
75
77
  modify_nilclass
76
78
  @object = object
77
79
  retval = __execute ? true : false
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe YARD::CLI::Config do
4
+ before do
5
+ @config = YARD::CLI::Config.new
6
+ YARD::Config.options = YARD::Config::DEFAULT_CONFIG_OPTIONS.dup
7
+ YARD::Config.stub!(:save)
8
+ end
9
+
10
+ def run(*args)
11
+ @config.run(*args)
12
+ end
13
+
14
+ describe 'Listing configuration' do
15
+ it "should accept --list" do
16
+ opts = YARD::Config.options
17
+ YAML.should_receive(:dump).twice.and_return("--- foo\nbar\nbaz")
18
+ @config.should_receive(:puts).twice.with("bar\nbaz")
19
+ run
20
+ run('--list')
21
+ YARD::Config.options.should == opts
22
+ end
23
+ end
24
+
25
+ describe 'Viewing an item' do
26
+ it "should view item if no value is given" do
27
+ YARD::Config.options[:foo] = 'bar'
28
+ @config.should_receive(:puts).with('"bar"')
29
+ run 'foo'
30
+ YARD::Config.options[:foo].should == 'bar'
31
+ end
32
+ end
33
+
34
+ describe 'Modifying an item' do
35
+ it "should accept --reset to set value" do
36
+ YARD::Config.options[:load_plugins] = 'foo'
37
+ run('--reset', 'load_plugins')
38
+ YARD::Config.options[:load_plugins].should == false
39
+ end
40
+
41
+
42
+ it "should modify item if value is given" do
43
+ run('foo', 'xxx')
44
+ YARD::Config.options[:foo].should == 'xxx'
45
+ end
46
+
47
+ it "should turn list of values into array of values" do
48
+ run('foo', 'a', 'b', '1', 'true', 'false')
49
+ YARD::Config.options[:foo].should == ['a', 'b', 1, true, false]
50
+ end
51
+
52
+ it "should turn number into numeric Ruby type" do
53
+ run('foo', '1')
54
+ YARD::Config.options[:foo].should == 1
55
+ end
56
+
57
+ it "should turn true into TrueClass" do
58
+ run('foo', 'true')
59
+ YARD::Config.options[:foo].should == true
60
+ end
61
+
62
+ it "should turn false into FalseClass" do
63
+ run('foo', 'false')
64
+ YARD::Config.options[:foo].should == false
65
+ end
66
+
67
+ it "should save on modification" do
68
+ YARD::Config.should_receive(:save)
69
+ run('foo', 'true')
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,81 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'ostruct'
3
+ require 'rubygems'
4
+
5
+ describe YARD::CLI::Gems do
6
+ before do
7
+ @rebuild = false
8
+ @gem1 = build_mock('gem1')
9
+ @gem2 = build_mock('gem2')
10
+ @gem3 = build_mock('gem3')
11
+ end
12
+
13
+ def build_mock(name, version = '1.0')
14
+ OpenStruct.new :name => name,
15
+ :version => version,
16
+ :full_gem_path => "/path/to/gems/#{name}-#{version}",
17
+ :yardoc_file => "/path/to/yardoc/#{name}-#{version}"
18
+ end
19
+
20
+ def build_specs(*specs)
21
+ specs.each do |themock|
22
+ Registry.should_receive(:yardoc_file_for_gem).with(themock.name, "= #{themock.version}").and_return(themock.yardoc_file)
23
+ File.should_receive(:directory?).with(themock.yardoc_file).and_return(@rebuild)
24
+ File.should_receive(:directory?).with(themock.full_gem_path).and_return(true)
25
+ Registry.should_receive(:yardoc_file_for_gem).with(themock.name, "= #{themock.version}", true).and_return(themock.yardoc_file)
26
+ Dir.should_receive(:chdir).with(themock.full_gem_path)
27
+ end
28
+ Registry.should_receive(:clear).exactly(specs.size).times
29
+ CLI::Yardoc.should_receive(:run).exactly(specs.size).times
30
+ end
31
+
32
+ describe '#run' do
33
+ it "should build all gem indexes if no gem is specified" do
34
+ build_specs(@gem1, @gem2)
35
+ Gem.source_index.should_receive(:find_name).with('').and_return([@gem1, @gem2])
36
+ CLI::Gems.run
37
+ end
38
+
39
+ it "should allow gem to be specified" do
40
+ build_specs(@gem1)
41
+ Gem.source_index.should_receive(:find_name).with(@gem1.name, '>= 0').and_return([@gem1])
42
+ CLI::Gems.run(@gem1.name)
43
+ end
44
+
45
+ it "should allow multiple gems to be specified for building" do
46
+ build_specs(@gem1, @gem2)
47
+ Gem.source_index.should_receive(:find_name).with(@gem1.name, @gem1.version).and_return([@gem1])
48
+ Gem.source_index.should_receive(:find_name).with(@gem2.name, '>= 0').and_return([@gem2])
49
+ CLI::Gems.run(@gem1.name, @gem1.version, @gem2.name)
50
+ end
51
+
52
+ it "should allow version to be specified with gem" do
53
+ build_specs(@gem1)
54
+ Gem.source_index.should_receive(:find_name).with(@gem1.name, '>= 1.0').and_return([@gem1])
55
+ CLI::Gems.run(@gem1.name, '>= 1.0')
56
+ end
57
+
58
+ it "should warn if one of the gems is not found, but it should process others" do
59
+ build_specs(@gem2)
60
+ Gem.source_index.should_receive(:find_name).with(@gem1.name, '>= 2.0').and_return([])
61
+ Gem.source_index.should_receive(:find_name).with(@gem2.name, '>= 0').and_return([@gem2])
62
+ log.should_receive(:warn).with(/#{@gem1.name} >= 2.0 could not be found/)
63
+ CLI::Gems.run(@gem1.name, '>= 2.0', @gem2.name)
64
+ end
65
+
66
+ it "should fail if specified gem(s) is/are not found" do
67
+ CLI::Yardoc.should_not_receive(:run)
68
+ Gem.source_index.should_receive(:find_name).with(@gem1.name, '>= 2.0').and_return([])
69
+ log.should_receive(:warn).with(/#{@gem1.name} >= 2.0 could not be found/)
70
+ log.should_receive(:error).with(/No specified gems could be found/)
71
+ CLI::Gems.run(@gem1.name, '>= 2.0')
72
+ end
73
+
74
+ it "should accept --rebuild" do
75
+ @rebuild = true
76
+ build_specs(@gem1)
77
+ Gem.source_index.should_receive(:find_name).with('').and_return([@gem1])
78
+ CLI::Gems.run('--rebuild')
79
+ end
80
+ end
81
+ end