single_test 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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