single_test 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,49 @@
1
+ Runs a single test/spec via rake.
2
+
3
+ USAGE
4
+ =====
5
+ As Rails plugin:
6
+ script/plugin install git://github.com/grosser/single_test.git
7
+
8
+ As Gem:
9
+ sudo gem install single_test
10
+
11
+ # in your Rakefile
12
+ require 'single_test'
13
+ SingleTest.load_tasks
14
+
15
+
16
+ ###Single test/spec
17
+ rake spec:user #run spec/model/user_spec.rb (searches for user*_spec.rb)
18
+ rake test:users_c #run test/functional/users_controller_test.rb
19
+ rake spec:admin/users_c #run spec/controllers/admin/users_controller_spec.rb
20
+ rake test:u*hel #run test/helpers/user_helper_test.rb (searches for u*hel*_test.rb)
21
+
22
+ ###Single test-case/example
23
+ rake spec:user:token #run the first spec in user_spec.rb that matches /token/
24
+ rake test:user:token #run all tests in user_test.rb that match /token/
25
+
26
+ ###Spec-server
27
+ rake spec:user X= #run test on spec_sever (if one is running...), very fast for quick failure pin-pointing
28
+
29
+ ###All one by one
30
+ rake spec:one_by_one #run each spec/test one by one, to find tests that fail when ran
31
+ rake test:one_by_one #on their own or produce strange output
32
+
33
+ ###For last mofified file
34
+ rake test:last
35
+ rake spec:last
36
+
37
+ TIPS
38
+ ====
39
+ - if `script/spec` is missing, if will use just `spec` for specs (which solves some issues)
40
+
41
+ TODO
42
+ ====
43
+ - make test:last more clever e.g. lib -> try spec + spec/lib
44
+
45
+ AUTHOR
46
+ ======
47
+ [Michael Grosser](http://pragmatig.wordpress.com)
48
+ grosser.michael@gmail.com
49
+ Hereby placed under public domain, do what you want, just do not hold me accountable...
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ task :default do |t|
2
+ options = "--colour"
3
+ files = FileList['spec/**/*_spec.rb'].map{|f| f.sub(%r{^spec/},'') }
4
+ exit system("cd spec && spec #{options} #{files}") ? 0 : 1
5
+ end
6
+
7
+ begin
8
+ require 'jeweler'
9
+ project_name = 'single_test'
10
+ Jeweler::Tasks.new do |gem|
11
+ gem.name = project_name
12
+ gem.summary = "Rake tasks to invoke single tests/specs with rakish syntax"
13
+ gem.email = "grosser.michael@gmail.com"
14
+ gem.homepage = "http://github.com/grosser/#{project_name}"
15
+ gem.authors = ["Michael Grosser"]
16
+ end
17
+
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
21
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,104 @@
1
+ require 'rake'
2
+
3
+ module SingleTest
4
+ extend self
5
+ CMD_LINE_MATCHER = /^(spec|test)\:.*(\:.*)?$/
6
+ SEARCH_ORDER = {
7
+ 'test'=> %w(unit functional integration *),
8
+ 'spec'=> %w(models controllers views helpers *),
9
+ }
10
+
11
+ def load_tasks
12
+ tasks = File.join(File.dirname(__FILE__), '..', 'tasks')
13
+ load File.join(tasks, 'single_test.rake')
14
+ end
15
+
16
+ def run_last(type)
17
+ path = "app"
18
+ last = last_modified_file(path,:ext=>'.rb')
19
+ test = last.sub('app/',"#{type}/").sub('.rb',"_#{type}.rb")
20
+ if File.exist?(test)
21
+ run_test(type, test)
22
+ else
23
+ puts "could not find #{test}"
24
+ end
25
+ end
26
+
27
+ def all_tests(type)
28
+ FileList["#{type}/**/*_#{type}.rb"].reject{|file|File.directory?(file)}
29
+ end
30
+
31
+ def run_one_by_one(type)
32
+ tests = all_tests(type)
33
+ puts "Running #{tests.size} #{type}s"
34
+ tests.sort.each do |file|
35
+ puts "Running #{file}"
36
+ run_test(type, file)
37
+ puts ''
38
+ end
39
+ end
40
+
41
+ def run_from_cli(call)
42
+ type, file, test_name = parse_cli(call)
43
+ file = find_test_file(type,file)
44
+ return unless file
45
+
46
+ #when spec, convert test_name regex to actual test_name
47
+ if type == 'spec' && test_name
48
+ test_name = find_example_in_spec(file, test_name) || test_name
49
+ end
50
+
51
+ #run the file
52
+ puts "running: #{file}"
53
+ ENV['RAILS_ENV'] = 'test' #current EVN['RAILS_ENV'] is 'development', and will also exist in all called commands
54
+ run_test(type, file, test_name)
55
+ end
56
+
57
+ # spec:user:blah --> [spec,user,blah]
58
+ def parse_cli(call)
59
+ raise "you should not have gotten here..." unless call =~ CMD_LINE_MATCHER
60
+ arguments = call.split(":",3)
61
+ [
62
+ arguments[0], #type
63
+ arguments[1], #file name
64
+ arguments[2].to_s.strip.empty? ? nil : arguments[2] #test name
65
+ ]
66
+ end
67
+
68
+ def find_test_file(type,file_name)
69
+ ["","**/"].each do |depth| # find in lower folders first
70
+ ['','*'].each do |exactness| # find exact matches first
71
+ SEARCH_ORDER[type].each do |folder|
72
+ base = "#{type}/#{folder}/#{depth}#{file_name}"
73
+ # without wildcard no search is performed -> ?rb
74
+ found = FileList["#{base}#{exactness}_#{type}?rb"].first
75
+ return found if found
76
+ end
77
+ end
78
+ end
79
+ nil
80
+ end
81
+
82
+ def find_example_in_spec(file, test_name)
83
+ File.readlines(file).each do |line|
84
+ return $2 if line =~ /.*it\s*(["'])(.*#{test_name}.*)\1\s*do/
85
+ end
86
+ nil
87
+ end
88
+
89
+ def run_test(type, file, test_name=nil)
90
+ case type.to_s
91
+ when 'test' then sh "ruby -Ilib:test #{file} -n /#{test_name}/"
92
+ when 'spec' then sh "export RAILS_ENV=test ; #{spec_executable} -O spec/spec.opts #{file}" + (test_name ? %Q( -e "#{test_name.sub('"',"\\\"")}") : '') + (ENV['X'] ? " -X" : "")
93
+ else raise "Unknown: #{type}"
94
+ end
95
+ end
96
+
97
+ def spec_executable
98
+ File.exist?("script/spec") ? "script/spec" : "spec"
99
+ end
100
+
101
+ def last_modified_file(dir, options={})
102
+ Dir["#{dir}/**/*#{options[:ext]}"].sort_by { |p| File.mtime(p) }.last
103
+ end
104
+ end
@@ -0,0 +1,48 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{single_test}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Grosser"]
12
+ s.date = %q{2009-12-13}
13
+ s.email = %q{grosser.michael@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "README.markdown"
16
+ ]
17
+ s.files = [
18
+ "README.markdown",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "lib/single_test.rb",
22
+ "single_test.gemspec",
23
+ "spec/example_finder_test.txt",
24
+ "spec/single_test_spec.rb",
25
+ "spec/spec_helper.rb",
26
+ "tasks/single_test.rake"
27
+ ]
28
+ s.homepage = %q{http://github.com/grosser/single_test}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.5}
32
+ s.summary = %q{Rake tasks to invoke single tests/specs with rakish syntax}
33
+ s.test_files = [
34
+ "spec/spec_helper.rb",
35
+ "spec/single_test_spec.rb"
36
+ ]
37
+
38
+ if s.respond_to? :specification_version then
39
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
+ else
44
+ end
45
+ else
46
+ end
47
+ end
48
+
@@ -0,0 +1,7 @@
1
+ it "example 1" do
2
+ something_be_here
3
+ end
4
+
5
+ it 'example "2"' do
6
+ wtf(yes)
7
+ end
@@ -0,0 +1,166 @@
1
+ require "spec_helper"
2
+ require 'single_test'
3
+
4
+ describe SingleTest do
5
+ describe :parse_cli do
6
+ it "finds the type spec" do
7
+ SingleTest.parse_cli('spec:something')[0].should == 'spec'
8
+ end
9
+
10
+ it "finds the type test" do
11
+ SingleTest.parse_cli('test:something:else')[0].should == 'test'
12
+ end
13
+
14
+ it "does not find another type" do
15
+ lambda{SingleTest.parse_cli('oops:something:else')}.should raise_error
16
+ end
17
+
18
+ it "parses the file name" do
19
+ SingleTest.parse_cli('test:something:else')[1].should == 'something'
20
+ end
21
+
22
+ it "parses the test name" do
23
+ SingleTest.parse_cli('test:something:else')[2].should == 'else'
24
+ end
25
+
26
+ it "parses missing test name as nil" do
27
+ SingleTest.parse_cli('test:something')[2].should be_nil
28
+ end
29
+
30
+ it "parses empty test name as nil" do
31
+ SingleTest.parse_cli('test:something: ')[2].should be_nil
32
+ end
33
+
34
+ it "does not split test name further" do
35
+ SingleTest.parse_cli('test:something:else:oh:no')[2].should == 'else:oh:no'
36
+ end
37
+ end
38
+
39
+ describe :find_test_file do
40
+ def make_file(path)
41
+ folder = File.dirname(path)
42
+ `mkdir -p #{folder}` unless File.exist?(folder)
43
+ `touch #{path}`
44
+ raise unless File.exist?(path)
45
+ end
46
+
47
+ before do
48
+ `rm -rf spec`
49
+ end
50
+
51
+ it "finds exact matches first" do
52
+ make_file 'spec/mixins/xxx_spec.rb'
53
+ make_file 'spec/controllers/xxx_controller_spec.rb'
54
+ SingleTest.find_test_file('spec','xxx').should == 'spec/mixins/xxx_spec.rb'
55
+ end
56
+
57
+ it "finds lower files first" do
58
+ make_file 'spec/mixins/xxx_spec.rb'
59
+ make_file 'spec/mixins/xxx/xxx_spec.rb'
60
+ SingleTest.find_test_file('spec','xxx').should == 'spec/mixins/xxx_spec.rb'
61
+ end
62
+
63
+ it "finds models before controllers" do
64
+ make_file 'spec/models/xxx_spec.rb'
65
+ make_file 'spec/controllers/xxx_controller_spec.rb'
66
+ SingleTest.find_test_file('spec','xx').should == 'spec/models/xxx_spec.rb'
67
+ end
68
+
69
+ it "finds with paths" do
70
+ make_file 'spec/controllers/admin/xxx_controller_spec.rb'
71
+ SingleTest.find_test_file('spec','ad*/xx').should == 'spec/controllers/admin/xxx_controller_spec.rb'
72
+ end
73
+ end
74
+
75
+ describe :find_example_in_spec do
76
+ examples_file = File.join(File.dirname(__FILE__),'example_finder_test.txt')
77
+
78
+ it "finds a complete statement" do
79
+ SingleTest.find_example_in_spec(examples_file,'example 1').should == 'example 1'
80
+ end
81
+
82
+ it "finds a partial statement" do
83
+ SingleTest.find_example_in_spec(examples_file,'mple 1').should == 'example 1'
84
+ end
85
+
86
+ it "finds in strangely formatted files" do
87
+ SingleTest.find_example_in_spec(examples_file,'2').should == 'example "2"'
88
+ end
89
+
90
+ it "returns nil for unfound examples" do
91
+ SingleTest.find_example_in_spec(examples_file,'not here').should == nil
92
+ end
93
+ end
94
+
95
+ describe :run_last do
96
+ before do
97
+ `mkdir app` unless File.exist?('app')
98
+ `touch app/yyy.rb`
99
+ `touch app/xxx.rb`
100
+ `mkdir spec` unless File.exist?('spec')
101
+ `touch spec/xxx_spec.rb`
102
+ `touch spec/yyy_spec.rb`
103
+ end
104
+
105
+ it "runs the last test" do
106
+ SingleTest.should_receive(:run_test).with(:spec, "spec/yyy_spec.rb")
107
+ SingleTest.run_last(:spec)
108
+ end
109
+
110
+ it "runs another file when timestamps change" do
111
+ `touch -t 12312359 #{SPEC_ROOT}/app/yyy.rb` # last minute in current year, spec will fail on new years eve :D
112
+ SingleTest.should_receive(:run_test).with(:spec, "spec/yyy_spec.rb")
113
+ SingleTest.run_last(:spec)
114
+ end
115
+ end
116
+
117
+ describe :run_test do
118
+ after :all do
119
+ ENV['X']=nil
120
+ end
121
+
122
+ it "fails when type is not spec/test" do
123
+ lambda{SingleTest.run_test('x','y')}.should raise_error
124
+ end
125
+
126
+ it "runs whole tests" do
127
+ SingleTest.should_receive(:sh).with('ruby -Ilib:test xxx -n //')
128
+ SingleTest.run_test('test','xxx')
129
+ end
130
+
131
+ it "runs single tests on their own" do
132
+ SingleTest.should_receive(:sh).with('ruby -Ilib:test xxx -n /yyy/')
133
+ SingleTest.run_test('test', 'xxx', 'yyy')
134
+ end
135
+
136
+ it "runs whole specs without -e" do
137
+ SingleTest.should_receive(:sh).with('export RAILS_ENV=test ; script/spec -O spec/spec.opts xxx')
138
+ SingleTest.run_test('spec','xxx')
139
+ end
140
+
141
+ it "runs single specs through -e" do
142
+ SingleTest.should_receive(:sh).with('export RAILS_ENV=test ; script/spec -O spec/spec.opts xxx -e "yyy"')
143
+ SingleTest.run_test('spec','xxx', 'yyy')
144
+ end
145
+
146
+ it "runs single specs through -e with -X" do
147
+ ENV['X']=''
148
+ SingleTest.should_receive(:sh).with('export RAILS_ENV=test ; script/spec -O spec/spec.opts xxx -e "yyy" -X')
149
+ SingleTest.run_test('spec','xxx', 'yyy')
150
+ end
151
+
152
+ it "runs quoted specs though -e" do
153
+ SingleTest.should_receive(:sh).with(%Q(export RAILS_ENV=test ; script/spec -O spec/spec.opts xxx -e "y\\\"yy" -X))
154
+ SingleTest.run_test('spec','xxx', 'y"yy')
155
+
156
+ end
157
+ end
158
+
159
+ describe :load_tasks do
160
+ it "can load em" do
161
+ (Rake::Task['spec:one_by_one'] rescue nil).should == nil
162
+ SingleTest.load_tasks
163
+ Rake::Task['spec:one_by_one'].should_not == nil
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,16 @@
1
+ # ---- requirements
2
+ SPEC_ROOT = File.dirname(__FILE__)
3
+ $LOAD_PATH << File.expand_path("../lib", SPEC_ROOT)
4
+
5
+ # ---- rspec
6
+ Spec::Runner.configure do |config|
7
+ config.before do
8
+ `mkdir -p #{SPEC_ROOT}/script`
9
+ `touch #{SPEC_ROOT}/script/spec`
10
+ end
11
+ config.after do
12
+ `rm -rf #{SPEC_ROOT}/script`
13
+ `rm -rf #{SPEC_ROOT}/app`
14
+ `rm -rf #{SPEC_ROOT}/spec`
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ #matches SingleTest::CMD_LINE_MATCHER --- test/spec:file[:method]
2
+ rule /^(spec|test)\:.*(\:.*)?$/ do |t|
3
+ require File.join(File.dirname(__FILE__),'..','lib','single_test')
4
+ SingleTest.run_from_cli(t.name)
5
+ end
6
+
7
+ [:spec, :test].each do |type|
8
+ namespace type do
9
+ desc "Runs each #{type} one by one and displays its results -> see which #{type}s fail on their own"
10
+ task :one_by_one do
11
+ require File.join(File.dirname(__FILE__),'..','lib','single_test')
12
+ SingleTest.run_one_by_one(type)
13
+ end
14
+
15
+ desc "run #{type} for last modified file in app folder"
16
+ task :last do
17
+ require File.join(File.dirname(__FILE__),'..','lib','single_test')
18
+ SingleTest.run_last(type)
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: single_test
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Grosser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-13 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: grosser.michael@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - README.markdown
26
+ - Rakefile
27
+ - VERSION
28
+ - lib/single_test.rb
29
+ - single_test.gemspec
30
+ - spec/example_finder_test.txt
31
+ - spec/single_test_spec.rb
32
+ - spec/spec_helper.rb
33
+ - tasks/single_test.rake
34
+ has_rdoc: true
35
+ homepage: http://github.com/grosser/single_test
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --charset=UTF-8
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.5
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Rake tasks to invoke single tests/specs with rakish syntax
62
+ test_files:
63
+ - spec/spec_helper.rb
64
+ - spec/single_test_spec.rb