rocksteady 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.8.0. Initial release. Basic functionality and tests.
data/Manifest ADDED
@@ -0,0 +1,13 @@
1
+ CHANGELOG
2
+ lib/rocksteady/corpus.rb
3
+ lib/rocksteady/helpers.rb
4
+ lib/rocksteady/output.rb
5
+ lib/rocksteady/scenario.rb
6
+ lib/rocksteady/session.rb
7
+ lib/rocksteady/tasks.rb
8
+ lib/rocksteady/version.rb
9
+ lib/rocksteady.rb
10
+ Manifest
11
+ Rakefile
12
+ README.rdoc
13
+ test/rocksteady_test.rb
data/README.rdoc ADDED
@@ -0,0 +1,143 @@
1
+ = Rocksteady
2
+
3
+ Often you need to test bits of code you write with bits of code other people write, across varying revisions. This is tedious, requiring a lot of custom work and infrastructure, so you probably don't do it enough. I know I don't, and it's a bad habit.
4
+
5
+ Rocksteady is meant to ease the process of switching out different versions of inter-dependent code, providing you with a simple _scenario_ metaphor to write build and test code within. It's test framework agnostic (it just uses exit codes), and extremely flexible.
6
+
7
+ Below you can read an example of testing different versions of Rails against different versions of a plugin; more in-depth examples can be found on the wiki (http://github.com/bruce/rocksteady/wikis/examples).
8
+
9
+ <i>Please let me know how you're using Rocksteady; it's nice to have feedback</i>.
10
+
11
+ Bruce Williams (http://codefluency.com)
12
+ http://github.com/bruce
13
+
14
+
15
+ == Installation
16
+
17
+ Get it from RubyForge (once released):
18
+ sudo gem install rocksteady
19
+
20
+ === Dependencies
21
+
22
+ * rake
23
+ sudo gem install rake
24
+ * ruport
25
+ sudo gem install ruport
26
+ * mojombo-grit >= 0.8.0
27
+ sudo gem install mojombo-grit -s http://gems.github.com
28
+ * (git in your PATH)
29
+
30
+ == Defining Scenarios
31
+
32
+ Create a new directory, and toss a <tt>Rakefile</tt> in it. Make it look like this:
33
+
34
+ require 'rubygems'
35
+ require 'rocksteady'
36
+
37
+ Now, point it at the git repos that are holding the code you'd like to test. You could <tt>clone</tt> the repos somewhere in this directory, if you'd like. For this example, we'll be testing a Rails plugin we've written against various versions of Rails, so it like look something like this (assuming we cloned bare <tt>.git</tt> repos into the current directory)
38
+
39
+ repos 'rails.git', 'our_plugin.git'
40
+
41
+ Okay, now let just create a single scenario. In general, a scenario will be some set of configuration you'd like to test. For this example we won't be doing anything fancy (just a simple drop in <tt>vendor/plugins</tt>) so it might look like this:
42
+
43
+ scenario "Installed in vendor/plugins" do
44
+ generate_rails_app
45
+ install_plugin
46
+ verify_loads_environment
47
+ end
48
+
49
+ You see 3 things need to happen in the scenario; we've broken these out for clarity and just define them underneath:
50
+
51
+ First, let's generate a fresh Rails app for testing with:
52
+
53
+ def generate_rails_app
54
+ ruby "#{rails_path}/railties/bin/rails rails_app"
55
+ end
56
+
57
+ A few notes on what you see above:
58
+
59
+ 0. <tt>ruby</tt> is simply a <tt>rake</tt> convenience method that calls out to a new <tt>ruby</tt> interpreter
60
+ 0. <tt>rails_path</tt> is the absolute path to a fresh clone of the <tt>rails.git</tt> repo we defined at the beginning of the file, checked-out to the reference point we're currently checking (more on how that's set later). <tt>*_path</tt> convenience methods are generated for all the repos you've defined; you'll see the other one in <tt>install_plugin</tt>.
61
+ 0. We're calling out to the <tt>rails</tt> executable in the checked-out source directly so we can generate an accurate skeleton app for that version. The <tt>rails_app</tt> argument is just the name of the directory where it will be generated.
62
+
63
+ It's worth noting that when scenarios are being run, the current working directory is changed for you automatically; right now you're actually sitting in <tt>build/<timestamp>/scenarios/installed_in_vendor_plugins</tt>, where <tt>rails_app</tt> will be generated as a subdirectory.
64
+
65
+ Let's install the plugin now:
66
+
67
+ def install_plugin
68
+ cp_r our_plugin_path, 'rails_app/vendor/plugins'
69
+ end
70
+
71
+ 0. <tt>cp_r</tt> is another <tt>rake</tt> convenience method that does a recursive copy.
72
+ 0. <tt>our_plugin_path</tt> is the <tt>*_path</tt> method generated automatically for our plugin repo.
73
+
74
+ So, that was simple; for this quick example we just copy the plugin directly in.
75
+
76
+ Now let's do something that just verifies the Rails app code will load successfully across the standard environments, just by printing the Rails version from <tt>script/runner</tt>:
77
+
78
+ def verify_loads_environment
79
+ Dir.chdir 'rails_app' do
80
+ %w(test development production).each do |env|
81
+ ENV['RAILS_ENV'] = env
82
+ ruby "script/runner 'p Rails::VERSION'"
83
+ end
84
+ end
85
+ end
86
+
87
+ The great thing about the convenience methods that <tt>rake</tt> provides (eg, <tt>ruby</tt>, <tt>sh</tt>, <tt>cp_r</tt>, etc) is that the raise an exception if the system call they make returns a bad exit code; the scenario automatically catches them and assigns a _failure_ to the scenario. If you're not using these convenience methods and need to assign a failure, you can raise an exception manually to get the same result.
88
+
89
+ == Running against arbitrary references
90
+
91
+ Here are some examples on how we could run the scenario, with plain English explanations:
92
+
93
+ Run all scenarios, with all repos set to <tt>master</tt>:
94
+
95
+ $ rake rocksteady
96
+
97
+ Run just the first scenario (you can use <tt>rake -T</tt> to see them all), with all repos set to <tt>master</tt>:
98
+
99
+ $ rake rocksteady:scenario:1
100
+
101
+ The same, but setting <tt>rails</tt> to <tt>v2.0.2</tt>:
102
+
103
+ $ rake rocksteady:scenario:1 REFS=rails:v2.0.2
104
+
105
+ and now with <tt>our_plugin</tt> set to the <tt>experimental</tt> branch:
106
+
107
+ $ rake rocksteady:scenario:1 REFS=rails:v2.0.2,our_plugin:experimental
108
+
109
+ You can also use full references:
110
+
111
+ $ rake rocksteady:scenario:1 REFS=rails:refs/tags/v2.0.2,our_plugin:refs/heads/experimental
112
+
113
+ == Output
114
+
115
+ Currently the output is a simple text-based table. You'll need to refer to the output in the terminal to find _where_ your failures occur. More granular, labelled scenario-level logging is on the roadmap.
116
+
117
+ == License
118
+
119
+ Copyright (c) 2008 Bruce R. Williams
120
+
121
+ Permission is hereby granted, free of charge, to any person
122
+ obtaining a copy of this software and associated documentation
123
+ files (the "Software"), to deal in the Software without
124
+ restriction, including without limitation the rights to use,
125
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
126
+ copies of the Software, and to permit persons to whom the
127
+ Software is furnished to do so, subject to the following
128
+ conditions:
129
+
130
+ The above copyright notice and this permission notice shall be
131
+ included in all copies or substantial portions of the Software.
132
+
133
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
134
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
135
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
136
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
137
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
138
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
139
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
140
+ OTHER DEALINGS IN THE SOFTWARE.
141
+
142
+
143
+
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'echoe'
3
+
4
+ require File.dirname(__FILE__) << "/lib/rocksteady/version"
5
+
6
+ Echoe.new 'rocksteady' do |p|
7
+ p.version = Rocksteady::Version::STRING
8
+ p.author = "Bruce Williams"
9
+ p.email = 'bruce@codefluency.com'
10
+ p.project = 'codefluency'
11
+ p.summary = "Run arbitrary scenarios across disparate sets of git repo revisions"
12
+ p.url = "http://github.com/bruce/rocksteady"
13
+ p.dependencies = ['rake', ['mojombo-grit', '>= 0.8.0'], 'ruport']
14
+ p.include_rakefile = true
15
+ end
16
+
data/lib/rocksteady.rb ADDED
@@ -0,0 +1,5 @@
1
+ Dir[File.dirname(__FILE__) << "/rocksteady/**/*.rb"].each do |file|
2
+ require file
3
+ end
4
+
5
+ include Rocksteady::Helpers
@@ -0,0 +1,83 @@
1
+ require 'rubygems'
2
+ require 'mojombo-grit'
3
+
4
+ module Rocksteady
5
+
6
+ class Corpus
7
+
8
+ attr_reader :app
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ # SCENARIOS
14
+
15
+ def scenarios
16
+ @scenarios ||= []
17
+ end
18
+
19
+ def add_scenario(*args, &block)
20
+ scenario = Scenario.new(self, *args, &block)
21
+ scenarios << scenario
22
+ scenario
23
+ end
24
+
25
+ # REPOS
26
+
27
+ def repos
28
+ @repos ||= {}
29
+ end
30
+
31
+ def add_repos(*paths)
32
+ paths.each do |path|
33
+ repo = Grit::Repo.new(path)
34
+ repos[name_of(repo)] = repo
35
+ end
36
+ end
37
+
38
+ # REFS
39
+
40
+ def refs
41
+ @refs ||= {}
42
+ end
43
+
44
+ def default_refs!
45
+ repos.each_key do |repo_name|
46
+ refs[repo_name] ||= 'master'
47
+ end
48
+ end
49
+
50
+ def verify_refs!
51
+ refs.each do |repo_name, ref|
52
+ repo = repos[repo_name]
53
+ unless repo.log(ref).any?
54
+ raise ArgumentError, "Could not find #{repo_name} ref `#{ref}'"
55
+ end
56
+ end
57
+ end
58
+
59
+ def session
60
+ @session ||= Session.new(self)
61
+ end
62
+
63
+ def schedule
64
+ @schedule ||= []
65
+ end
66
+
67
+ #######
68
+ private
69
+ #######
70
+
71
+ # Extract the canonical name of the git repository
72
+ def name_of(repo)
73
+ case repo.path
74
+ when /#{File::SEPARATOR}\.git$/
75
+ File.basename(File.dirname(repo.path))
76
+ else
77
+ File.basename(repo.path, '.git')
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,38 @@
1
+ module Rocksteady
2
+
3
+ module Helpers
4
+
5
+ def corpus
6
+ @corpus ||= Rocksteady::Corpus.new(self)
7
+ end
8
+
9
+ def repos(*paths)
10
+ corpus.add_repos(*paths.flatten)
11
+ end
12
+
13
+ def scenario(opts, &block)
14
+ title, deps = if opts.is_a?(Hash)
15
+ [opts.keys.first, Array(opts.values.first)]
16
+ else
17
+ [opts, []]
18
+ end
19
+ scenario = corpus.add_scenario(title, &block)
20
+ generate_scenario_task scenario, deps
21
+ end
22
+
23
+ #######
24
+ private
25
+ #######
26
+
27
+ # Create the scenario task
28
+ def generate_scenario_task(scenario, deps)
29
+ deps.unshift 'rocksteady:refs:check'
30
+ desc scenario.title
31
+ task "rocksteady:scenario:#{corpus.scenarios.size}" => deps do |t|
32
+ scenario.schedule!
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'ruport'
3
+
4
+ # FIXME: This is a total hackjob.
5
+ # TODO: Support other output types
6
+ at_exit do
7
+ corpus.session.run! do |scenarios|
8
+ table = Ruport::Data::Table.new :column_names => ['Scenario', corpus.session.title] do |t|
9
+ scenarios.sort_by { |s| s.title }.each do |scenario|
10
+ t << [scenario.title, scenario.result.is_a?(Exception) ? "FAIL" : 'PASS']
11
+ end
12
+ end
13
+ puts table
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ module Rocksteady
2
+
3
+ class Scenario
4
+
5
+ attr_reader :corpus, :title, :operation
6
+ def initialize(corpus, title, &operation)
7
+ @corpus = corpus
8
+ @title = title
9
+ @operation = operation
10
+ end
11
+
12
+ def schedule!
13
+ corpus.schedule << self
14
+ end
15
+
16
+ def name
17
+ @name ||= title.gsub(/[^[:alnum:]]+/, '_').downcase
18
+ end
19
+
20
+ def result
21
+ @result ||= begin
22
+ operation.call
23
+ rescue Exception => e
24
+ e
25
+ end
26
+ end
27
+ alias :run! :result
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,79 @@
1
+ module Rocksteady
2
+
3
+ class Session
4
+
5
+ attr_reader :corpus
6
+ def initialize(corpus)
7
+ @corpus = corpus
8
+ end
9
+
10
+ def title
11
+ @title ||= corpus.refs.map { |k, v| "#{k} `#{v}'" }.join(' vs ')
12
+ end
13
+
14
+ def timestamp
15
+ @timestamp ||= Time.now.to_i
16
+ end
17
+
18
+ def run!
19
+ return if corpus.schedule.empty?
20
+ create_timestamp_directory
21
+ clone_repos
22
+ corpus.schedule.each do |scenario|
23
+ focus_on scenario do
24
+ scenario.run!
25
+ end
26
+ end
27
+ yield corpus.schedule
28
+ end
29
+
30
+ #######
31
+ private
32
+ #######
33
+
34
+ def timestamp_directory
35
+ File.expand_path("build/#{timestamp}")
36
+ end
37
+
38
+ def create_timestamp_directory
39
+ mkdir_p timestamp_directory
40
+ end
41
+
42
+ # FIXME: Cleanup
43
+ def clone_repos
44
+ Dir.chdir timestamp_directory do
45
+ mkdir_p 'repos'
46
+ corpus.refs.each do |repo_name, ref|
47
+ repo = corpus.repos[repo_name]
48
+ path = File.expand_path("repos/#{repo_name}")
49
+ (class << corpus.app; self; end).send(:define_method, "#{repo_name}_path") { path }
50
+ sh "git clone -q '#{repo.path}' '#{path}'"
51
+ Dir.chdir path do
52
+ sh "git checkout -q '#{ref}'"
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def focus_on(scenario, &block)
59
+ directory = directory_for(scenario)
60
+ (class << corpus.app; self; end).send(:define_method, "scenario_log") { logfile_for(scenario) }
61
+ mkdir_p directory
62
+ Dir.chdir(directory, &block)
63
+ end
64
+
65
+ #######
66
+ private
67
+ #######
68
+
69
+ def logfile_for(scenario)
70
+ File.join(directory_for(scenario), 'scenario.log')
71
+ end
72
+
73
+ def directory_for(scenario)
74
+ File.join("#{timestamp_directory}/scenarios/#{scenario.name}")
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,71 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ namespace :rocksteady do
5
+
6
+ desc "Remove build files"
7
+ task :clean do
8
+ rm_rf 'build' rescue nil
9
+ end
10
+
11
+ namespace :refs do
12
+
13
+ task :check => :default do
14
+ begin
15
+ corpus.verify_refs!
16
+ rescue ArgumentError => e
17
+ abort e.message
18
+ end
19
+ end
20
+
21
+ task :default => :add_from_env do
22
+ corpus.default_refs!
23
+ end
24
+
25
+ task :add_from_env => 'rocksteady:repos:check' do
26
+ if ENV['REFS']
27
+ pairs = ENV['REFS'].split(',').map
28
+ pairs.each do |pair|
29
+ repo_name, ref = pair.split(':')
30
+ ref ||= 'master'
31
+ if (repo = corpus.repos[repo_name])
32
+ corpus.refs[repo_name] = ref
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ namespace :repos do
41
+
42
+ desc "Show configured source repositories"
43
+ task :show => :check do
44
+ corpus.repos.sort_by { |k, v| k }.each do |name, repo|
45
+ puts "#{name}: #{repo.path}"
46
+ end
47
+ end
48
+
49
+ task :check => :add_from_env do
50
+ unless corpus.repos.any?
51
+ abort "Could not find repositories.\nSet ENV['REPOS'] or use `repos' method in Rakefile to set repo paths."
52
+ end
53
+ end
54
+
55
+ task :add_from_env do
56
+ if ENV['REPOS']
57
+ paths = ENV['REPOS'].split(',')
58
+ corpus.add_repos(*paths)
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ desc "Run all corpus scenarios"
67
+ task :rocksteady => 'rocksteady:refs:check' do
68
+ corpus.scenarios.each do |scenario|
69
+ scenario.schedule!
70
+ end
71
+ end
@@ -0,0 +1,78 @@
1
+ # (The MIT License)
2
+ #
3
+ # Copyright (c) 2008 Jamis Buck <jamis@37signals.com>,
4
+ # with modifications by Bruce Williams <bruce@codefluency.com>
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # 'Software'), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ module Rocksteady
25
+
26
+ # A class for describing the current version of a library. The version
27
+ # consists of three parts: the +major+ number, the +minor+ number, and the
28
+ # +tiny+ (or +patch+) number.
29
+ class Version
30
+
31
+ include Comparable
32
+
33
+ # A convenience method for instantiating a new Version instance with the
34
+ # given +major+, +minor+, and +tiny+ components.
35
+ def self.[](major, minor, tiny)
36
+ new(major, minor, tiny)
37
+ end
38
+
39
+ attr_reader :major, :minor, :tiny
40
+
41
+ # Create a new Version object with the given components.
42
+ def initialize(major, minor, tiny)
43
+ @major, @minor, @tiny = major, minor, tiny
44
+ end
45
+
46
+ # Compare this version to the given +version+ object.
47
+ def <=>(version)
48
+ to_i <=> version.to_i
49
+ end
50
+
51
+ # Converts this version object to a string, where each of the three
52
+ # version components are joined by the '.' character. E.g., 2.0.0.
53
+ def to_s
54
+ @to_s ||= [@major, @minor, @tiny].join(".")
55
+ end
56
+
57
+ # Converts this version to a canonical integer that may be compared
58
+ # against other version objects.
59
+ def to_i
60
+ @to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
61
+ end
62
+
63
+ def to_a
64
+ [@major, @minor, @tiny]
65
+ end
66
+
67
+ MAJOR = 0
68
+ MINOR = 8
69
+ TINY = 0
70
+
71
+ # The current version as a Version instance
72
+ CURRENT = new(MAJOR, MINOR, TINY)
73
+ # The current version as a String
74
+ STRING = CURRENT.to_s
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,50 @@
1
+
2
+ # Gem::Specification for Rocksteady-0.8.0
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{rocksteady}
7
+ s.version = "0.8.0"
8
+
9
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.authors = ["Bruce Williams"]
13
+ s.date = %q{2008-06-07}
14
+ s.description = %q{Run arbitrary scenarios across disparate sets of git repo revisions}
15
+ s.email = %q{bruce@codefluency.com}
16
+ s.extra_rdoc_files = ["CHANGELOG", "lib/rocksteady/corpus.rb", "lib/rocksteady/helpers.rb", "lib/rocksteady/output.rb", "lib/rocksteady/scenario.rb", "lib/rocksteady/session.rb", "lib/rocksteady/tasks.rb", "lib/rocksteady/version.rb", "lib/rocksteady.rb", "README.rdoc"]
17
+ s.files = ["CHANGELOG", "lib/rocksteady/corpus.rb", "lib/rocksteady/helpers.rb", "lib/rocksteady/output.rb", "lib/rocksteady/scenario.rb", "lib/rocksteady/session.rb", "lib/rocksteady/tasks.rb", "lib/rocksteady/version.rb", "lib/rocksteady.rb", "Manifest", "Rakefile", "README.rdoc", "test/rocksteady_test.rb", "rocksteady.gemspec"]
18
+ s.has_rdoc = true
19
+ s.homepage = %q{http://github.com/bruce/rocksteady}
20
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rocksteady", "--main", "README.rdoc"]
21
+ s.require_paths = ["lib"]
22
+ s.rubyforge_project = %q{codefluency}
23
+ s.rubygems_version = %q{1.1.1}
24
+ s.summary = %q{Run arbitrary scenarios across disparate sets of git repo revisions}
25
+ s.test_files = ["test/rocksteady_test.rb"]
26
+
27
+ s.add_dependency(%q<rake>, [">= 0"])
28
+ s.add_dependency(%q<mojombo-grit>, [">= 0.8.0"])
29
+ s.add_dependency(%q<ruport>, [">= 0"])
30
+ end
31
+
32
+
33
+ # # Original Rakefile source (requires the Echoe gem):
34
+ #
35
+ # require 'rubygems'
36
+ # require 'echoe'
37
+ #
38
+ # require File.dirname(__FILE__) << "/lib/rocksteady/version"
39
+ #
40
+ # Echoe.new 'rocksteady' do |p|
41
+ # p.version = Rocksteady::Version::STRING
42
+ # p.author = "Bruce Williams"
43
+ # p.email = 'bruce@codefluency.com'
44
+ # p.project = 'codefluency'
45
+ # p.summary = "Run arbitrary scenarios across disparate sets of git repo revisions"
46
+ # p.url = "http://github.com/bruce/rocksteady"
47
+ # p.dependencies = ['rake', ['mojombo-grit', '>= 0.8.0'], 'ruport']
48
+ # p.include_rakefile = true
49
+ # end
50
+ #
@@ -0,0 +1,95 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'Shoulda'
4
+
5
+ $:.unshift(File.dirname(__FILE__) << "/../lib")
6
+ require 'rocksteady/corpus'
7
+ require 'rocksteady/helpers'
8
+
9
+ class RSTarget
10
+ include Rocksteady::Helpers
11
+ end
12
+
13
+ class RocksteadyTest < Test::Unit::TestCase
14
+
15
+ context "Rocksteady" do
16
+
17
+ tmp_dir = File.dirname(__FILE__) << "/tmp"
18
+
19
+ repo_dirs = (1..3).to_a.map do |n|
20
+ "#{tmp_dir}/repo#{n}"
21
+ end
22
+
23
+ setup do
24
+ @r = RSTarget.new
25
+ repo_dirs.each do |dir|
26
+ FileUtils.mkdir_p dir
27
+ Dir.chdir(dir) do
28
+ system "git init > /dev/null 2>&1"
29
+ File.open('stub', 'w') { |f| f.puts 'nothing' }
30
+ system 'git add . > /dev/null 2>&1'
31
+ system 'git commit -m "stub" > /dev/null 2>&1'
32
+ end
33
+ end
34
+ end
35
+
36
+ teardown do
37
+ FileUtils.rm_rf tmp_dir
38
+ end
39
+
40
+ populate = lambda { @r.corpus.add_repos(*Dir["#{tmp_dir}/*"]) }
41
+
42
+ context "Helpers" do
43
+ should "have corpus accessor added as a helper" do
44
+ assert @r.respond_to?(:corpus)
45
+ end
46
+ end
47
+
48
+ context "Core" do
49
+
50
+ should "start without repos" do
51
+ assert @r.corpus.repos.empty?
52
+ end
53
+
54
+ should "start without refs" do
55
+ assert @r.corpus.refs.empty?
56
+ end
57
+
58
+ should "add repos by paths" do
59
+ instance_eval(&populate)
60
+ assert @r.corpus.repos.size == repo_dirs.size
61
+ assert @r.corpus.repos.keys.all? { |r| r =~ /^repo\d+$/ }
62
+ assert @r.corpus.repos.values.all? { |r| r.is_a?(Grit::Repo) }
63
+ assert @r.corpus.refs.empty?
64
+ end
65
+
66
+ should "default refs for existing repos without explicit ref" do
67
+ instance_eval(&populate)
68
+ assert @r.corpus.refs.empty?
69
+ @r.corpus.refs['repo1'] = explicit = 'explicit-ref-for-this-repo'
70
+ @r.corpus.default_refs!
71
+ masters, explicits = @r.corpus.refs.partition { |k, v| v == 'master' }
72
+ assert_equal 2, masters.size
73
+ assert_equal 1, explicits.size
74
+ end
75
+
76
+ should "allow verification of refs" do
77
+ instance_eval(&populate)
78
+ assert @r.corpus.refs.empty?
79
+ @r.corpus.default_refs!
80
+ assert_nothing_raised do
81
+ @r.corpus.verify_refs!
82
+ end
83
+ @r.corpus.refs.clear
84
+ @r.corpus.refs['repo1'] = 'this-does-not-exist'
85
+ @r.corpus.default_refs!
86
+ assert_raises ArgumentError do
87
+ @r.corpus.verify_refs!
88
+ end
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rocksteady
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.0
5
+ platform: ruby
6
+ authors:
7
+ - Bruce Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-07 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: mojombo-grit
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 0.8.0
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: ruport
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ description: Run arbitrary scenarios across disparate sets of git repo revisions
43
+ email: bruce@codefluency.com
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ extra_rdoc_files:
49
+ - CHANGELOG
50
+ - lib/rocksteady/corpus.rb
51
+ - lib/rocksteady/helpers.rb
52
+ - lib/rocksteady/output.rb
53
+ - lib/rocksteady/scenario.rb
54
+ - lib/rocksteady/session.rb
55
+ - lib/rocksteady/tasks.rb
56
+ - lib/rocksteady/version.rb
57
+ - lib/rocksteady.rb
58
+ - README.rdoc
59
+ files:
60
+ - CHANGELOG
61
+ - lib/rocksteady/corpus.rb
62
+ - lib/rocksteady/helpers.rb
63
+ - lib/rocksteady/output.rb
64
+ - lib/rocksteady/scenario.rb
65
+ - lib/rocksteady/session.rb
66
+ - lib/rocksteady/tasks.rb
67
+ - lib/rocksteady/version.rb
68
+ - lib/rocksteady.rb
69
+ - Manifest
70
+ - Rakefile
71
+ - README.rdoc
72
+ - test/rocksteady_test.rb
73
+ - rocksteady.gemspec
74
+ has_rdoc: true
75
+ homepage: http://github.com/bruce/rocksteady
76
+ post_install_message:
77
+ rdoc_options:
78
+ - --line-numbers
79
+ - --inline-source
80
+ - --title
81
+ - Rocksteady
82
+ - --main
83
+ - README.rdoc
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ version:
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: "0"
97
+ version:
98
+ requirements: []
99
+
100
+ rubyforge_project: codefluency
101
+ rubygems_version: 1.1.1
102
+ signing_key:
103
+ specification_version: 2
104
+ summary: Run arbitrary scenarios across disparate sets of git repo revisions
105
+ test_files:
106
+ - test/rocksteady_test.rb