ginger 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE +20 -0
- data/README.textile +54 -0
- data/bin/ginger +42 -0
- data/lib/ginger.rb +22 -0
- data/lib/ginger/configuration.rb +20 -0
- data/lib/ginger/kernel.rb +56 -0
- data/lib/ginger/scenario.rb +30 -0
- data/spec/ginger/configuration_spec.rb +7 -0
- data/spec/ginger/kernel_spec.rb +7 -0
- data/spec/ginger/scenario_spec.rb +57 -0
- data/spec/ginger_spec.rb +14 -0
- metadata +70 -0
data/LICENCE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Pat Allan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
Ginger is a small gem that allows you to test your projects using multiple versions of gem libraries. The idea is from "Ian White's garlic":http://github.com/ianwhite/garlic/tree - hence the related name of this - but my approach is a bit different, since I don't test my plugins from within a rails application. Maybe they can be merged at some point - I just hacked this up quickly to fit my needs.
|
2
|
+
|
3
|
+
To get it all working, you need to do four things. The first is, of course, to install this gem.
|
4
|
+
|
5
|
+
<pre><code>sudo gem install ginger --source=http://gemcutter.org</code></pre>
|
6
|
+
|
7
|
+
Next, add the following line of code to your @spec_helper.rb@ file (or equivalent):
|
8
|
+
|
9
|
+
<pre><code>require 'ginger'</code></pre>
|
10
|
+
|
11
|
+
You'll want to put it as high up as possible - in particular, before any @require@ calls to libraries you want to cover multiple versions of.
|
12
|
+
|
13
|
+
Step number three is creating the sets of scenarios in a file called @ginger_scenarios.rb@, which should go in the root, spec or test directory of your project. Here's an example, showing off the syntax possibilities.
|
14
|
+
|
15
|
+
<pre><code>require 'ginger'
|
16
|
+
|
17
|
+
Ginger.configure do |config|
|
18
|
+
config.aliases["active_record"] = "activerecord"
|
19
|
+
|
20
|
+
ar_1_2_6 = Ginger::Scenario.new
|
21
|
+
ar_1_2_6[/^active_?record$/] = "1.15.6"
|
22
|
+
|
23
|
+
ar_2_0_2 = Ginger::Scenario.new
|
24
|
+
ar_2_0_2[/^active_?record$/] = "2.0.2"
|
25
|
+
|
26
|
+
ar_2_1_1 = Ginger::Scenario.new
|
27
|
+
ar_2_1_1[/^active_?record$/] = "2.1.1"
|
28
|
+
|
29
|
+
config.scenarios << ar_1_2_6 << ar_2_0_2 << ar_2_1_1
|
30
|
+
end</code></pre>
|
31
|
+
|
32
|
+
Above, I've added three different scenarios, for three different versions of ActiveRecord. I also added an alias, as people sometimes use the underscore, and sometimes don't. The gem's name has no underscore though, so the _value_ of the alias matches the gem name (whereas the key would be alternative usage).
|
33
|
+
|
34
|
+
You can have multiple gems set in each scenario - and you don't have to use regular expressions, you can just use straight strings.
|
35
|
+
|
36
|
+
<pre><code>sphinx_scenario = Ginger::Scenario.new
|
37
|
+
sphinx_scenario["riddle"] = "0.9.8"
|
38
|
+
sphinx_scenario["thinking_sphinx"] = "0.9.8"</code></pre>
|
39
|
+
|
40
|
+
Don't forget to add them to @config@'s scenarios collection, else they're not saved anywhere.
|
41
|
+
|
42
|
+
To better discern different defined scenarios you can create them with a name. The name will be output when the scenario runs as the title.
|
43
|
+
|
44
|
+
<pre><code>sphinx_scenario = Ginger::Scenario.new('Thinking Sphinx 0.9.8')</code></pre>
|
45
|
+
|
46
|
+
And finally, you'll want to run the tests or specs for each scenario. This is done using the @ginger@ CLI tool, which parrots whatever parameters you give it onto @rake@. So just do something like:
|
47
|
+
|
48
|
+
<pre><code>ginger spec
|
49
|
+
ginger test
|
50
|
+
ginger spec:unit</code></pre>
|
51
|
+
|
52
|
+
h2. Contributors
|
53
|
+
|
54
|
+
* "Adam Meehan":http://duckpunching.com/
|
data/bin/ginger
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ginger'
|
5
|
+
require 'rake'
|
6
|
+
|
7
|
+
if ARGV.length == 0
|
8
|
+
puts <<-USAGE
|
9
|
+
ginger #{Ginger::Version::String}
|
10
|
+
Use ginger to run specs for each scenario defined. Scenarios must be set out in
|
11
|
+
a file called ginger_scenarios.rb wherever this tool is run. Once they're
|
12
|
+
defined, then you can run this tool and provide the rake task that would
|
13
|
+
normally be called.
|
14
|
+
|
15
|
+
Examples:
|
16
|
+
ginger spec
|
17
|
+
ginger test
|
18
|
+
ginger spec:models
|
19
|
+
USAGE
|
20
|
+
exit 0
|
21
|
+
end
|
22
|
+
|
23
|
+
file_path = File.join Dir.pwd, ".ginger"
|
24
|
+
|
25
|
+
File.delete(file_path) if File.exists?(file_path)
|
26
|
+
|
27
|
+
scenarios = Ginger::Configuration.instance.scenarios
|
28
|
+
puts "No Ginger Scenarios defined" if scenarios.empty?
|
29
|
+
|
30
|
+
scenarios.each_with_index do |scenario, index|
|
31
|
+
puts <<-SCENARIO
|
32
|
+
|
33
|
+
-------------------
|
34
|
+
Ginger Scenario: #{scenario.name || index+1}
|
35
|
+
-------------------
|
36
|
+
SCENARIO
|
37
|
+
|
38
|
+
File.open('.ginger', 'w') { |f| f.write index.to_s }
|
39
|
+
system("rake #{ARGV.join(" ")}")
|
40
|
+
end
|
41
|
+
|
42
|
+
File.delete(file_path) if File.exists?(file_path)
|
data/lib/ginger.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ginger/configuration'
|
3
|
+
require 'ginger/scenario'
|
4
|
+
require 'ginger/kernel'
|
5
|
+
|
6
|
+
module Ginger
|
7
|
+
module Version
|
8
|
+
Major = 1
|
9
|
+
Minor = 1
|
10
|
+
Tiny = 0
|
11
|
+
|
12
|
+
String = [Major, Minor, Tiny].join('.')
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.configure(&block)
|
16
|
+
yield Ginger::Configuration.instance
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Kernel.send(:include, Ginger::Kernel)
|
21
|
+
|
22
|
+
Ginger::Configuration.detect_scenario_file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Ginger
|
4
|
+
class Configuration
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
attr_accessor :scenarios, :aliases
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@scenarios = []
|
11
|
+
@aliases = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.detect_scenario_file
|
15
|
+
['.','spec','test'].each do |path|
|
16
|
+
require "#{path}/ginger_scenarios" and break if File.exists?("#{path}/ginger_scenarios.rb")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Ginger
|
2
|
+
module Kernel
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
def require_with_ginger(req)
|
6
|
+
unless scenario = ginger_scenario
|
7
|
+
require_without_ginger(req)
|
8
|
+
return
|
9
|
+
end
|
10
|
+
|
11
|
+
if scenario.version(req)
|
12
|
+
gem ginger_gem_name(req)
|
13
|
+
end
|
14
|
+
|
15
|
+
require_without_ginger(req)
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :require_without_ginger, :require
|
19
|
+
alias_method :require, :require_with_ginger
|
20
|
+
|
21
|
+
def gem_with_ginger(gem_name, *version_requirements)
|
22
|
+
unless scenario = ginger_scenario
|
23
|
+
gem_without_ginger(gem_name, *version_requirements)
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
if version_requirements.length == 0 &&
|
28
|
+
version = scenario.version(gem_name)
|
29
|
+
version_requirements << "= #{version}"
|
30
|
+
end
|
31
|
+
|
32
|
+
gem_without_ginger(gem_name, *version_requirements)
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :gem_without_ginger, :gem
|
36
|
+
alias_method :gem, :gem_with_ginger
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def ginger_scenario
|
41
|
+
return nil unless File.exists?(".ginger")
|
42
|
+
|
43
|
+
scenario = nil
|
44
|
+
File.open('.ginger') { |f| scenario = f.read }
|
45
|
+
return nil unless scenario
|
46
|
+
|
47
|
+
Ginger::Configuration.instance.scenarios[scenario.to_i]
|
48
|
+
end
|
49
|
+
|
50
|
+
def ginger_gem_name(gem_name)
|
51
|
+
Ginger::Configuration.instance.aliases[gem_name] || gem_name
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Ginger
|
2
|
+
class Scenario < Hash
|
3
|
+
attr_accessor :name
|
4
|
+
|
5
|
+
def initialize(name=nil)
|
6
|
+
@name = name
|
7
|
+
end
|
8
|
+
|
9
|
+
def add(gem, version)
|
10
|
+
self[gem] = version
|
11
|
+
end
|
12
|
+
|
13
|
+
def version(gem)
|
14
|
+
self.keys.each do |key|
|
15
|
+
case key
|
16
|
+
when String
|
17
|
+
return self[key] if gem == key
|
18
|
+
when Regexp
|
19
|
+
return self[key] if gem =~ key
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def gems
|
27
|
+
self.keys
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Ginger::Scenario do
|
4
|
+
it "should allow for multiple gem/version pairs" do
|
5
|
+
scenario = Ginger::Scenario.new
|
6
|
+
scenario.add "thinking_sphinx", "1.0"
|
7
|
+
scenario.add "riddle", "0.9.8"
|
8
|
+
|
9
|
+
scenario.gems.should include("thinking_sphinx")
|
10
|
+
scenario.gems.should include("riddle")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to be used as a hash" do
|
14
|
+
scenario = Ginger::Scenario.new
|
15
|
+
scenario["thinking_sphinx"] = "1.0"
|
16
|
+
scenario["riddle"] = "0.9.8"
|
17
|
+
|
18
|
+
scenario.gems.should include("thinking_sphinx")
|
19
|
+
scenario.gems.should include("riddle")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow gem names to be regular expressions" do
|
23
|
+
scenario = Ginger::Scenario.new
|
24
|
+
scenario.add /^active_?record$/, "2.1.0"
|
25
|
+
|
26
|
+
scenario.gems.first.should be_kind_of(Regexp)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return the appropriate version for a given gem" do
|
30
|
+
scenario = Ginger::Scenario.new
|
31
|
+
scenario.add "riddle", "0.9.8"
|
32
|
+
|
33
|
+
scenario.version("riddle").should == "0.9.8"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should use regular expressions to figure out matching version" do
|
37
|
+
scenario = Ginger::Scenario.new
|
38
|
+
scenario[/^active_?record$/] = "2.1.0"
|
39
|
+
|
40
|
+
scenario.version("activerecord").should == "2.1.0"
|
41
|
+
scenario.version("active_record").should == "2.1.0"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return nil if no matching gem" do
|
45
|
+
scenario = Ginger::Scenario.new
|
46
|
+
scenario.add "riddle", "0.9.8"
|
47
|
+
|
48
|
+
scenario.version("thinking_sphinx").should be_nil
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return name of scenario if defined" do
|
52
|
+
scenario = Ginger::Scenario.new('Thinking Sphinx')
|
53
|
+
scenario.add "riddle", "0.9.8"
|
54
|
+
|
55
|
+
scenario.name.should == "Thinking Sphinx"
|
56
|
+
end
|
57
|
+
end
|
data/spec/ginger_spec.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "Ginger" do
|
4
|
+
it "should add scenarios to the Configuration instance" do
|
5
|
+
Ginger.configure do |config|
|
6
|
+
scenario = Ginger::Scenario.new
|
7
|
+
scenario["riddle"] = "0.9.8"
|
8
|
+
|
9
|
+
config.scenarios << scenario
|
10
|
+
end
|
11
|
+
|
12
|
+
Ginger::Configuration.instance.scenarios.length.should == 1
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ginger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pat Allan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-19 00:00:00 +02:00
|
13
|
+
default_executable: ginger
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Run specs/tests multiple times through different gem versions.
|
17
|
+
email: pat@freelancing-gods.com
|
18
|
+
executables:
|
19
|
+
- ginger
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/ginger/configuration.rb
|
26
|
+
- lib/ginger/kernel.rb
|
27
|
+
- lib/ginger/scenario.rb
|
28
|
+
- lib/ginger.rb
|
29
|
+
- LICENCE
|
30
|
+
- README.textile
|
31
|
+
- spec/ginger/configuration_spec.rb
|
32
|
+
- spec/ginger/kernel_spec.rb
|
33
|
+
- spec/ginger/scenario_spec.rb
|
34
|
+
- spec/ginger_spec.rb
|
35
|
+
- bin/ginger
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/freelancing_god/ginger/tree
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --title
|
43
|
+
- Ginger
|
44
|
+
- --line-numbers
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project: ginger
|
62
|
+
rubygems_version: 1.3.5
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: Run specs/tests multiple times through different gem versions.
|
66
|
+
test_files:
|
67
|
+
- spec/ginger/configuration_spec.rb
|
68
|
+
- spec/ginger/kernel_spec.rb
|
69
|
+
- spec/ginger/scenario_spec.rb
|
70
|
+
- spec/ginger_spec.rb
|