testrbl 0.1.17 → 0.2.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/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/lib/testrbl/version.rb +1 -1
- data/lib/testrbl.rb +66 -40
- data/spec/testrbl_spec.rb +45 -6
- metadata +5 -5
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/lib/testrbl/version.rb
CHANGED
data/lib/testrbl.rb
CHANGED
@@ -7,6 +7,8 @@ module Testrbl
|
|
7
7
|
/^(\s+)def\s+(test_)([a-z_\d]+)\s*(?:#.*)?$/
|
8
8
|
]
|
9
9
|
|
10
|
+
OPTION_WITH_ARGUMENT = ["-I", "-r", "-n", "-e"]
|
11
|
+
|
10
12
|
# copied from minitest
|
11
13
|
MINITEST_NAME_RE = if RUBY_VERSION >= "1.9"
|
12
14
|
Regexp.new("[^[[:word:]]]+")
|
@@ -17,89 +19,113 @@ module Testrbl
|
|
17
19
|
INTERPOLATION = /\\\#\\\{.*?\\\}/
|
18
20
|
|
19
21
|
def self.run_from_cli(argv)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
run
|
28
|
-
else
|
29
|
-
|
30
|
-
|
22
|
+
files, options = partition_argv(argv)
|
23
|
+
files = files.map { |f| localize(f) }
|
24
|
+
load_options, options = partition_options(options)
|
25
|
+
|
26
|
+
if files.size == 1 and files.first =~ /^(\S+):(\d+)$/
|
27
|
+
file = $1
|
28
|
+
line = $2
|
29
|
+
run(ruby + load_options + [file, "-n", "/#{pattern_from_file(File.readlines(file), line)}/"] + options)
|
30
|
+
else
|
31
|
+
if files.all? { |f| File.file?(f) } and options.none? { |arg| arg =~ /^-n/ }
|
32
|
+
run(ruby + load_options + files.map { |f| "-r#{f}" } + options + ["-e", ""])
|
33
|
+
else # pass though
|
34
|
+
# no bundle exec: projects with mini and unit-test do not run well via bundle exec testrb
|
35
|
+
run ["testrb"] + argv
|
36
|
+
end
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
34
|
-
#
|
40
|
+
# usable via external tools like zeus
|
35
41
|
def self.pattern_from_file(lines, line)
|
36
|
-
|
42
|
+
possible_lines = lines[0..(line.to_i-1)].reverse
|
37
43
|
|
38
44
|
last_spaces = " " * 100
|
39
|
-
found =
|
45
|
+
found = possible_lines.map { |line| test_pattern_from_line(line) }.compact
|
46
|
+
|
47
|
+
# pattern and the groups it is nested under (like describe - describe - it)
|
40
48
|
patterns = found.select do |spaces, name|
|
41
49
|
last_spaces = spaces if spaces.size < last_spaces.size
|
42
50
|
end.map(&:last)
|
43
51
|
|
44
|
-
|
45
|
-
found_final = false
|
46
|
-
patterns.each do |pattern|
|
47
|
-
is_final = pattern.end_with?("$")
|
48
|
-
next if is_final && found_final
|
49
|
-
found_final = is_final
|
50
|
-
use << pattern
|
51
|
-
end
|
52
|
-
|
53
|
-
return use.reverse.join(".*") if found.size > 0
|
52
|
+
return filter_duplicate_final(patterns).reverse.join(".*") if found.size > 0
|
54
53
|
|
55
54
|
raise "no test found before line #{line}"
|
56
55
|
end
|
57
56
|
|
57
|
+
# only keep 1 pattern that stops matching via $
|
58
|
+
def self.filter_duplicate_final(patterns)
|
59
|
+
found_final = 0
|
60
|
+
patterns.reject { |p| p.end_with?("$") and (found_final += 1) > 1 }
|
61
|
+
end
|
62
|
+
|
58
63
|
private
|
59
64
|
|
65
|
+
def self.partition_options(options)
|
66
|
+
next_is_before = false
|
67
|
+
options.partition do |option|
|
68
|
+
if next_is_before
|
69
|
+
next_is_before = false
|
70
|
+
true
|
71
|
+
else
|
72
|
+
if option =~ /^-(r|I)/
|
73
|
+
next_is_before = (option.size == 2)
|
74
|
+
true
|
75
|
+
else
|
76
|
+
false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
60
82
|
# fix 1.9 not being able to load local files
|
61
83
|
def self.localize(file)
|
62
84
|
file =~ /^[-a-z\d_]/ ? "./#{file}" : file
|
63
85
|
end
|
64
86
|
|
65
|
-
def self.
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
87
|
+
def self.partition_argv(argv)
|
88
|
+
next_is_option = false
|
89
|
+
argv.partition do |arg|
|
90
|
+
if next_is_option
|
91
|
+
next_is_option = false
|
92
|
+
else
|
93
|
+
if arg =~ /^-.$/ or arg =~ /^--/ # single letter option followed by argument like -I test or long options like --verbose
|
94
|
+
next_is_option = true if OPTION_WITH_ARGUMENT.include?(arg)
|
95
|
+
false
|
96
|
+
elsif arg =~ /^-/ # multi letter option like -Itest
|
97
|
+
false
|
98
|
+
else
|
99
|
+
true
|
100
|
+
end
|
101
|
+
end
|
75
102
|
end
|
76
103
|
end
|
77
104
|
|
78
105
|
def self.ruby
|
79
106
|
if File.file?("Gemfile")
|
80
|
-
"ruby -rbundler/setup" # faster then bundle exec ruby
|
107
|
+
["ruby", "-rbundler/setup"] # faster then bundle exec ruby
|
81
108
|
else
|
82
|
-
"ruby"
|
109
|
+
["ruby"]
|
83
110
|
end
|
84
111
|
end
|
85
112
|
|
86
113
|
def self.run(command)
|
87
|
-
command = [*command]
|
88
114
|
puts command.join(" ")
|
89
115
|
STDOUT.flush # if exec fails horribly we at least see some output
|
90
116
|
Kernel.exec *command
|
91
117
|
end
|
92
118
|
|
93
|
-
def self.
|
119
|
+
def self.test_pattern_from_line(line)
|
94
120
|
PATTERNS.each do |r|
|
95
121
|
next unless line =~ r
|
96
122
|
whitespace, method, test_name = $1, $2, $3
|
97
|
-
return [whitespace,
|
123
|
+
return [whitespace, test_pattern_from_match(method, test_name)]
|
98
124
|
end
|
99
125
|
nil
|
100
126
|
end
|
101
127
|
|
102
|
-
def self.
|
128
|
+
def self.test_pattern_from_match(method, test_name)
|
103
129
|
regex = Regexp.escape(test_name).gsub("\\ "," ").gsub(INTERPOLATION, ".*")
|
104
130
|
|
105
131
|
if method == "should"
|
data/spec/testrbl_spec.rb
CHANGED
@@ -383,24 +383,33 @@ describe Testrbl do
|
|
383
383
|
before do
|
384
384
|
write "backtrace_test.rb", <<-RUBY
|
385
385
|
puts caller
|
386
|
+
require 'test/unit'
|
387
|
+
|
388
|
+
class Xxx1 < Test::Unit::TestCase
|
389
|
+
def test_xxx
|
390
|
+
puts 'BACKTRACE'
|
391
|
+
end
|
392
|
+
end
|
386
393
|
RUBY
|
387
394
|
end
|
388
395
|
|
389
396
|
it "does not run via testrb if possible" do
|
390
|
-
result = testrbl "a/b/c_test.rb backtrace_test.rb"
|
397
|
+
result = testrbl "-Itest -I lib a/b/c_test.rb backtrace_test.rb -v"
|
391
398
|
result.should include("CDE")
|
399
|
+
result.should include("BACKTRACE")
|
392
400
|
result.should_not include("bin/testrb:")
|
393
401
|
end
|
394
402
|
|
395
|
-
it "runs via testrb if
|
396
|
-
result = testrbl "a/b/c_test.rb backtrace_test.rb -
|
403
|
+
it "runs via testrb if unavoidable" do
|
404
|
+
result = testrbl "a/b/c_test.rb backtrace_test.rb -n '/xxx/'"
|
397
405
|
result.should include("CDE")
|
406
|
+
result.should include("BACKTRACE")
|
398
407
|
result.should include("bin/testrb:")
|
399
408
|
end
|
400
409
|
end
|
401
410
|
end
|
402
411
|
|
403
|
-
describe ".
|
412
|
+
describe ".test_pattern_from_file" do
|
404
413
|
def call(content, line)
|
405
414
|
lines = content.split("\n").map{|l| l + "\n" }
|
406
415
|
Testrbl.pattern_from_file(lines, line)
|
@@ -425,9 +434,9 @@ describe Testrbl do
|
|
425
434
|
end
|
426
435
|
end
|
427
436
|
|
428
|
-
describe ".
|
437
|
+
describe ".test_pattern_from_line" do
|
429
438
|
def call(line)
|
430
|
-
Testrbl.
|
439
|
+
Testrbl.test_pattern_from_line(line)
|
431
440
|
end
|
432
441
|
|
433
442
|
it "finds simple tests" do
|
@@ -498,4 +507,34 @@ describe Testrbl do
|
|
498
507
|
call(" context \"xx ' xx\" do\n").should == [" ", "xx . xx"]
|
499
508
|
end
|
500
509
|
end
|
510
|
+
|
511
|
+
describe ".partition_argv" do
|
512
|
+
def call(*args)
|
513
|
+
Testrbl.send(:partition_argv, *args)
|
514
|
+
end
|
515
|
+
|
516
|
+
it "finds files" do
|
517
|
+
call(["xxx"]).should == [["xxx"], []]
|
518
|
+
end
|
519
|
+
|
520
|
+
it "finds files after multi-space options" do
|
521
|
+
call(["-I", "test", "xxx"]).should == [["xxx"], ["-I", "test"]]
|
522
|
+
end
|
523
|
+
|
524
|
+
it "finds options" do
|
525
|
+
call(["-I", "test"]).should == [[], ["-I", "test"]]
|
526
|
+
end
|
527
|
+
|
528
|
+
it "finds --verbose" do
|
529
|
+
call(["--verbose", "test"]).should == [["test"], ["--verbose"]]
|
530
|
+
end
|
531
|
+
|
532
|
+
it "finds -- options" do
|
533
|
+
call(["--foo", "test"]).should == [["test"], ["--foo"]]
|
534
|
+
end
|
535
|
+
|
536
|
+
it "finds mashed options" do
|
537
|
+
call(["-Itest"]).should == [[], ["-Itest"]]
|
538
|
+
end
|
539
|
+
end
|
501
540
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testrbl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-03-09 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email: michael@grosser.it
|
@@ -44,7 +44,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
44
|
version: '0'
|
45
45
|
segments:
|
46
46
|
- 0
|
47
|
-
hash:
|
47
|
+
hash: -866997392072142941
|
48
48
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
@@ -53,10 +53,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
53
|
version: '0'
|
54
54
|
segments:
|
55
55
|
- 0
|
56
|
-
hash:
|
56
|
+
hash: -866997392072142941
|
57
57
|
requirements: []
|
58
58
|
rubyforge_project:
|
59
|
-
rubygems_version: 1.8.
|
59
|
+
rubygems_version: 1.8.25
|
60
60
|
signing_key:
|
61
61
|
specification_version: 3
|
62
62
|
summary: Run ruby Test::Unit/Shoulda tests by line-number / folder / the dozen
|