Permalink
Browse files

Vendoring ginger and adding rake ginger task

  • Loading branch information...
1 parent 9f46de7 commit b1ece683def91162a71bb9ddc191ce1f911b3c25 @qrush qrush committed Mar 18, 2009
View
@@ -20,3 +20,11 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end
+
+desc 'Run ginger tests'
+task :ginger do
+ $LOAD_PATH << File.join(*%w[vendor ginger lib])
+ ARGV.clear
+ ARGV << 'test'
+ load File.join(*%w[vendor ginger bin ginger])
+end
View
@@ -3,6 +3,8 @@
require 'mocha'
gem 'thoughtbot-shoulda', ">= 2.0.0"
require 'shoulda'
+
+$LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. vendor ginger lib])
require 'ginger'
require 'action_controller'
View
@@ -0,0 +1 @@
+ginger*.gem
View
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Pat Allan
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,50 @@
+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.
+
+To get it all working, you need to do four things. The first is, of course, to install this gem.
+
+<pre><code>sudo gem install freelancing-god-ginger --source=http://gems.github.com</code></pre>
+
+Next, add the following line of code to your @spec_helper.rb@ file (or equivalent):
+
+<pre><code>require 'ginger'</code></pre>
+
+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.
+
+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.
+
+<pre><code>require 'ginger'
+
+Ginger.configure do |config|
+ config.aliases["active_record"] = "activerecord"
+
+ ar_1_2_6 = Ginger::Scenario.new
+ ar_1_2_6[/^active_?record$/] = "1.15.6"
+
+ ar_2_0_2 = Ginger::Scenario.new
+ ar_2_0_2[/^active_?record$/] = "2.0.2"
+
+ ar_2_1_1 = Ginger::Scenario.new
+ ar_2_1_1[/^active_?record$/] = "2.1.1"
+
+ config.scenarios << ar_1_2_6 << ar_2_0_2 << ar_2_1_1
+end</code></pre>
+
+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).
+
+You can have multiple gems set in each scenario - and you don't have to use regular expressions, you can just use straight strings.
+
+<pre><code>sphinx_scenario = Ginger::Scenario.new
+sphinx_scenario["riddle"] = "0.9.8"
+sphinx_scenario["thinking_sphinx"] = "0.9.8"</code></pre>
+
+Don't forget to add them to @config@'s scenarios collection, else they're not saved anywhere.
+
+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:
+
+<pre><code>ginger spec
+ginger test
+ginger spec:unit</code></pre>
+
+h2. Contributors
+
+* "Adam Meehan":http://duckpunching.com/
View
@@ -0,0 +1,57 @@
+require 'rubygems'
+require 'spec'
+require 'rake/rdoctask'
+require 'spec/rake/spectask'
+require 'rake/gempackagetask'
+
+$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
+
+require 'ginger'
+
+spec = Gem::Specification.new do |s|
+ s.name = "ginger"
+ s.version = Ginger::Version::String
+ s.summary = "Run specs/tests multiple times through different gem versions."
+ s.description = "Run specs/tests multiple times through different gem versions."
+ s.author = "Pat Allan"
+ s.email = "pat@freelancing-gods.com"
+ s.homepage = "http://github.com/freelancing_god/ginger/tree"
+ s.has_rdoc = true
+ s.rdoc_options << "--title" << "Ginger" <<
+ "--line-numbers"
+ s.rubyforge_project = "ginger"
+ s.test_files = FileList["spec/**/*_spec.rb"]
+ s.files = FileList[
+ "lib/**/*.rb",
+ "LICENCE",
+ "README.textile"
+ ]
+ s.executables = ["ginger"]
+end
+
+Rake::GemPackageTask.new(spec) do |p|
+ p.gem_spec = spec
+ p.need_tar = true
+ p.need_zip = true
+end
+
+desc "Generate ginger.gemspec file"
+task :gemspec do
+ File.open('ginger.gemspec', 'w') { |f|
+ f.write spec.to_ruby
+ }
+end
+
+desc "Run the specs under spec"
+Spec::Rake::SpecTask.new do |t|
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.spec_opts << "-c"
+end
+
+desc "Generate RCov reports"
+Spec::Rake::SpecTask.new(:rcov) do |t|
+ t.libs << 'lib'
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.rcov = true
+ t.rcov_opts = ['--exclude', 'spec', '--exclude', 'gems']
+end
View
@@ -0,0 +1,42 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+require 'ginger'
+require 'rake'
+
+if ARGV.length == 0
+ puts <<-USAGE
+ginger #{Ginger::Version::String}
+Use ginger to run specs for each scenario defined. Scenarios must be set out in
+a file called ginger_scenarios.rb wherever this tool is run. Once they're
+defined, then you can run this tool and provide the rake task that would
+normally be called.
+
+Examples:
+ ginger spec
+ ginger test
+ ginger spec:models
+USAGE
+ exit 0
+end
+
+file_path = File.join Dir.pwd, ".ginger"
+
+File.delete(file_path) if File.exists?(file_path)
+
+scenarios = Ginger::Configuration.instance.scenarios
+puts "No Ginger Scenarios defined" if scenarios.empty?
+
+scenarios.each_with_index do |scenario, index|
+ puts <<-SCENARIO
+
+-------------------
+Ginger Scenario #{index+1}
+-------------------
+ SCENARIO
+
+ File.open('.ginger', 'w') { |f| f.write index.to_s }
+ system("rake #{ARGV.join(" ")}")
+end
+
+File.delete(file_path) if File.exists?(file_path)
@@ -0,0 +1,33 @@
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{ginger}
+ s.version = "1.0.0"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["Pat Allan"]
+ s.date = %q{2008-10-11}
+ s.default_executable = %q{ginger}
+ s.description = %q{Run specs/tests multiple times through different gem versions.}
+ s.email = %q{pat@freelancing-gods.com}
+ s.executables = ["ginger"]
+ s.files = ["lib/ginger/configuration.rb", "lib/ginger/kernel.rb", "lib/ginger/scenario.rb", "lib/ginger.rb", "LICENCE", "README.textile", "spec/ginger/configuration_spec.rb", "spec/ginger/kernel_spec.rb", "spec/ginger/scenario_spec.rb", "spec/ginger_spec.rb", "bin/ginger"]
+ s.has_rdoc = true
+ s.homepage = %q{http://github.com/freelancing_god/ginger/tree}
+ s.rdoc_options = ["--title", "Ginger", "--line-numbers"]
+ s.require_paths = ["lib"]
+ s.rubyforge_project = %q{ginger}
+ s.rubygems_version = %q{1.3.0}
+ s.summary = %q{Run specs/tests multiple times through different gem versions.}
+ s.test_files = ["spec/ginger/configuration_spec.rb", "spec/ginger/kernel_spec.rb", "spec/ginger/scenario_spec.rb", "spec/ginger_spec.rb"]
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 2
+
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+ else
+ end
+ else
+ end
+end
@@ -0,0 +1,21 @@
+require 'ginger/configuration'
+require 'ginger/scenario'
+require 'ginger/kernel'
+
+module Ginger
+ module Version
+ Major = 1
+ Minor = 0
+ Tiny = 0
+
+ String = [Major, Minor, Tiny].join('.')
+ end
+
+ def self.configure(&block)
+ yield Ginger::Configuration.instance
+ end
+end
+
+Kernel.send(:include, Ginger::Kernel)
+
+Ginger::Configuration.detect_scenario_file
@@ -0,0 +1,20 @@
+require 'singleton'
+
+module Ginger
+ class Configuration
+ include Singleton
+
+ attr_accessor :scenarios, :aliases
+
+ def initialize
+ @scenarios = []
+ @aliases = {}
+ end
+
+ def self.detect_scenario_file
+ ['.','spec','test'].each do |path|
+ require "#{path}/ginger_scenarios" and break if File.exists?("#{path}/ginger_scenarios.rb")
+ end
+ end
+ end
+end
@@ -0,0 +1,56 @@
+module Ginger
+ module Kernel
+ def self.included(base)
+ base.class_eval do
+ def require_with_ginger(req)
+ unless scenario = ginger_scenario
+ require_without_ginger(req)
+ return
+ end
+
+ if scenario.version(req)
+ gem ginger_gem_name(req)
+ end
+
+ require_without_ginger(req)
+ end
+
+ alias_method :require_without_ginger, :require
+ alias_method :require, :require_with_ginger
+
+ def gem_with_ginger(gem_name, *version_requirements)
+ unless scenario = ginger_scenario
+ gem_without_ginger(gem_name, *version_requirements)
+ return
+ end
+
+ if version_requirements.length == 0 &&
+ version = scenario.version(gem_name)
+ version_requirements << "= #{version}"
+ end
+
+ gem_without_ginger(gem_name, *version_requirements)
+ end
+
+ alias_method :gem_without_ginger, :gem
+ alias_method :gem, :gem_with_ginger
+
+ private
+
+ def ginger_scenario
+ return nil unless File.exists?(".ginger")
+
+ scenario = nil
+ File.open('.ginger') { |f| scenario = f.read }
+ return nil unless scenario
+
+ Ginger::Configuration.instance.scenarios[scenario.to_i]
+ end
+
+ def ginger_gem_name(gem_name)
+ Ginger::Configuration.instance.aliases[gem_name] || gem_name
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,24 @@
+module Ginger
+ class Scenario < Hash
+ def add(gem, version)
+ self[gem] = version
+ end
+
+ def version(gem)
+ self.keys.each do |key|
+ case key
+ when String
+ return self[key] if gem == key
+ when Regexp
+ return self[key] if gem =~ key
+ end
+ end
+
+ return nil
+ end
+
+ def gems
+ self.keys
+ end
+ end
+end
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe Ginger::Configuration do
+ it "should be a singleton class" do
+ Ginger::Configuration.should respond_to(:instance)
+ end
+end
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe "Ginger::Kernel" do
+ it "should description" do
+ #
+ end
+end
Oops, something went wrong.

0 comments on commit b1ece68

Please sign in to comment.