cucumber-rails2 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +4 -0
  2. data/HACKING.rdoc +24 -0
  3. data/History.txt +145 -0
  4. data/LICENSE +22 -0
  5. data/README.rdoc +70 -0
  6. data/Rakefile +24 -0
  7. data/VERSION +1 -0
  8. data/config/.gitignore +1 -0
  9. data/cucumber-rails2.gemspec +111 -0
  10. data/dev_tasks/cucumber.rake +5 -0
  11. data/dev_tasks/rspec.rake +13 -0
  12. data/features/rails2.feature +64 -0
  13. data/features/rails3.feature +97 -0
  14. data/features/rerun_profile.feature +39 -0
  15. data/features/step_definitions/cucumber_rails_steps.rb +35 -0
  16. data/features/support/env.rb +4 -0
  17. data/features/support/matchers/files.rb +17 -0
  18. data/generators/cucumber/USAGE +13 -0
  19. data/generators/cucumber/cucumber_generator.rb +88 -0
  20. data/generators/feature/USAGE +12 -0
  21. data/generators/feature/feature_generator.rb +47 -0
  22. data/lib/cucumber/rails/action_controller.rb +65 -0
  23. data/lib/cucumber/rails/active_record.rb +34 -0
  24. data/lib/cucumber/rails/capybara_javascript_emulation.rb +81 -0
  25. data/lib/cucumber/rails/rspec.rb +22 -0
  26. data/lib/cucumber/rails/test_unit.rb +7 -0
  27. data/lib/cucumber/rails/world.rb +48 -0
  28. data/lib/cucumber/web/tableish.rb +118 -0
  29. data/lib/generators/cucumber/feature/USAGE +16 -0
  30. data/lib/generators/cucumber/feature/feature_base.rb +29 -0
  31. data/lib/generators/cucumber/feature/feature_generator.rb +37 -0
  32. data/lib/generators/cucumber/feature/named_arg.rb +17 -0
  33. data/lib/generators/cucumber/install/USAGE +15 -0
  34. data/lib/generators/cucumber/install/install_base.rb +202 -0
  35. data/lib/generators/cucumber/install/install_generator.rb +64 -0
  36. data/spec/cucumber/web/tableish_spec.rb +192 -0
  37. data/spec/generators/cucumber/install/install_base_spec.rb +84 -0
  38. data/spec/spec.opts +2 -0
  39. data/spec/spec_helper.rb +6 -0
  40. data/templates/feature/feature.erb +63 -0
  41. data/templates/feature/steps.erb +14 -0
  42. data/templates/install/config/cucumber.yml.erb +8 -0
  43. data/templates/install/environments/cucumber.rb.erb +37 -0
  44. data/templates/install/script/cucumber +10 -0
  45. data/templates/install/step_definitions/capybara_steps.rb.erb +214 -0
  46. data/templates/install/step_definitions/web_steps_cs.rb.erb +136 -0
  47. data/templates/install/step_definitions/web_steps_da.rb.erb +114 -0
  48. data/templates/install/step_definitions/web_steps_de.rb.erb +136 -0
  49. data/templates/install/step_definitions/web_steps_es.rb.erb +136 -0
  50. data/templates/install/step_definitions/web_steps_ja.rb.erb +139 -0
  51. data/templates/install/step_definitions/web_steps_ko.rb.erb +141 -0
  52. data/templates/install/step_definitions/web_steps_no.rb.erb +114 -0
  53. data/templates/install/step_definitions/web_steps_pt-BR.rb.erb +140 -0
  54. data/templates/install/step_definitions/webrat_steps.rb.erb +276 -0
  55. data/templates/install/support/_rails_each_run.rb.erb +35 -0
  56. data/templates/install/support/_rails_prefork.rb.erb +12 -0
  57. data/templates/install/support/capybara.rb +9 -0
  58. data/templates/install/support/edit_warning.txt +5 -0
  59. data/templates/install/support/paths.rb +33 -0
  60. data/templates/install/support/rails.rb.erb +4 -0
  61. data/templates/install/support/rails_spork.rb.erb +13 -0
  62. data/templates/install/support/webrat.rb +8 -0
  63. data/templates/install/tasks/cucumber.rake.erb +48 -0
  64. metadata +143 -0
