testrbl 0.5.2 → 0.6.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -2
- data/lib/testrbl/version.rb +1 -1
- data/lib/testrbl.rb +129 -127
- data/spec/testrbl_spec.rb +12 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19c9047a28fbe54dceae56eee9360e2ff2b82e8c
|
4
|
+
data.tar.gz: b1cf3632adeafde0312a2de8fc26c99305c5b378
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecff79d8880fda14fd4b11fa1d8c40451b29bfcb5247baec18f7ef2cf769ac3cddcf5032a42f501cf0704d3fe13d0daf29196e9b84cfdab22acf6203664c0295
|
7
|
+
data.tar.gz: b76fa10d9bf4ab91746fbf1535cba627162ddbf8b4fb110ff6bf075f50e89dd9183575a1ab68beff60f135198800e3f8b51ed49f9565df09e3551beac1c87e3c
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
testrbl (0.
|
4
|
+
testrbl (0.6.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
activesupport (2.3.14)
|
10
|
-
bump (0.
|
10
|
+
bump (0.5.2)
|
11
11
|
diff-lcs (1.1.3)
|
12
12
|
minitest (5.0.3)
|
13
13
|
rake (0.9.2.2)
|
@@ -38,3 +38,6 @@ DEPENDENCIES
|
|
38
38
|
shoulda
|
39
39
|
test-unit
|
40
40
|
testrbl!
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
1.10.6
|
data/lib/testrbl/version.rb
CHANGED
data/lib/testrbl.rb
CHANGED
@@ -10,167 +10,169 @@ module Testrbl
|
|
10
10
|
OPTION_WITH_ARGUMENT = ["-I", "-r", "-n", "-e", "--seed"]
|
11
11
|
INTERPOLATION = /\\\#\\\{.*?\\\}/
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
13
|
+
class << self
|
14
|
+
def run_from_cli(argv)
|
15
|
+
files, options = partition_argv(argv)
|
16
|
+
files.concat(changed_files) if options.delete("--changed")
|
17
|
+
files = files.map { |f| localize(f) }
|
18
|
+
load_options, options = partition_options(options)
|
19
|
+
|
20
|
+
if files.size == 1 and files.first =~ /^(\S+):(\d+)$/
|
21
|
+
file = $1
|
22
|
+
line = $2
|
23
|
+
run(ruby + load_options + line_pattern_option(file, line) + options)
|
24
|
+
else
|
25
|
+
if files.size == 1 and File.file?(files.first)
|
26
|
+
run(ruby + load_options + files + options)
|
27
|
+
elsif options.none? { |arg| arg =~ /^-n/ }
|
28
|
+
seed = if seed = options.index("--seed")
|
29
|
+
["--"] + options.slice!(seed, 2)
|
30
|
+
else
|
31
|
+
[]
|
32
|
+
end
|
33
|
+
files = files.map { |f| File.directory?(f) ? all_test_files_in(f) : f }.flatten
|
34
|
+
run(ruby + load_options + files.map { |f| "-r#{f}" } + options + ["-e", ""] + seed)
|
35
|
+
else # pass though
|
36
|
+
# no bundle exec: projects with mini and unit-test do not run well via bundle exec testrb
|
37
|
+
run ["testrb"] + argv
|
31
38
|
end
|
32
|
-
files = files.map { |f| File.directory?(f) ? all_test_files_in(f) : f }.flatten
|
33
|
-
run(ruby + load_options + files.map { |f| "-r#{f}" } + options + ["-e", ""] + seed)
|
34
|
-
else # pass though
|
35
|
-
# no bundle exec: projects with mini and unit-test do not run well via bundle exec testrb
|
36
|
-
run ["testrb"] + argv
|
37
39
|
end
|
38
40
|
end
|
39
|
-
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
# overwritten by maxitest to just return line
|
43
|
+
def line_pattern_option(file, line)
|
44
|
+
[file, "-n", "/#{pattern_from_file(File.readlines(file), line)}/"]
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
# usable via external tools like zeus
|
48
|
+
def pattern_from_file(lines, line)
|
49
|
+
possible_lines = lines[0..(line.to_i-1)].reverse
|
49
50
|
|
50
|
-
|
51
|
+
found = possible_lines.map { |line| test_pattern_from_line(line) || block_start_from_line(line) }.compact
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
# pattern and the groups it is nested under (like describe - describe - it)
|
54
|
+
last_spaces = " " * 100
|
55
|
+
patterns = found.select do |spaces, name|
|
56
|
+
last_spaces = spaces if spaces.size < last_spaces.size
|
57
|
+
end.map(&:last).compact
|
57
58
|
|
58
|
-
|
59
|
+
return filter_duplicate_final(patterns).reverse.join(".*") if found.size > 0
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
raise "no test found before line #{line}"
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
# only keep 1 pattern that stops matching via $
|
65
|
+
def filter_duplicate_final(patterns)
|
66
|
+
found_final = 0
|
67
|
+
patterns.reject { |p| p.end_with?("$") and (found_final += 1) > 1 }
|
68
|
+
end
|
68
69
|
|
69
|
-
|
70
|
+
private
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
72
|
+
def all_test_files_in(folder)
|
73
|
+
Dir[File.join(folder, "{**/,}*_{test,spec}.rb")].uniq
|
74
|
+
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
true
|
81
|
-
else
|
82
|
-
if option =~ /^-(r|I)/
|
83
|
-
next_is_before = (option.size == 2)
|
76
|
+
def partition_options(options)
|
77
|
+
next_is_before = false
|
78
|
+
options.partition do |option|
|
79
|
+
if next_is_before
|
80
|
+
next_is_before = false
|
84
81
|
true
|
85
82
|
else
|
86
|
-
|
83
|
+
if option =~ /^-(r|I)/
|
84
|
+
next_is_before = (option.size == 2)
|
85
|
+
true
|
86
|
+
else
|
87
|
+
false
|
88
|
+
end
|
87
89
|
end
|
88
90
|
end
|
89
91
|
end
|
90
|
-
end
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
# fix 1.9 not being able to load local files
|
94
|
+
def localize(file)
|
95
|
+
file =~ /^[-a-z\d_]/ ? "./#{file}" : file
|
96
|
+
end
|
96
97
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
else
|
103
|
-
if arg =~ /^-.$/ or arg =~ /^--/ # single letter option followed by argument like -I test or long options like --verbose
|
104
|
-
next_is_option = true if OPTION_WITH_ARGUMENT.include?(arg)
|
105
|
-
false
|
106
|
-
elsif arg =~ /^-/ # multi letter option like -Itest
|
107
|
-
false
|
98
|
+
def partition_argv(argv)
|
99
|
+
next_is_option = false
|
100
|
+
argv.partition do |arg|
|
101
|
+
if next_is_option
|
102
|
+
next_is_option = false
|
108
103
|
else
|
109
|
-
|
104
|
+
if arg =~ /^-.$/ or arg =~ /^--/ # single letter option followed by argument like -I test or long options like --verbose
|
105
|
+
next_is_option = true if OPTION_WITH_ARGUMENT.include?(arg)
|
106
|
+
false
|
107
|
+
elsif arg =~ /^-/ # multi letter option like -Itest
|
108
|
+
false
|
109
|
+
else
|
110
|
+
true
|
111
|
+
end
|
110
112
|
end
|
111
113
|
end
|
112
114
|
end
|
113
|
-
end
|
114
115
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
def self.ruby
|
122
|
-
if File.file?("Gemfile")
|
123
|
-
["ruby", "-rbundler/setup"] # faster then bundle exec ruby
|
124
|
-
else
|
125
|
-
["ruby"]
|
116
|
+
def changed_files
|
117
|
+
changed_files = `git status -s`.split("\n").map { |l| l.strip.split(/\s+/, 2)[1] }
|
118
|
+
raise "Failed: #{changed_files}" unless $?.success?
|
119
|
+
changed_files.select { |f| f =~ /_(test|spec)\.rb$/ && File.exist?(f) }
|
126
120
|
end
|
127
|
-
end
|
128
121
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
122
|
+
def ruby
|
123
|
+
if File.file?("Gemfile")
|
124
|
+
["ruby", "-rbundler/setup"] # faster then bundle exec ruby
|
125
|
+
else
|
126
|
+
["ruby"]
|
127
|
+
end
|
128
|
+
end
|
134
129
|
|
135
|
-
|
136
|
-
|
137
|
-
|
130
|
+
def run(command)
|
131
|
+
puts command.join(" ")
|
132
|
+
STDOUT.flush # if exec fails horribly we at least see some output
|
133
|
+
Kernel.exec *command
|
138
134
|
end
|
139
|
-
end
|
140
135
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
return [whitespace, test_pattern_from_match(method, test_name)]
|
136
|
+
def block_start_from_line(line)
|
137
|
+
if line =~ /^(\s*).* do( \|.*\|)?$/
|
138
|
+
[$1, nil]
|
139
|
+
end
|
146
140
|
end
|
147
|
-
nil
|
148
|
-
end
|
149
141
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
"^test(: |_)#{regex.gsub(" ", ".")}$"
|
158
|
-
elsif method == "describe" || (method == "context" && !via_shoulda?)
|
159
|
-
"#{test_name}(::)?"
|
160
|
-
elsif method == "should" && via_shoulda?
|
161
|
-
optional_test_name = "(?:\(.*\))?"
|
162
|
-
"#{method} #{regex}\. #{optional_test_name}$"
|
163
|
-
elsif ["it", "should"].include?(method) # minitest aliases for shoulda
|
164
|
-
"#test_\\d+_#{test_name}$"
|
165
|
-
else
|
166
|
-
regex
|
142
|
+
def test_pattern_from_line(line)
|
143
|
+
PATTERNS.each do |r|
|
144
|
+
next unless line =~ r
|
145
|
+
whitespace, method, test_name = $1, $2, $3
|
146
|
+
return [whitespace, test_pattern_from_match(method, test_name)]
|
147
|
+
end
|
148
|
+
nil
|
167
149
|
end
|
168
150
|
|
169
|
-
|
170
|
-
|
151
|
+
def test_pattern_from_match(method, test_name)
|
152
|
+
regex = Regexp.escape(test_name).gsub("\\ "," ").gsub(INTERPOLATION, ".*")
|
153
|
+
|
154
|
+
regex = if method == "test"
|
155
|
+
# test "xxx -_ yyy"
|
156
|
+
# test-unit: "test: xxx -_ yyy"
|
157
|
+
# activesupport: "test_xxx_-__yyy"
|
158
|
+
"^test(: |_)#{regex.gsub(" ", ".")}$"
|
159
|
+
elsif method == "describe" || (method == "context" && !via_shoulda?)
|
160
|
+
"#{regex}(::)?"
|
161
|
+
elsif method == "should" && via_shoulda?
|
162
|
+
optional_test_name = "(?:\(.*\))?"
|
163
|
+
"#{method} #{regex}\. #{optional_test_name}$"
|
164
|
+
elsif ["it", "should"].include?(method) # minitest aliases for shoulda
|
165
|
+
"#test_\\d+_#{regex}$"
|
166
|
+
else
|
167
|
+
regex
|
168
|
+
end
|
169
|
+
|
170
|
+
regex.gsub("'", ".")
|
171
|
+
end
|
171
172
|
|
172
|
-
|
173
|
-
|
174
|
-
|
173
|
+
def via_shoulda?
|
174
|
+
return @via_shoulda if defined?(@via_shoulda)
|
175
|
+
@via_shoulda = !File.exist?("Gemfile.lock") || File.read("Gemfile.lock").include?(" shoulda-context ")
|
176
|
+
end
|
175
177
|
end
|
176
178
|
end
|
data/spec/testrbl_spec.rb
CHANGED
@@ -552,7 +552,7 @@ describe Testrbl do
|
|
552
552
|
|
553
553
|
describe ".test_pattern_from_line" do
|
554
554
|
def call(line)
|
555
|
-
Testrbl.test_pattern_from_line
|
555
|
+
Testrbl.send(:test_pattern_from_line, line)
|
556
556
|
end
|
557
557
|
|
558
558
|
it "finds simple tests" do
|
@@ -603,12 +603,18 @@ describe Testrbl do
|
|
603
603
|
call(" context \"c\#{111}b\" do\n").should == [" ", "c.*b"]
|
604
604
|
end
|
605
605
|
|
606
|
-
|
607
|
-
|
608
|
-
|
606
|
+
describe "minitest id do" do
|
607
|
+
it "finds simple" do
|
608
|
+
call(" it \"xx xx\" do\n").should == [" ", "#test_\\d+_xx xx$"]
|
609
|
+
end
|
609
610
|
|
610
|
-
|
611
|
-
|
611
|
+
it "finds complex" do
|
612
|
+
call(" it \"xX ._-.. ___ Xx\" do\n").should == [" ", "#test_\\d+_xX \\._\\-\\.\\. ___ Xx$"]
|
613
|
+
end
|
614
|
+
|
615
|
+
it "finds with pecial characters" do
|
616
|
+
call(" it \"hmm? it's weird\\\"?\" do\n").should == [" ", "#test_\\d+_hmm\\? it.s weird\\\\\"\\?$"]
|
617
|
+
end
|
612
618
|
end
|
613
619
|
|
614
620
|
it "finds minitest describe do calls" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testrbl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: michael@grosser.it
|