raldred-webrat 0.4.4.2

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 (160) hide show
  1. data/History.txt +346 -0
  2. data/MIT-LICENSE.txt +19 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +168 -0
  5. data/install.rb +1 -0
  6. data/lib/webrat.rb +31 -0
  7. data/lib/webrat/core.rb +14 -0
  8. data/lib/webrat/core/configuration.rb +102 -0
  9. data/lib/webrat/core/elements/area.rb +31 -0
  10. data/lib/webrat/core/elements/element.rb +33 -0
  11. data/lib/webrat/core/elements/field.rb +405 -0
  12. data/lib/webrat/core/elements/form.rb +103 -0
  13. data/lib/webrat/core/elements/label.rb +31 -0
  14. data/lib/webrat/core/elements/link.rb +92 -0
  15. data/lib/webrat/core/elements/select_option.rb +35 -0
  16. data/lib/webrat/core/locators.rb +20 -0
  17. data/lib/webrat/core/locators/area_locator.rb +38 -0
  18. data/lib/webrat/core/locators/button_locator.rb +54 -0
  19. data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
  20. data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
  21. data/lib/webrat/core/locators/field_locator.rb +25 -0
  22. data/lib/webrat/core/locators/field_named_locator.rb +41 -0
  23. data/lib/webrat/core/locators/form_locator.rb +19 -0
  24. data/lib/webrat/core/locators/label_locator.rb +34 -0
  25. data/lib/webrat/core/locators/link_locator.rb +75 -0
  26. data/lib/webrat/core/locators/locator.rb +20 -0
  27. data/lib/webrat/core/locators/select_option_locator.rb +59 -0
  28. data/lib/webrat/core/logging.rb +24 -0
  29. data/lib/webrat/core/matchers.rb +4 -0
  30. data/lib/webrat/core/matchers/have_content.rb +73 -0
  31. data/lib/webrat/core/matchers/have_selector.rb +74 -0
  32. data/lib/webrat/core/matchers/have_tag.rb +21 -0
  33. data/lib/webrat/core/matchers/have_xpath.rb +147 -0
  34. data/lib/webrat/core/methods.rb +63 -0
  35. data/lib/webrat/core/mime.rb +29 -0
  36. data/lib/webrat/core/save_and_open_page.rb +50 -0
  37. data/lib/webrat/core/scope.rb +350 -0
  38. data/lib/webrat/core/session.rb +289 -0
  39. data/lib/webrat/core/xml.rb +115 -0
  40. data/lib/webrat/core/xml/hpricot.rb +19 -0
  41. data/lib/webrat/core/xml/nokogiri.rb +76 -0
  42. data/lib/webrat/core/xml/rexml.rb +24 -0
  43. data/lib/webrat/core_extensions/blank.rb +58 -0
  44. data/lib/webrat/core_extensions/deprecate.rb +8 -0
  45. data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
  46. data/lib/webrat/core_extensions/meta_class.rb +6 -0
  47. data/lib/webrat/core_extensions/nil_to_param.rb +5 -0
  48. data/lib/webrat/core_extensions/tcp_socket.rb +27 -0
  49. data/lib/webrat/mechanize.rb +74 -0
  50. data/lib/webrat/merb.rb +9 -0
  51. data/lib/webrat/merb_session.rb +65 -0
  52. data/lib/webrat/rack.rb +24 -0
  53. data/lib/webrat/rack_test.rb +32 -0
  54. data/lib/webrat/rails.rb +105 -0
  55. data/lib/webrat/rspec-rails.rb +13 -0
  56. data/lib/webrat/selenium.rb +81 -0
  57. data/lib/webrat/selenium/application_server.rb +73 -0
  58. data/lib/webrat/selenium/location_strategy_javascript/button.js +19 -0
  59. data/lib/webrat/selenium/location_strategy_javascript/label.js +15 -0
  60. data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
  61. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +12 -0
  62. data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
  63. data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
  64. data/lib/webrat/selenium/matchers.rb +4 -0
  65. data/lib/webrat/selenium/matchers/have_content.rb +66 -0
  66. data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
  67. data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
  68. data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
  69. data/lib/webrat/selenium/merb_application_server.rb +48 -0
  70. data/lib/webrat/selenium/rails_application_server.rb +42 -0
  71. data/lib/webrat/selenium/selenium_extensions.js +6 -0
  72. data/lib/webrat/selenium/selenium_rc_server.rb +84 -0
  73. data/lib/webrat/selenium/selenium_session.rb +242 -0
  74. data/lib/webrat/selenium/silence_stream.rb +18 -0
  75. data/lib/webrat/selenium/sinatra_application_server.rb +35 -0
  76. data/lib/webrat/sinatra.rb +44 -0
  77. data/spec/fakes/test_session.rb +34 -0
  78. data/spec/integration/merb/app/controllers/application.rb +2 -0
  79. data/spec/integration/merb/app/controllers/exceptions.rb +13 -0
  80. data/spec/integration/merb/app/controllers/testing.rb +18 -0
  81. data/spec/integration/merb/config/environments/development.rb +15 -0
  82. data/spec/integration/merb/config/environments/rake.rb +11 -0
  83. data/spec/integration/merb/config/environments/test.rb +14 -0
  84. data/spec/integration/merb/config/init.rb +25 -0
  85. data/spec/integration/merb/config/rack.rb +11 -0
  86. data/spec/integration/merb/config/router.rb +33 -0
  87. data/spec/integration/merb/spec/spec_helper.rb +24 -0
  88. data/spec/integration/merb/spec/webrat_spec.rb +32 -0
  89. data/spec/integration/merb/tasks/merb.thor/app_script.rb +31 -0
  90. data/spec/integration/merb/tasks/merb.thor/common.rb +64 -0
  91. data/spec/integration/merb/tasks/merb.thor/gem_ext.rb +124 -0
  92. data/spec/integration/merb/tasks/merb.thor/ops.rb +93 -0
  93. data/spec/integration/merb/tasks/merb.thor/utils.rb +40 -0
  94. data/spec/integration/rack/rack_app.rb +16 -0
  95. data/spec/integration/rack/test/test_helper.rb +20 -0
  96. data/spec/integration/rack/test/webrat_rack_test.rb +67 -0
  97. data/spec/integration/rails/app/controllers/application.rb +15 -0
  98. data/spec/integration/rails/app/controllers/buttons_controller.rb +7 -0
  99. data/spec/integration/rails/app/controllers/fields_controller.rb +4 -0
  100. data/spec/integration/rails/app/controllers/links_controller.rb +7 -0
  101. data/spec/integration/rails/app/controllers/webrat_controller.rb +39 -0
  102. data/spec/integration/rails/app/helpers/buttons_helper.rb +2 -0
  103. data/spec/integration/rails/app/helpers/fields_helper.rb +2 -0
  104. data/spec/integration/rails/app/helpers/links_helper.rb +2 -0
  105. data/spec/integration/rails/config/boot.rb +109 -0
  106. data/spec/integration/rails/config/environment.rb +12 -0
  107. data/spec/integration/rails/config/environments/development.rb +17 -0
  108. data/spec/integration/rails/config/environments/selenium.rb +22 -0
  109. data/spec/integration/rails/config/environments/test.rb +22 -0
  110. data/spec/integration/rails/config/initializers/inflections.rb +10 -0
  111. data/spec/integration/rails/config/initializers/mime_types.rb +5 -0
  112. data/spec/integration/rails/config/initializers/new_rails_defaults.rb +17 -0
  113. data/spec/integration/rails/config/routes.rb +17 -0
  114. data/spec/integration/rails/test/integration/button_click_test.rb +80 -0
  115. data/spec/integration/rails/test/integration/fill_in_test.rb +24 -0
  116. data/spec/integration/rails/test/integration/link_click_test.rb +21 -0
  117. data/spec/integration/rails/test/integration/webrat_test.rb +75 -0
  118. data/spec/integration/rails/test/test_helper.rb +25 -0
  119. data/spec/integration/sinatra/classic_app.rb +64 -0
  120. data/spec/integration/sinatra/modular_app.rb +16 -0
  121. data/spec/integration/sinatra/test/classic_app_test.rb +37 -0
  122. data/spec/integration/sinatra/test/modular_app_test.rb +18 -0
  123. data/spec/integration/sinatra/test/test_helper.rb +16 -0
  124. data/spec/private/core/configuration_spec.rb +106 -0
  125. data/spec/private/core/field_spec.rb +85 -0
  126. data/spec/private/core/link_spec.rb +24 -0
  127. data/spec/private/core/logging_spec.rb +10 -0
  128. data/spec/private/core/session_spec.rb +198 -0
  129. data/spec/private/mechanize/mechanize_session_spec.rb +81 -0
  130. data/spec/private/merb/merb_session_spec.rb +42 -0
  131. data/spec/private/nokogiri_spec.rb +77 -0
  132. data/spec/private/rails/attaches_file_spec.rb +81 -0
  133. data/spec/private/rails/rails_session_spec.rb +110 -0
  134. data/spec/public/basic_auth_spec.rb +24 -0
  135. data/spec/public/check_spec.rb +191 -0
  136. data/spec/public/choose_spec.rb +118 -0
  137. data/spec/public/click_area_spec.rb +106 -0
  138. data/spec/public/click_button_spec.rb +496 -0
  139. data/spec/public/click_link_spec.rb +541 -0
  140. data/spec/public/fill_in_spec.rb +209 -0
  141. data/spec/public/locators/field_by_xpath_spec.rb +19 -0
  142. data/spec/public/locators/field_labeled_spec.rb +172 -0
  143. data/spec/public/locators/field_with_id_spec.rb +16 -0
  144. data/spec/public/matchers/contain_spec.rb +114 -0
  145. data/spec/public/matchers/have_selector_spec.rb +142 -0
  146. data/spec/public/matchers/have_tag_spec.rb +39 -0
  147. data/spec/public/matchers/have_xpath_spec.rb +136 -0
  148. data/spec/public/reload_spec.rb +10 -0
  149. data/spec/public/save_and_open_spec.rb +51 -0
  150. data/spec/public/select_date_spec.rb +112 -0
  151. data/spec/public/select_datetime_spec.rb +137 -0
  152. data/spec/public/select_spec.rb +249 -0
  153. data/spec/public/select_time_spec.rb +100 -0
  154. data/spec/public/set_hidden_field_spec.rb +5 -0
  155. data/spec/public/submit_form_spec.rb +5 -0
  156. data/spec/public/visit_spec.rb +58 -0
  157. data/spec/public/within_spec.rb +177 -0
  158. data/spec/spec_helper.rb +50 -0
  159. data/vendor/selenium-server.jar +0 -0
  160. metadata +220 -0