@@ -0,0 +1,81 @@
1
+ module Cucumber
2
+ module Rails
3
+ module CapybaraJavascriptEmulation
4
+ def self.included(base)
5
+ base.class_eval do
6
+ alias_method :click_without_javascript_emulation, :click
7
+ alias_method :click, :click_with_javascript_emulation
8
+ end
9
+ end
10
+
11
+ def click_with_javascript_emulation
12
+ if link_with_non_get_http_method?
13
+ Capybara::RackTest::Form.new(driver, js_form(element_node.document, self[:href], emulated_method)).submit(self)
14
+ else
15
+ click_without_javascript_emulation
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def js_form(document, action, emulated_method, method = 'POST')
22
+ js_form = document.create_element('form')
23
+ js_form['action'] = action
24
+ js_form['method'] = method
25
+
26
+ if emulated_method and emulated_method.downcase != method.downcase
27
+ input = document.create_element('input')
28
+ input['type'] = 'hidden'
29
+ input['name'] = '_method'
30
+ input['value'] = emulated_method
31
+ js_form.add_child(input)
32
+ end
33
+
34
+ js_form
35
+ end
36
+
37
+ def link_with_non_get_http_method?
38
+ if ::Rails.version.to_f >= 3.0
39
+ tag_name == 'a' && element_node['data-method'] && element_node['data-method'] =~ /(?:delete|put|post)/
40
+ else
41
+ tag_name == 'a' && element_node['onclick'] && element_node['onclick'] =~ /var f = document\.createElement\('form'\); f\.style\.display = 'none';/
42
+ end
43
+ end
44
+
45
+ def emulated_method
46
+ if ::Rails.version.to_f >= 3.0
47
+ element_node['data-method']
48
+ else
49
+ element_node['onclick'][/m\.setAttribute\('value', '([^']*)'\)/, 1]
50
+ end
51
+ end
52
+
53
+ def element_node
54
+ if self.respond_to? :native
55
+ self.native
56
+ else
57
+ warn "DEPRECATED: cucumber-rails loves you, just not your version of Capybara. Please update Capybara to >= 0.4.0"
58
+ self.node
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ class Capybara::RackTest::Node
66
+ include Cucumber::Rails::CapybaraJavascriptEmulation
67
+ end
68
+
69
+ Before('~@no-js-emulation') do
70
+ # Enable javascript emulation
71
+ Capybara::RackTest::Node.class_eval do
72
+ alias_method :click, :click_with_javascript_emulation
73
+ end
74
+ end
75
+
76
+ Before('@no-js-emulation') do
77
+ # Disable javascript emulation
78
+ Capybara::RackTest::Node.class_eval do
79
+ alias_method :click, :click_without_javascript_emulation
80
+ end
81
+ end
@@ -0,0 +1,22 @@
1
+ # TODO: Not even sure is this is necessary anymore, since we're doing this in Cucumber's rb_world.rb...
2
+ require 'cucumber/rails/world'
3
+
4
+ begin
5
+ require 'rspec/rails/matchers'
6
+
7
+ [Cucumber::Rails::World, ActionController::Integration::Session].each do |klass|
8
+ klass.class_eval do
9
+ include RSpec::Matchers
10
+ end
11
+ end
12
+ rescue LoadError => try_rspec_1
13
+ require 'spec/expectations'
14
+ require 'spec/rails'
15
+
16
+ [Cucumber::Rails::World, ActionController::Integration::Session].each do |klass|
17
+ klass.class_eval do
18
+ include Spec::Matchers
19
+ include Spec::Rails::Matchers if defined?(Spec::Rails::Matchers)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ # This is fishy. Try to get rid of it....
2
+ begin
3
+ require 'test/unit/testresult'
4
+ # So that Test::Unit doesn't launch at the end - makes it think it has already been run.
5
+ Test::Unit.run = true if Test::Unit.respond_to?(:run=)
6
+ rescue LoadError => ignore
7
+ end
@@ -0,0 +1,48 @@
1
+ unless defined?(Test)
2
+ begin
3
+ require 'spec/test/unit'
4
+ rescue LoadError => ignore_if_rspec_not_installed
5
+ end
6
+ end
7
+
8
+ if defined?(ActiveRecord::Base)
9
+ if Rails.version.to_f >= 3.0
10
+ require 'rails/test_help'
11
+ else
12
+ require 'test_help'
13
+ end
14
+ else
15
+ # I can't do rescue LoadError because in this files could be loaded
16
+ # from rails gem (ie. load actionpack 2.3.5 if rubygems are not disabled)
17
+ if Rails.version.to_f < 3.0
18
+ require 'action_controller/test_process'
19
+ require 'action_controller/integration'
20
+ else
21
+ require 'action_dispatch/testing/test_process'
22
+ require 'action_dispatch/testing/integration'
23
+ end
24
+ end
25
+
26
+ require 'cucumber/rails/test_unit'
27
+ require 'cucumber/rails/action_controller'
28
+
29
+
30
+ if (::Rails.respond_to?(:application) && !(::Rails.application.config.cache_classes)) ||
31
+ (!(::Rails.respond_to?(:application)) && ::Rails.respond_to?(:configuration) && !(::Rails.configuration.cache_classes))
32
+ warn "WARNING: You have set Rails' config.cache_classes to false (most likely in config/environments/cucumber.rb). This setting is known to break Cucumber's use_transactional_fixtures method. Set config.cache_classes to true if you want to use transactional fixtures. For more information see https://rspec.lighthouseapp.com/projects/16211/tickets/165."
33
+ end
34
+
35
+ module Cucumber #:nodoc:
36
+ module Rails
37
+ class World < ActionController::IntegrationTest
38
+ include ActiveSupport::Testing::SetupAndTeardown if ActiveSupport::Testing.const_defined?("SetupAndTeardown")
39
+ def initialize #:nodoc:
40
+ @_result = Test::Unit::TestResult.new if defined?(Test::Unit::TestResult)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ World do
47
+ Cucumber::Rails::World.new
48
+ end
@@ -0,0 +1,118 @@
1
+ require 'nokogiri'
2
+
3
+ module Cucumber
4
+ module Web
5
+ module Tableish
6
+ # This method returns an Array of Array of String, using CSS3 selectors.
7
+ # This is particularly handy when using Cucumber's Table#diff! method.
8
+ #
9
+ # The +row_selector+ argument must be a String, and picks out all the rows
10
+ # from the web page's DOM. If the number of cells in each row differs, it
11
+ # will be constrained by (or padded with) the number of cells in the first row
12
+ #
13
+ # The +column_selectors+ argument must be a String or a Proc, picking out
14
+ # cells from each row. If you pass a Proc, it will be yielded an instance
15
+ # of Nokogiri::HTML::Element.
16
+ #
17
+ # == Example with a table
18
+ #
19
+ # <table id="tools">
20
+ # <tr>
21
+ # <th>tool</th>
22
+ # <th>dude</th>
23
+ # </tr>
24
+ # <tr>
25
+ # <td>webrat</td>
26
+ # <td>bryan</td>
27
+ # </tr>
28
+ # <tr>
29
+ # <td>cucumber</td>
30
+ # <td>aslak</td>
31
+ # </tr>
32
+ # </table>
33
+ #
34
+ # t = tableish('table#tools tr', 'td,th')
35
+ #
36
+ # == Example with a dl
37
+ #
38
+ # <dl id="tools">
39
+ # <dt>webrat</dt>
40
+ # <dd>bryan</dd>
41
+ # <dt>cucumber</dt>
42
+ # <dd>aslak</dd>
43
+ # </dl>
44
+ #
45
+ # t = tableish('dl#tools dt', lambda{|dt| [dt, dt.next.next]})
46
+ #
47
+ def tableish(row_selector, column_selectors)
48
+ html = defined?(Capybara) ? body : response_body
49
+ _tableish(html, row_selector, column_selectors)
50
+ end
51
+
52
+ def _tableish(html, row_selector, column_selectors) #:nodoc
53
+ doc = Nokogiri::HTML(html)
54
+ spans = nil
55
+ max_cols = 0
56
+
57
+ # Parse the table.
58
+ rows = doc.search(row_selector).map do |row|
59
+ cells = case(column_selectors)
60
+ when String
61
+ row.search(column_selectors)
62
+ when Proc
63
+ column_selectors.call(row)
64
+ end
65
+
66
+ # TODO: max_cols should be sum of colspans
67
+ max_cols = [max_cols, cells.length].max
68
+
69
+ spans ||= Array.new(max_cols, 1)
70
+
71
+ cell_index = 0
72
+
73
+ cells = (0...spans.length).inject([]) do |array, n|
74
+ span = spans[n]
75
+
76
+ cell = if span > 1
77
+ row_span, col_span = 1, 1
78
+ nil
79
+ else
80
+ cell = cells[cell_index]
81
+
82
+ row_span, col_span = _parse_spans(cell)
83
+
84
+ if col_span > 1
85
+ ((n + 1)...(n + col_span)).each do |m|
86
+ spans[m] = row_span + 1
87
+ end
88
+ end
89
+
90
+ cell_index +=1
91
+ cell
92
+ end
93
+
94
+ spans[n] = row_span > 1 ? row_span : ([span - 1, 1].max)
95
+
96
+ array << case cell
97
+ when String then cell.strip
98
+ when nil then ''
99
+ else cell.text.strip
100
+ end
101
+
102
+ array
103
+ end
104
+
105
+ cells
106
+ end
107
+ end
108
+
109
+ def _parse_spans(cell)
110
+ cell.is_a?(Nokogiri::XML::Node) ?
111
+ [cell.attributes['rowspan'].to_s.to_i || 1, cell.attributes['colspan'].to_s.to_i || 1] :
112
+ [1, 1]
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ World(Cucumber::Web::Tableish)
@@ -0,0 +1,16 @@
1
+ Description:
2
+ Generates a skeleton for a new feature. Both a simple .feature file and
3
+ a steps.rb file is generated. This generator should be used with moderation.
4
+ See http://github.com/aslakhellesoy/cucumber/wikis/feature-coupled-steps-antipattern
5
+ for details about the dangers involved.
6
+
7
+ This generator can take an optional list of attribute pairs similar to Rails'
8
+ built-in resource generator.
9
+
10
+ Examples (Rails 3):
11
+ `script/rails generate cucumber:feature post` # no attributes
12
+ `script/rails generate cucumber:feature post title:string body:text published:boolean`
13
+
14
+ Examples (Rails 2):
15
+ `script/generate feature post` # no attributes
16
+ `script/generate feature post title:string body:text published:boolean`
@@ -0,0 +1,29 @@
1
+ module Cucumber
2
+ module Generators
3
+ module FeatureBase
4
+
5
+ def create_directory(m = self, rails2 = false)
6
+ if rails2
7
+ m.directory 'features/step_definitions'
8
+ else
9
+ m.empty_directory 'features/step_definitions'
10
+ end
11
+ end
12
+
13
+ def create_feature_file(m = self)
14
+ m.template 'feature.erb', "features/manage_#{plural_name}.feature"
15
+ end
16
+
17
+ def create_steps_file(m = self)
18
+ m.template 'steps.erb', "features/step_definitions/#{singular_name}_steps.rb"
19
+ end
20
+
21
+ def create_support_file(m = self)
22
+ m.gsub_file 'features/support/paths.rb', /'\/'/mi do |match|
23
+ "#{match}\n when /the new #{singular_name} page/\n new_#{singular_name}_path\n"
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ require File.join(File.dirname(__FILE__), 'named_arg')
2
+ require File.join(File.dirname(__FILE__), 'feature_base')
3
+
4
+ module Cucumber
5
+ class FeatureGenerator < Rails::Generators::NamedBase
6
+
7
+ include Cucumber::Generators::FeatureBase
8
+
9
+ argument :fields, :optional => true, :type => :array, :banner => "[field:type, field:type]"
10
+
11
+ attr_reader :named_args
12
+
13
+ def parse_fields
14
+ @named_args = @fields.nil? ? [] : @fields.map { |arg| NamedArg.new(arg) }
15
+ end
16
+
17
+ def generate
18
+ create_directory
19
+ create_feature_file
20
+ create_steps_file
21
+ create_support_file
22
+ end
23
+
24
+ def self.banner
25
+ "#{$0} cucumber:feature ModelName [field:type, field:type]"
26
+ end
27
+
28
+ def self.gem_root
29
+ File.expand_path("../../../../../", __FILE__)
30
+ end
31
+
32
+ def self.source_root
33
+ File.join(gem_root, 'templates', 'feature')
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ class NamedArg
2
+ attr_reader :name
3
+ attr_reader :type
4
+
5
+ def initialize(s)
6
+ @name, @type = *s.split(':')
7
+ end
8
+
9
+ def value(n)
10
+ if @type == 'boolean'
11
+ (n % 2) == 0
12
+ else
13
+ "#{@name} #{n}"
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,15 @@
1
+ Description:
2
+ Sets up Cucumber in your Rails project. After running this generator you will
3
+ get a new rake task called features.
4
+
5
+ This also generates the necessary files in the features directory.
6
+
7
+ Also see the cucumber:feature generator.
8
+
9
+ Examples:
10
+ `script/rails generate cucumber:install`
11
+
12
+ `script/rails generate cucumber:install --help`
13
+
14
+ You can also provide a language argument for localized webrat_steps:
15
+ `script/rails generate cucumber:install de`
@@ -0,0 +1,202 @@
1
+ module Cucumber
2
+ module Generators
3
+ module InstallBase
4
+
5
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
6
+
7
+ # Checks and prints the limitations
8
+ def check_upgrade_limitations
9
+ if File.exist?('features/step_definitions/webrat_steps.rb')
10
+ STDERR.puts "Please remove features/step_definitions/webrat_steps.rb\n" +
11
+ "See upgrading instructions for 0.2.0 in History.txt"
12
+ exit(1)
13
+ end
14
+
15
+ if File.exist?('features/support/version_check.rb')
16
+ STDERR.puts "Please remove features/support/version_check.rb\n" +
17
+ "See upgrading instructions for 0.2.0 in History.txt"
18
+ exit(1)
19
+ end
20
+ end
21
+
22
+ # Creates templates
23
+ def create_templates(m = self, rails2 = false)
24
+ m.template 'config/cucumber.yml.erb', 'config/cucumber.yml'
25
+ if rails2
26
+ m.template 'environments/cucumber.rb.erb', 'config/environments/cucumber.rb'
27
+ end
28
+ end
29
+
30
+ def configure_gemfile(m = self, rails2 = false)
31
+ require 'thor-ext'
32
+ unless rails2
33
+ puts "Update Rails 3 Gemfile for cucumber"
34
+ gsub_file 'Gemfile', /('|")gem/, "\1\ngem"
35
+ add_gem('database_cleaner', '>=0.5.2') unless has_plugin? 'database_cleaner'
36
+ if driver == :capybara
37
+ add_gem('capybara', '>=0.3.7')
38
+ else
39
+ add_gem('webrat', '>=0.7.0') unless has_plugin? 'webrat'
40
+ end
41
+ if framework == :rspec
42
+ add_gem('rspec', '>=1.3.0') unless has_plugin? 'rspec'
43
+ add_gem('rspec-rails', '>=1.3.2') unless has_plugin? 'rspec-rails'
44
+ end
45
+ if spork?
46
+ add_gem('spork''>=0.7.5') unless has_plugin? 'spork'
47
+ end
48
+ add_gems(%w{cucumber cucumber-rails})
49
+ end
50
+ end
51
+
52
+ def create_scripts(m = self, rails2 = false)
53
+ if rails2
54
+ m.file 'script/cucumber', 'script/cucumber', {
55
+ :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang]
56
+ }
57
+ else
58
+ m.copy_file 'script/cucumber', 'script/cucumber'
59
+ m.chmod 'script/cucumber', 0755
60
+ end
61
+ end
62
+
63
+ def create_step_definitions(m = self, rails2 = false)
64
+ if rails2
65
+ m.directory 'features/step_definitions'
66
+ else
67
+ m.empty_directory 'features/step_definitions'
68
+ end
69
+
70
+ m.template "step_definitions/#{driver}_steps.rb.erb", 'features/step_definitions/web_steps.rb'
71
+ if language != 'en'
72
+ m.template "step_definitions/web_steps_#{language}.rb.erb", "features/step_definitions/web_steps_#{language}.rb"
73
+ end
74
+ end
75
+
76
+ def create_feature_support(m = self, rails2 = false)
77
+ if rails2
78
+ m.directory 'features/support'
79
+ m.file 'support/paths.rb', 'features/support/paths.rb'
80
+
81
+ if spork?
82
+ m.template 'support/rails_spork.rb.erb', 'features/support/env.rb'
83
+ else
84
+ m.template 'support/rails.rb.erb', 'features/support/env.rb'
85
+ end
86
+ else
87
+ m.empty_directory 'features/support'
88
+ m.copy_file 'support/paths.rb', 'features/support/paths.rb'
89
+
90
+ if spork?
91
+ m.template 'support/rails_spork.rb.erb', 'features/support/env.rb'
92
+ else
93
+ m.template 'support/rails.rb.erb', 'features/support/env.rb'
94
+ end
95
+ end
96
+ end
97
+
98
+ def create_tasks(m = self, rails2 = false)
99
+ if rails2
100
+ m.directory 'lib/tasks'
101
+ else
102
+ m.empty_directory 'lib/tasks'
103
+ end
104
+
105
+ m.template 'tasks/cucumber.rake.erb', 'lib/tasks/cucumber.rake'
106
+ end
107
+
108
+ def create_database(m = self, rails2 = false)
109
+ unless File.read('config/database.yml').include? 'cucumber:'
110
+ m.gsub_file 'config/database.yml', /^test:.*\n/, "test: &test\n"
111
+ m.gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *test"
112
+
113
+ # Since gsub_file doesn't ask the user, just inform user that the file was overwritten.
114
+ puts " force config/database.yml"
115
+ end
116
+ end
117
+
118
+ def print_instructions
119
+ require 'cucumber/formatter/ansicolor'
120
+ extend Cucumber::Formatter::ANSIColor
121
+
122
+ if @default_driver
123
+ puts <<-WARNING
124
+
125
+ #{yellow_cukes(15)}
126
+
127
+ #{yellow_cukes(1)} D R I V E R A L E R T #{yellow_cukes(1)}
128
+
129
+ You didn't explicitly generate with --capybara or --webrat, so I looked at
130
+ your gems and saw that you had #{green(@default_driver.to_s)} installed, so I went with that.
131
+ If you want something else, be specific about it. Otherwise, relax.
132
+
133
+ #{yellow_cukes(15)}
134
+
135
+ WARNING
136
+ end
137
+ end
138
+
139
+ protected
140
+
141
+ def detect_current_driver
142
+ detect_in_env([['capybara', :capybara], ['webrat', :webrat]])
143
+ end
144
+
145
+ def detect_default_driver
146
+ @default_driver = first_loadable([['capybara', :capybara], ['webrat', :webrat]])
147
+ raise "I don't know which driver you want. Use --capybara or --webrat, or gem install capybara or webrat." unless @default_driver
148
+ @default_driver
149
+ end
150
+
151
+ def detect_current_framework
152
+ detect_in_env([['spec', :rspec]]) || :testunit
153
+ end
154
+
155
+ def detect_default_framework
156
+ # TODO need to check this - defaulting to :testunit has been moved from first_loadable
157
+ # It's unlikely that we don't have test/unit since it comes with Ruby
158
+ @default_framework ||= first_loadable([['rspec', :rspec]])
159
+ end
160
+
161
+ def spork?
162
+ options[:spork]
163
+ end
164
+
165
+ def embed_file(source, indent='')
166
+ IO.read(File.join(self.class.source_root, source)).gsub(/^/, indent)
167
+ end
168
+
169
+ def embed_template(source, indent='')
170
+ template = File.join(self.class.source_root, source)
171
+ ERB.new(IO.read(template), nil, '-').result(binding).gsub(/^/, indent)
172
+ end
173
+
174
+ def version
175
+ IO.read(File.join(self.class.gem_root, 'VERSION')).chomp
176
+ end
177
+
178
+ def first_loadable(libraries)
179
+ require 'rubygems'
180
+
181
+ libraries.each do |lib_name, lib_key|
182
+ return lib_key if Gem.available?(lib_name)
183
+ end
184
+
185
+ nil
186
+ end
187
+
188
+ def detect_in_env(choices)
189
+ return nil unless File.file?("features/support/env.rb")
190
+
191
+ env = IO.read("features/support/env.rb")
192
+
193
+ choices.each do |choice|
194
+ detected = choice[1] if env =~ /#{choice[0]}/n
195
+ return detected if detected
196
+ end
197
+
198
+ nil
199
+ end
200
+ end
201
+ end
202
+ end