@@ -0,0 +1,18 @@
1
+ module Webrat
2
+ module Selenium
3
+ module SilenceStream
4
+ # active_support already defines silence_stream, no need to do that again if it's already present.
5
+ # http://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/kernel/reporting.rb
6
+ unless Kernel.respond_to?(:silence_stream)
7
+ def silence_stream(stream)
8
+ old_stream = stream.dup
9
+ stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
10
+ stream.sync = true
11
+ yield
12
+ ensure
13
+ stream.reopen(old_stream)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ module Webrat
2
+ module Selenium
3
+
4
+ class SinatraApplicationServer < ApplicationServer
5
+
6
+ def start
7
+ fork do
8
+ File.open('rack.pid', 'w') { |fp| fp.write Process.pid }
9
+ exec 'rackup', File.expand_path(Dir.pwd + '/config.ru'), '-p', Webrat.configuration.application_port.to_s
10
+ end
11
+ end
12
+
13
+ def stop
14
+ silence_stream(STDOUT) do
15
+ pid = File.read(pid_file)
16
+ system("kill -9 #{pid}")
17
+ FileUtils.rm_f pid_file
18
+ end
19
+ end
20
+
21
+ def fail
22
+ $stderr.puts
23
+ $stderr.puts
24
+ $stderr.puts "==> Failed to boot the Sinatra application server... exiting!"
25
+ exit
26
+ end
27
+
28
+ def pid_file
29
+ prepare_pid_file(Dir.pwd, 'rack.pid')
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ require "webrat/rack"
2
+ require "sinatra/test"
3
+
4
+ module Webrat
5
+ class SinatraSession < RackSession
6
+ include Sinatra::Test
7
+
8
+ attr_reader :request, :response
9
+
10
+ def initialize(context = nil)
11
+ super(context)
12
+
13
+ app = context.respond_to?(:app) ? context.app : Sinatra::Application
14
+ @browser = Sinatra::TestHarness.new(app)
15
+ end
16
+
17
+ %w(get head post put delete).each do |verb|
18
+ class_eval <<-RUBY
19
+ def #{verb}(path, data, headers = {})
20
+ params = data.inject({}) do |data, (key,value)|
21
+ data[key] = Rack::Utils.unescape(value)
22
+ data
23
+ end
24
+ headers["HTTP_HOST"] = "www.example.com"
25
+ @browser.#{verb}(path, params, headers)
26
+ end
27
+ RUBY
28
+ end
29
+
30
+ def response_body
31
+ @browser.body
32
+ end
33
+
34
+ def response_code
35
+ @browser.status
36
+ end
37
+
38
+ private
39
+
40
+ def response
41
+ @browser.response
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module Webrat #:nodoc:
2
+ def self.session_class #:nodoc:
3
+ TestSession
4
+ end
5
+
6
+ class TestSession < Session #:nodoc:
7
+ attr_accessor :response_body
8
+ attr_writer :response_code
9
+
10
+ def doc_root
11
+ File.expand_path(File.join(".", "public"))
12
+ end
13
+
14
+ def response
15
+ @response ||= Object.new
16
+ end
17
+
18
+ def response_code
19
+ @response_code || 200
20
+ end
21
+
22
+ def get(url, data, headers = nil)
23
+ end
24
+
25
+ def post(url, data, headers = nil)
26
+ end
27
+
28
+ def put(url, data, headers = nil)
29
+ end
30
+
31
+ def delete(url, data, headers = nil)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,2 @@
1
+ class Application < Merb::Controller
2
+ end
@@ -0,0 +1,13 @@
1
+ class Exceptions < Merb::Controller
2
+
3
+ # handle NotFound exceptions (404)
4
+ def not_found
5
+ render :format => :html
6
+ end
7
+
8
+ # handle NotAcceptable exceptions (406)
9
+ def not_acceptable
10
+ render :format => :html
11
+ end
12
+
13
+ end
@@ -0,0 +1,18 @@
1
+ class Testing < Application
2
+
3
+ def show_form
4
+ render
5
+ end
6
+
7
+ def submit_form
8
+ end
9
+
10
+ def internal_redirect
11
+ redirect "/"
12
+ end
13
+
14
+ def external_redirect
15
+ redirect "http://google.com"
16
+ end
17
+
18
+ end
@@ -0,0 +1,15 @@
1
+ Merb.logger.info("Loaded DEVELOPMENT Environment...")
2
+ Merb::Config.use { |c|
3
+ c[:exception_details] = true
4
+ c[:reload_templates] = true
5
+ c[:reload_classes] = true
6
+ c[:reload_time] = 0.5
7
+ c[:ignore_tampered_cookies] = true
8
+ c[:log_auto_flush ] = true
9
+ c[:log_level] = :debug
10
+
11
+ c[:log_stream] = STDOUT
12
+ c[:log_file] = nil
13
+ # Or redirect logging into a file:
14
+ # c[:log_file] = Merb.root / "log" / "development.log"
15
+ }
@@ -0,0 +1,11 @@
1
+ Merb.logger.info("Loaded RAKE Environment...")
2
+ Merb::Config.use { |c|
3
+ c[:exception_details] = true
4
+ c[:reload_classes] = false
5
+ c[:log_auto_flush ] = true
6
+
7
+ c[:log_stream] = STDOUT
8
+ c[:log_file] = nil
9
+ # Or redirect logging into a file:
10
+ # c[:log_file] = Merb.root / "log" / "development.log"
11
+ }
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + "/../../../../../lib/webrat"
2
+
3
+ Merb.logger.info("Loaded TEST Environment...")
4
+ Merb::Config.use { |c|
5
+ c[:testing] = true
6
+ c[:exception_details] = true
7
+ c[:log_auto_flush ] = true
8
+ # log less in testing environment
9
+ c[:log_level] = :error
10
+
11
+ #c[:log_file] = Merb.root / "log" / "test.log"
12
+ # or redirect logger using IO handle
13
+ c[:log_stream] = STDOUT
14
+ }
@@ -0,0 +1,25 @@
1
+ # Go to http://wiki.merbivore.com/pages/init-rb
2
+
3
+ # Specify a specific version of a dependency
4
+ # dependency "RedCloth", "> 3.0"
5
+
6
+ # use_orm :none
7
+ use_test :rspec
8
+ use_template_engine :erb
9
+
10
+ Merb::Config.use do |c|
11
+ c[:use_mutex] = false
12
+ c[:session_store] = 'cookie' # can also be 'memory', 'memcache', 'container', 'datamapper
13
+
14
+ # cookie session store configuration
15
+ c[:session_secret_key] = 'adb9ea7a0e94b5513503f58623a393c5efe18851' # required for cookie session store
16
+ c[:session_id_key] = '_merb_session_id' # cookie session id key, defaults to "_session_id"
17
+ end
18
+
19
+ Merb::BootLoader.before_app_loads do
20
+ # This will get executed after dependencies have been loaded but before your app's classes have loaded.
21
+ end
22
+
23
+ Merb::BootLoader.after_app_loads do
24
+ # This will get executed after your app's classes have been loaded.
25
+ end
@@ -0,0 +1,11 @@
1
+ # use PathPrefix Middleware if :path_prefix is set in Merb::Config
2
+ if prefix = ::Merb::Config[:path_prefix]
3
+ use Merb::Rack::PathPrefix, prefix
4
+ end
5
+
6
+ # comment this out if you are running merb behind a load balancer
7
+ # that serves static files
8
+ use Merb::Rack::Static, Merb.dir_for(:public)
9
+
10
+ # this is our main merb application
11
+ run Merb::Rack::Application.new
@@ -0,0 +1,33 @@
1
+ # Merb::Router is the request routing mapper for the merb framework.
2
+ #
3
+ # You can route a specific URL to a controller / action pair:
4
+ #
5
+ # match("/contact").
6
+ # to(:controller => "info", :action => "contact")
7
+ #
8
+ # You can define placeholder parts of the url with the :symbol notation. These
9
+ # placeholders will be available in the params hash of your controllers. For example:
10
+ #
11
+ # match("/books/:book_id/:action").
12
+ # to(:controller => "books")
13
+ #
14
+ # Or, use placeholders in the "to" results for more complicated routing, e.g.:
15
+ #
16
+ # match("/admin/:module/:controller/:action/:id").
17
+ # to(:controller => ":module/:controller")
18
+ #
19
+ # You can specify conditions on the placeholder by passing a hash as the second
20
+ # argument of "match"
21
+ #
22
+ # match("/registration/:course_name", :course_name => /^[a-z]{3,5}-\d{5}$/).
23
+ # to(:controller => "registration")
24
+ #
25
+ # You can also use regular expressions, deferred routes, and many other options.
26
+ # See merb/specs/merb/router.rb for a fairly complete usage sample.
27
+
28
+ Merb.logger.info("Compiling routes...")
29
+ Merb::Router.prepare do
30
+ match("/").to(:controller => "testing", :action => "show_form")
31
+ match("/internal_redirect").to(:controller => "testing", :action => "internal_redirect")
32
+ match("/external_redirect").to(:controller => "testing", :action => "external_redirect")
33
+ end
@@ -0,0 +1,24 @@
1
+ require "rubygems"
2
+
3
+ # Add the local gems dir if found within the app root; any dependencies loaded
4
+ # hereafter will try to load from the local gems before loading system gems.
5
+ if (local_gem_dir = File.join(File.dirname(__FILE__), '..', 'gems')) && $BUNDLE.nil?
6
+ $BUNDLE = true; Gem.clear_paths; Gem.path.unshift(local_gem_dir)
7
+ end
8
+
9
+ require "merb-core"
10
+ require "spec" # Satisfies Autotest and anyone else not using the Rake tasks
11
+
12
+ # this loads all plugins required in your init file so don't add them
13
+ # here again, Merb will do it for you
14
+ Merb.start_environment(:testing => true, :adapter => 'runner', :environment => ENV['MERB_ENV'] || 'test')
15
+
16
+ Spec::Runner.configure do |config|
17
+ config.include(Merb::Test::ViewHelper)
18
+ config.include(Merb::Test::RouteHelper)
19
+ config.include(Merb::Test::ControllerHelper)
20
+ end
21
+
22
+ Webrat.configure do |config|
23
+ config.mode = :merb
24
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
2
+
3
+ describe "Webrat" do
4
+ it "should visit pages" do
5
+ response = visit "/"
6
+ response.should contain("Webrat Form")
7
+ end
8
+
9
+ it "should submit forms" do
10
+ visit "/"
11
+ fill_in "Text field", :with => "Hello"
12
+ check "TOS"
13
+ select "January"
14
+ click_button "Test"
15
+ end
16
+
17
+ it "should follow internal redirects" do
18
+ response = visit "/internal_redirect"
19
+ response.status.should == 200
20
+ response.should contain("Webrat Form")
21
+ end
22
+
23
+ it "should check the value of a field" do
24
+ visit "/"
25
+ field_labeled("Prefilled").value.should == "text"
26
+ end
27
+
28
+ it "should not follow external redirects" do
29
+ response = visit "/external_redirect"
30
+ response.status.should == 302
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This was added by Merb's bundler
4
+
5
+ require "rubygems"
6
+ require File.join(File.dirname(__FILE__), "common")
7
+
8
+ gems_dir = File.join(File.dirname(__FILE__), '..', 'gems')
9
+
10
+ if File.directory?(gems_dir)
11
+ $BUNDLE = true
12
+ Gem.clear_paths
13
+ Gem.path.replace([File.expand_path(gems_dir)])
14
+ ENV["PATH"] = "#{File.dirname(__FILE__)}:#{ENV["PATH"]}"
15
+
16
+ gem_file = File.join(gems_dir, "specifications", "<%= spec.name %>-*.gemspec")
17
+
18
+ if local_gem = Dir[gem_file].last
19
+ version = File.basename(local_gem)[/-([\.\d]+)\.gemspec$/, 1]
20
+ end
21
+ end
22
+
23
+ version ||= "<%= Gem::Requirement.default %>"
24
+
25
+ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
26
+ version = $1
27
+ ARGV.shift
28
+ end
29
+
30
+ gem '<%= @spec.name %>', version
31
+ load '<%= bin_file_name %>'
@@ -0,0 +1,64 @@
1
+ # This was added via Merb's bundler
2
+
3
+ require "rubygems"
4
+ require "rubygems/source_index"
5
+
6
+ module Gem
7
+ BUNDLED_SPECS = File.join(Dir.pwd, "gems", "specifications")
8
+ MAIN_INDEX = Gem::SourceIndex.from_gems_in(BUNDLED_SPECS)
9
+ FALLBACK_INDEX = Gem::SourceIndex.from_installed_gems
10
+
11
+ def self.source_index
12
+ MultiSourceIndex.new
13
+ end
14
+
15
+ def self.searcher
16
+ MultiPathSearcher.new
17
+ end
18
+
19
+ class ArbitrarySearcher < GemPathSearcher
20
+ def initialize(source_index)
21
+ @source_index = source_index
22
+ super()
23
+ end
24
+
25
+ def init_gemspecs
26
+ @source_index.map { |_, spec| spec }.sort { |a,b|
27
+ (a.name <=> b.name).nonzero? || (b.version <=> a.version)
28
+ }
29
+ end
30
+ end
31
+
32
+ class MultiPathSearcher
33
+ def initialize
34
+ @main_searcher = ArbitrarySearcher.new(MAIN_INDEX)
35
+ @fallback_searcher = ArbitrarySearcher.new(FALLBACK_INDEX)
36
+ end
37
+
38
+ def find(path)
39
+ try = @main_searcher.find(path)
40
+ return try if try
41
+ @fallback_searcher.find(path)
42
+ end
43
+
44
+ def find_all(path)
45
+ try = @main_searcher.find_all(path)
46
+ return try unless try.empty?
47
+ @fallback_searcher.find_all(path)
48
+ end
49
+ end
50
+
51
+ class MultiSourceIndex
52
+ def search(*args)
53
+ try = MAIN_INDEX.search(*args)
54
+ return try unless try.empty?
55
+ FALLBACK_INDEX.search(*args)
56
+ end
57
+
58
+ def find_name(*args)
59
+ try = MAIN_INDEX.find_name(*args)
60
+ return try unless try.empty?
61
+ FALLBACK_INDEX.find_name(*args)
62
+ end
63
+ end
64
+ end