oktest 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +197 -22
- data/Rakefile.rb +5 -2
- data/benchmark/Rakefile.rb +4 -0
- data/lib/oktest.rb +170 -58
- data/oktest.gemspec +3 -3
- data/test/assertion_test.rb +1 -1
- data/test/filter_test.rb +1 -1
- data/test/fixture_test.rb +14 -1
- data/test/generator_test.rb +1 -1
- data/test/helper_test.rb +3 -3
- data/test/initialize.rb +1 -1
- data/test/mainapp_test.rb +59 -43
- data/test/matcher_test.rb +1 -1
- data/test/misc_test.rb +5 -5
- data/test/node_test.rb +27 -4
- data/test/reporter_test.rb +30 -31
- data/test/runner_test.rb +8 -17
- data/test/tc.rb +12 -0
- data/test/util_test.rb +71 -1
- data/test/utilhelper_test.rb +84 -0
- data/test/visitor_test.rb +1 -1
- metadata +4 -3
data/lib/oktest.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.2.0 $
|
5
5
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
6
6
|
### $License: MIT License $
|
7
7
|
###
|
@@ -12,7 +12,7 @@ require 'set'
|
|
12
12
|
module Oktest
|
13
13
|
|
14
14
|
|
15
|
-
VERSION = '$Release: 1.
|
15
|
+
VERSION = '$Release: 1.2.0 $'.split()[1]
|
16
16
|
|
17
17
|
|
18
18
|
class OktestError < StandardError
|
@@ -794,6 +794,21 @@ END
|
|
794
794
|
end
|
795
795
|
|
796
796
|
|
797
|
+
module UtilHelper
|
798
|
+
|
799
|
+
def partial_regexp(pattern, begin_='\A', end_='\z', mark="{== ==}")
|
800
|
+
#; [!9drtn] is available in both topic and spec blocks.
|
801
|
+
return Util.partial_regexp(pattern, begin_, end_, mark)
|
802
|
+
end
|
803
|
+
|
804
|
+
def partial_regexp!(pattern, begin_='\A', end_='\z', mark="{== ==}")
|
805
|
+
#; [!wo4hp] is available in both topic and spec blocks.
|
806
|
+
return Util.partial_regexp!(pattern, begin_, end_, mark)
|
807
|
+
end
|
808
|
+
|
809
|
+
end
|
810
|
+
|
811
|
+
|
797
812
|
class Context
|
798
813
|
## * Context class is separated from ScopeNode, TopicNode, and SpecLeaf.
|
799
814
|
## * `topic()` and `spec()` creates subclass of Context class,
|
@@ -801,6 +816,8 @@ END
|
|
801
816
|
## * `scope()` instanciates those subclasses, and run spec blocks
|
802
817
|
## in that instance objects.
|
803
818
|
|
819
|
+
extend UtilHelper
|
820
|
+
|
804
821
|
class << self
|
805
822
|
attr_accessor :__node
|
806
823
|
end
|
@@ -833,26 +850,29 @@ END
|
|
833
850
|
return to
|
834
851
|
end
|
835
852
|
|
836
|
-
def self.spec(desc, tag: nil, &block)
|
853
|
+
def self.spec(desc, tag: nil, fixture: nil, &block)
|
837
854
|
node = @__node
|
838
855
|
node.is_a?(Node) or raise "internal error: node=#{node.inspect}" # for debug
|
856
|
+
#; [!4vkbl] error when `fixture:` keyword arg is not a Hash object.
|
857
|
+
fixture.nil? || fixture.is_a?(Hash) or
|
858
|
+
raise ArgumentError, "spec(fixture: #{fixture.inspect}): fixture argument should be a Hash object, but got #{fixture.class.name} object."
|
839
859
|
#; [!ala78] provides raising TodoException block if block not given.
|
840
860
|
block ||= proc { raise TodoException, "not implemented yet" }
|
841
861
|
#; [!x48db] keeps called location only when block has parameters.
|
842
862
|
if block.parameters.empty?
|
843
863
|
location = nil
|
844
864
|
else
|
845
|
-
location =
|
865
|
+
location = caller_locations(1, 1).first
|
846
866
|
end
|
847
867
|
#; [!c8c8o] creates new spec object.
|
848
|
-
spec = SpecLeaf.new(node, desc, tag: tag, location: location, &block)
|
868
|
+
spec = SpecLeaf.new(node, desc, tag: tag, fixture: fixture, location: location, &block)
|
849
869
|
return spec
|
850
870
|
end
|
851
871
|
|
852
872
|
def self.fixture(name, &block)
|
853
873
|
#; [!8wfrq] registers fixture factory block.
|
854
874
|
#; [!y3ks3] retrieves block parameter names.
|
855
|
-
location =
|
875
|
+
location = caller_locations(1, 1).first
|
856
876
|
@__node.register_fixture_block(name, location, &block)
|
857
877
|
self
|
858
878
|
end
|
@@ -976,6 +996,7 @@ END
|
|
976
996
|
context = @context_class.new()
|
977
997
|
#; [!9hbxn] context object has 'ok()' method.
|
978
998
|
context.extend SpecHelper
|
999
|
+
context.extend UtilHelper
|
979
1000
|
return context
|
980
1001
|
end
|
981
1002
|
|
@@ -1004,7 +1025,7 @@ END
|
|
1004
1025
|
return @hooks[key]
|
1005
1026
|
end
|
1006
1027
|
|
1007
|
-
def _repr(depth=0, buf=
|
1028
|
+
def _repr(depth=0, buf=String.new)
|
1008
1029
|
#; [!bt5j8] builds debug string.
|
1009
1030
|
if depth < 0
|
1010
1031
|
id_str = "%x" % self.object_id
|
@@ -1079,16 +1100,17 @@ END
|
|
1079
1100
|
|
1080
1101
|
class SpecLeaf < Item
|
1081
1102
|
|
1082
|
-
def initialize(parent, desc, tag: nil, location: nil, &block)
|
1103
|
+
def initialize(parent, desc, tag: nil, fixture: nil, location: nil, &block)
|
1083
1104
|
#@parent = parent # not keep parent node to avoid recursive reference
|
1084
1105
|
@desc = desc
|
1085
1106
|
@tag = tag
|
1107
|
+
@fixture = fixture
|
1086
1108
|
@location = location # necessary when raising fixture not found error
|
1087
1109
|
@block = block
|
1088
1110
|
parent.add_child(self) if parent
|
1089
1111
|
end
|
1090
1112
|
|
1091
|
-
attr_reader :desc, :tag, :location, :block
|
1113
|
+
attr_reader :desc, :tag, :fixture, :location, :block
|
1092
1114
|
|
1093
1115
|
def _prefix
|
1094
1116
|
'-'
|
@@ -1109,7 +1131,7 @@ END
|
|
1109
1131
|
nil
|
1110
1132
|
end
|
1111
1133
|
|
1112
|
-
def _repr(depth=0, buf=
|
1134
|
+
def _repr(depth=0, buf=String.new) #:nodoc:
|
1113
1135
|
#; [!6nsgy] builds debug string.
|
1114
1136
|
buf << " " * depth << "- #{@desc}"
|
1115
1137
|
buf << " (tag: #{@tag.inspect})" if @tag
|
@@ -1138,8 +1160,8 @@ END
|
|
1138
1160
|
|
1139
1161
|
def self.scope(tag: nil, &block)
|
1140
1162
|
#; [!kem4y] detects test script filename.
|
1141
|
-
location =
|
1142
|
-
filename = location
|
1163
|
+
location = caller_locations(1, 1).first
|
1164
|
+
filename = location.path.to_s
|
1143
1165
|
#; [!6ullm] changes test script filename from absolute path to relative path.
|
1144
1166
|
if filename
|
1145
1167
|
pwd = Dir.pwd()
|
@@ -1175,7 +1197,7 @@ END
|
|
1175
1197
|
#; [!bc3l2] records invoked location.
|
1176
1198
|
#; [!mqtdy] not record invoked location when `Config.ok_location == false`.
|
1177
1199
|
if Config.ok_location
|
1178
|
-
location =
|
1200
|
+
location = caller_locations(1, 1).first
|
1179
1201
|
else
|
1180
1202
|
location = nil
|
1181
1203
|
end
|
@@ -1190,7 +1212,7 @@ END
|
|
1190
1212
|
#; [!agmx8] records invoked location.
|
1191
1213
|
#; [!a9508] not record invoked location when `Config.ok_location == false`.
|
1192
1214
|
if Config.ok_location
|
1193
|
-
location =
|
1215
|
+
location = caller_locations(1, 1).first
|
1194
1216
|
else
|
1195
1217
|
location = nil
|
1196
1218
|
end
|
@@ -1216,7 +1238,7 @@ END
|
|
1216
1238
|
#; [!wxcsp] raises error when fixture not found.
|
1217
1239
|
unless tuple
|
1218
1240
|
exc = FixtureNotFoundError.new("`#{name.inspect}`: fixture not found.")
|
1219
|
-
exc.set_backtrace([
|
1241
|
+
exc.set_backtrace([caller_locations(1, 1).first.to_s])
|
1220
1242
|
raise exc
|
1221
1243
|
end
|
1222
1244
|
#; [!m4ava] calls fixture block and returns result of it.
|
@@ -1226,7 +1248,7 @@ END
|
|
1226
1248
|
end
|
1227
1249
|
|
1228
1250
|
def TODO()
|
1229
|
-
location =
|
1251
|
+
location = caller_locations(1, 1).first # ex: "foo_test.rb:123:in ...."
|
1230
1252
|
@__TODO = location
|
1231
1253
|
end
|
1232
1254
|
|
@@ -1547,7 +1569,8 @@ END
|
|
1547
1569
|
begin
|
1548
1570
|
params = Util.required_param_names_of_block(spec.block)
|
1549
1571
|
values = params.nil? || params.empty? ? [] \
|
1550
|
-
: get_fixture_values(params, node, spec, context
|
1572
|
+
: get_fixture_values(params, node, spec, context, spec.location,
|
1573
|
+
spec.fixture ? spec.fixture.dup : {})
|
1551
1574
|
spec.run_block_in_context_object(context, *values)
|
1552
1575
|
rescue NoMemoryError => exc; raise exc
|
1553
1576
|
rescue SignalException => exc; raise exc
|
@@ -1572,7 +1595,7 @@ END
|
|
1572
1595
|
exc = TODO_EXCEPTION.new("#{exc.class} raised because not implemented yet")
|
1573
1596
|
end
|
1574
1597
|
location = context.__TODO
|
1575
|
-
exc.set_backtrace([location])
|
1598
|
+
exc.set_backtrace([location.to_s])
|
1576
1599
|
end
|
1577
1600
|
#; [!dihkr] calls 'at_end' blocks, even when exception raised.
|
1578
1601
|
begin
|
@@ -1586,8 +1609,8 @@ END
|
|
1586
1609
|
|
1587
1610
|
private
|
1588
1611
|
|
1589
|
-
def get_fixture_values(names, node, spec, context)
|
1590
|
-
return THE_FIXTURE_MANAGER.get_fixture_values(names, node, spec, context)
|
1612
|
+
def get_fixture_values(names, node, spec, context, location=nil, resolved=nil)
|
1613
|
+
return THE_FIXTURE_MANAGER.get_fixture_values(names, node, spec, context, location, resolved)
|
1591
1614
|
end
|
1592
1615
|
|
1593
1616
|
def _call_blocks_parent_first(node, name, context)
|
@@ -1643,51 +1666,53 @@ END
|
|
1643
1666
|
|
1644
1667
|
class FixtureManager
|
1645
1668
|
|
1646
|
-
def get_fixture_values(names, node, spec, context, location
|
1669
|
+
def get_fixture_values(names, node, spec, context, location, resolved={}, _resolving=[])
|
1647
1670
|
#; [!w6ffs] resolves 'this_topic' fixture name as target objec of current topic.
|
1648
|
-
|
1671
|
+
resolved[:this_topic] = node.target if !resolved.key?(:this_topic) && node.topic?
|
1649
1672
|
#; [!ja2ew] resolves 'this_spec' fixture name as description of current spec.
|
1650
|
-
|
1673
|
+
resolved[:this_spec] = spec.desc if !resolved.key?(:this_spec)
|
1651
1674
|
#; [!v587k] resolves fixtures.
|
1652
|
-
location ||= spec.location
|
1653
1675
|
return names.collect {|name|
|
1654
1676
|
#; [!np4p9] raises error when loop exists in dependency.
|
1655
1677
|
! _resolving.include?(name) or
|
1656
1678
|
raise _looped_dependency_error(name, _resolving, location)
|
1657
|
-
get_fixture_value(name, node, spec, context, location,
|
1679
|
+
get_fixture_value(name, node, spec, context, location, resolved, _resolving)
|
1658
1680
|
}
|
1659
1681
|
end
|
1660
1682
|
|
1661
|
-
def get_fixture_value(name, node, spec, context, location
|
1662
|
-
return
|
1663
|
-
location ||= spec.location
|
1683
|
+
def get_fixture_value(name, node, spec, context, location, resolved={}, _resolving=[])
|
1684
|
+
return resolved[name] if resolved.key?(name)
|
1664
1685
|
tuple = node.get_fixture_block(name)
|
1665
1686
|
if tuple
|
1666
1687
|
block, param_names, location = tuple
|
1667
1688
|
#; [!2esaf] resolves fixture dependencies.
|
1668
1689
|
if param_names
|
1669
1690
|
_resolving << name
|
1670
|
-
args = get_fixture_values(param_names, node, spec, context, location,
|
1691
|
+
args = get_fixture_values(param_names, node, spec, context, location, resolved, _resolving)
|
1671
1692
|
(popped = _resolving.pop) == name or
|
1672
1693
|
raise "** assertion failed: name=#{name.inspect}, resolvng[-1]=#{popped.inspect}"
|
1673
|
-
#; [!4xghy] calls fixture block with context object as self.
|
1674
|
-
val = context.instance_exec(*args, &block)
|
1675
1694
|
else
|
1676
|
-
|
1695
|
+
args = []
|
1677
1696
|
end
|
1697
|
+
#; [!gyyst] overwrites keyword params by fixture values.
|
1698
|
+
kwnames = Util.keyword_param_names_of_block(block)
|
1699
|
+
kwargs = {}
|
1700
|
+
kwnames.each {|name| kwargs[name] = resolved[name] if resolved.key?(name) }
|
1701
|
+
#; [!4xghy] calls fixture block with context object as self.
|
1702
|
+
val = context.instance_exec(*args, **kwargs, &block)
|
1678
1703
|
#; [!8t3ul] caches fixture value to call fixture block only once per spec.
|
1679
|
-
|
1704
|
+
resolved[name] = val
|
1680
1705
|
return val
|
1681
1706
|
elsif node.parent
|
1682
1707
|
#; [!4chb9] traverses parent topics if fixture not found in current topic.
|
1683
|
-
return get_fixture_value(name, node.parent, spec, context, location,
|
1708
|
+
return get_fixture_value(name, node.parent, spec, context, location, resolved, _resolving)
|
1684
1709
|
elsif ! node.equal?(THE_GLOBAL_SCOPE)
|
1685
1710
|
#; [!wt3qk] suports global scope.
|
1686
|
-
return get_fixture_value(name, THE_GLOBAL_SCOPE, spec, context, location,
|
1711
|
+
return get_fixture_value(name, THE_GLOBAL_SCOPE, spec, context, location, resolved, _resolving)
|
1687
1712
|
else
|
1688
1713
|
#; [!nr79z] raises error when fixture not found.
|
1689
1714
|
exc = FixtureNotFoundError.new("#{name}: fixture not found. (spec: #{spec.desc})")
|
1690
|
-
exc.set_backtrace([location]) if location
|
1715
|
+
exc.set_backtrace([location.to_s]) if location
|
1691
1716
|
raise exc
|
1692
1717
|
end
|
1693
1718
|
end
|
@@ -1702,7 +1727,7 @@ END
|
|
1702
1727
|
loop = s1.empty? ? s2 : "#{s1}->#{s2}"
|
1703
1728
|
#location = $1 if location =~ /(.*:\d+)/
|
1704
1729
|
exc = LoopedDependencyError.new("fixture dependency is looped: #{loop}")
|
1705
|
-
exc.set_backtrace([location])
|
1730
|
+
exc.set_backtrace([location.to_s])
|
1706
1731
|
return exc
|
1707
1732
|
end
|
1708
1733
|
|
@@ -1846,7 +1871,7 @@ END
|
|
1846
1871
|
end
|
1847
1872
|
lines = []
|
1848
1873
|
msg.each_line {|line| lines << line }
|
1849
|
-
puts lines.shift.chomp
|
1874
|
+
puts Color.errmsg(lines.shift.chomp)
|
1850
1875
|
puts lines.join.chomp unless lines.empty?
|
1851
1876
|
puts exc.diff if exc.respond_to?(:diff) && exc.diff # for oktest.rb
|
1852
1877
|
end
|
@@ -1912,9 +1937,9 @@ END
|
|
1912
1937
|
$stdout.flush
|
1913
1938
|
end
|
1914
1939
|
label = Color.status(status, LABELS[status] || '???')
|
1915
|
-
msg = "#{' ' * (depth - 1)}- [#{label}] #{spec.desc}"
|
1940
|
+
msg = ["#{' ' * (depth - 1)}- [#{label}] #{spec.desc}"]
|
1916
1941
|
msg << " " << Color.reason("(reason: #{error.message})") if status == :SKIP
|
1917
|
-
puts msg
|
1942
|
+
puts msg.join()
|
1918
1943
|
end
|
1919
1944
|
|
1920
1945
|
end
|
@@ -2100,6 +2125,13 @@ END
|
|
2100
2125
|
return param_names
|
2101
2126
|
end
|
2102
2127
|
|
2128
|
+
def keyword_param_names_of_block(block)
|
2129
|
+
#; [!p6qqp] returns keyword param names of proc object.
|
2130
|
+
names = []
|
2131
|
+
block.parameters.each {|kind, name| names << name if kind == :key }
|
2132
|
+
return names
|
2133
|
+
end
|
2134
|
+
|
2103
2135
|
def strfold(str, width=80, mark='...')
|
2104
2136
|
#; [!wb7m8] returns string as it is if string is not long.
|
2105
2137
|
return str if str.bytesize <= width
|
@@ -2200,6 +2232,70 @@ END
|
|
2200
2232
|
end
|
2201
2233
|
end
|
2202
2234
|
|
2235
|
+
class PartialRegexp < Regexp
|
2236
|
+
attr_accessor :pattern_string, :begin, :end, :mark
|
2237
|
+
def inspect()
|
2238
|
+
#; [!uyh31] returns function call style string if @pattern_string is set.
|
2239
|
+
if @pattern_string
|
2240
|
+
c = @pattern_string.end_with?("\n") ? "" : ".chomp"
|
2241
|
+
p = @pattern_string.chomp
|
2242
|
+
b = @begin == '\A' ? "'\\A'" : @begin.inspect
|
2243
|
+
e = @end == '\z' ? "'\\z'" : @end.inspect
|
2244
|
+
m = mark == "{== ==}" ? "" : ", #{mark.inspect}"
|
2245
|
+
return "partial_regexp(<<PREXP#{c}, #{b}, #{e}#{m})\n#{p}\nPREXP\n"
|
2246
|
+
#; [!ts9v4] returns regexp literal style string if @pattern_string is not set.
|
2247
|
+
else
|
2248
|
+
s = super
|
2249
|
+
s = s.gsub(/([^\\](?:\\\\)*)((?:\\n)+)/) {
|
2250
|
+
$1 + ("\\n\n" * ($2.length / 2))
|
2251
|
+
}
|
2252
|
+
if s =~ /\n/
|
2253
|
+
s = s.sub(/\A\/(\\A)?/, "/\\1\n")
|
2254
|
+
s = s + "x" # `/.../x` means multiline regexp
|
2255
|
+
end
|
2256
|
+
return s
|
2257
|
+
end
|
2258
|
+
end
|
2259
|
+
end
|
2260
|
+
|
2261
|
+
def partial_regexp!(pattern, begin_='\A', end_='\z', mark="{== ==}")
|
2262
|
+
#; [!peyu4] returns PartialRegexp object which inspect string is function call styel.
|
2263
|
+
regexp = partial_regexp(pattern, begin_, end_, mark)
|
2264
|
+
regexp.pattern_string = pattern
|
2265
|
+
regexp.begin = begin_; regexp.end = end_; regexp.mark = mark
|
2266
|
+
return regexp
|
2267
|
+
end
|
2268
|
+
|
2269
|
+
def partial_regexp(pattern, begin_='\A', end_='\z', mark="{== ==}")
|
2270
|
+
mark_rexp = PARTIAL_REGEXP_CACHE[mark]
|
2271
|
+
if mark_rexp.nil?
|
2272
|
+
#; [!ostkw] raises error if mark has no space or has more than two spaces.
|
2273
|
+
pair = mark.split()
|
2274
|
+
pair.length == 2 or
|
2275
|
+
raise ArgumentError.new("#{mark.inspect}: mark should contain only one space (ex: `{== ==}`).")
|
2276
|
+
open = Regexp.escape(pair[0])
|
2277
|
+
close = Regexp.escape(pair[1])
|
2278
|
+
mark_rexp = Regexp.compile("#{open}(.*?)#{close}")
|
2279
|
+
PARTIAL_REGEXP_CACHE[mark] = mark_rexp
|
2280
|
+
end
|
2281
|
+
#; [!wn524] returns PartialRegexp object which inspect string is regexp literal style.
|
2282
|
+
pos = 0
|
2283
|
+
buf = []
|
2284
|
+
buf << begin_ if begin_
|
2285
|
+
pattern.scan(mark_rexp) do
|
2286
|
+
m = Regexp.last_match
|
2287
|
+
text = pattern[pos, m.begin(0) - pos]
|
2288
|
+
buf << Regexp.escape(text) << $1.strip()
|
2289
|
+
pos = m.end(0)
|
2290
|
+
end
|
2291
|
+
rest = pos == 0 ? pattern : pattern[pos..-1]
|
2292
|
+
buf << Regexp.escape(rest) unless rest.empty?
|
2293
|
+
buf << end_ if end_
|
2294
|
+
return PartialRegexp.compile(buf.join())
|
2295
|
+
end
|
2296
|
+
|
2297
|
+
PARTIAL_REGEXP_CACHE = {} # :nodoc:
|
2298
|
+
|
2203
2299
|
end
|
2204
2300
|
|
2205
2301
|
|
@@ -2342,24 +2438,35 @@ END
|
|
2342
2438
|
module_function
|
2343
2439
|
|
2344
2440
|
def normal s; return s; end
|
2345
|
-
def bold s; return "\e[0;1m#{s}\e[
|
2346
|
-
|
2347
|
-
def
|
2348
|
-
def
|
2349
|
-
def
|
2350
|
-
def
|
2351
|
-
def
|
2352
|
-
def
|
2353
|
-
def
|
2441
|
+
def bold s; return "\e[0;1m#{s}\e[0m"; end
|
2442
|
+
|
2443
|
+
def black s; return "\e[0;30m#{s}\e[0m"; end
|
2444
|
+
def red s; return "\e[0;31m#{s}\e[0m"; end
|
2445
|
+
def green s; return "\e[0;32m#{s}\e[0m"; end
|
2446
|
+
def yellow s; return "\e[0;33m#{s}\e[0m"; end
|
2447
|
+
def blue s; return "\e[0;34m#{s}\e[0m"; end
|
2448
|
+
def magenta s; return "\e[0;35m#{s}\e[0m"; end
|
2449
|
+
def cyan s; return "\e[0;36m#{s}\e[0m"; end
|
2450
|
+
def white s; return "\e[0;37m#{s}\e[0m"; end
|
2451
|
+
|
2452
|
+
def black_b s; return "\e[1;30m#{s}\e[0m"; end # bold
|
2453
|
+
def red_b s; return "\e[1;31m#{s}\e[0m"; end # bold
|
2454
|
+
def green_b s; return "\e[1;32m#{s}\e[0m"; end # bold
|
2455
|
+
def yellow_b s; return "\e[1;33m#{s}\e[0m"; end # bold
|
2456
|
+
def blue_b s; return "\e[1;34m#{s}\e[0m"; end # bold
|
2457
|
+
def magenta_b s; return "\e[1;35m#{s}\e[0m"; end # bold
|
2458
|
+
def cyan_b s; return "\e[1;36m#{s}\e[0m"; end # bold
|
2459
|
+
def white_b s; return "\e[1;37m#{s}\e[0m"; end # bold
|
2354
2460
|
|
2355
2461
|
def topic s; Config.color_enabled ? bold(s) : s; end
|
2356
2462
|
def spec s; Config.color_enabled ? normal(s) : s; end
|
2357
|
-
def pass s; Config.color_enabled ?
|
2463
|
+
def pass s; Config.color_enabled ? cyan(s) : s; end
|
2358
2464
|
def fail s; Config.color_enabled ? red(s) : s; end
|
2359
|
-
def error s; Config.color_enabled ?
|
2465
|
+
def error s; Config.color_enabled ? red_b(s) : s; end # bold
|
2360
2466
|
def skip s; Config.color_enabled ? yellow(s) : s; end
|
2361
2467
|
def todo s; Config.color_enabled ? yellow(s) : s; end
|
2362
2468
|
def reason s; Config.color_enabled ? yellow(s) : s; end
|
2469
|
+
def errmsg s; Config.color_enabled ? red(s) : s; end
|
2363
2470
|
|
2364
2471
|
def status(status, s)
|
2365
2472
|
#; [!yev5y] returns string containing color escape sequence.
|
@@ -2494,6 +2601,11 @@ END
|
|
2494
2601
|
color_enabled = nil
|
2495
2602
|
opts = Options.new
|
2496
2603
|
parser = option_parser(opts)
|
2604
|
+
#; [!v5xie] parses $OKTEST_RB environment variable.
|
2605
|
+
if ENV.key?('OKTEST_RB')
|
2606
|
+
parser.parse(ENV['OKTEST_RB'].split())
|
2607
|
+
end
|
2608
|
+
#
|
2497
2609
|
filenames = parser.parse(args)
|
2498
2610
|
#; [!9973n] '-h' or '--help' option prints help message.
|
2499
2611
|
if opts.help
|
@@ -2505,8 +2617,8 @@ END
|
|
2505
2617
|
puts VERSION
|
2506
2618
|
return 0
|
2507
2619
|
end
|
2508
|
-
#; [!dk8eg] '-
|
2509
|
-
if opts.
|
2620
|
+
#; [!dk8eg] '-S' or '--skeleton' option prints test code skeleton.
|
2621
|
+
if opts.skeleton
|
2510
2622
|
print SKELETON
|
2511
2623
|
return 0
|
2512
2624
|
end
|
@@ -2565,7 +2677,7 @@ END
|
|
2565
2677
|
private
|
2566
2678
|
|
2567
2679
|
class Options #:nodoc:
|
2568
|
-
attr_accessor :help, :version, :style, :filter, :color, :
|
2680
|
+
attr_accessor :help, :version, :style, :filter, :color, :skeleton, :generate, :faster
|
2569
2681
|
end
|
2570
2682
|
|
2571
2683
|
def option_parser(opts)
|
@@ -2592,7 +2704,7 @@ END
|
|
2592
2704
|
#; [!dptgn] '--color' is same as '--color=on'.
|
2593
2705
|
opts.color = val || 'on'
|
2594
2706
|
}
|
2595
|
-
parser.on('-
|
2707
|
+
parser.on('-S', '--skeleton') { opts.skeleton = true }
|
2596
2708
|
parser.on('-G', '--generate[=styleoption]') {|val|
|
2597
2709
|
val.nil? || val == 'unaryop' or
|
2598
2710
|
raise OptionParser::InvalidArgument, val
|
@@ -2607,16 +2719,16 @@ END
|
|
2607
2719
|
return HELP_MESSAGE % {command: command}
|
2608
2720
|
end
|
2609
2721
|
|
2610
|
-
HELP_MESSAGE = <<'END'
|
2722
|
+
HELP_MESSAGE = <<'END'.gsub(/^#.*\n/, '')
|
2611
2723
|
Usage: %{command} [<options>] [<file-or-directory>...]
|
2612
2724
|
-h, --help : show help
|
2613
2725
|
--version : print version
|
2614
2726
|
-s <REPORT-STYLE> : verbose/simple/compact/plain/quiet, or v/s/c/p/q
|
2615
2727
|
-F <PATTERN> : filter topic or spec with pattern (see below)
|
2616
2728
|
--color[={on|off}] : enable/disable output coloring forcedly
|
2617
|
-
-
|
2729
|
+
-S, --skeleton : print test code skeleton
|
2618
2730
|
-G, --generate : generate test code skeleton from ruby file
|
2619
|
-
--faster : make 'ok{}' faster (for very large project)
|
2731
|
+
# --faster : make 'ok{}' faster (for very large project)
|
2620
2732
|
|
2621
2733
|
Filter examples:
|
2622
2734
|
$ oktest -F topic=Hello # filter by topic
|
data/oktest.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.2.0 $
|
5
5
|
### $License: MIT License $
|
6
6
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
7
7
|
###
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.name = "oktest"
|
14
14
|
s.author = "kwatch"
|
15
15
|
s.email = "kwatch@gmail.com"
|
16
|
-
s.version = "$Release: 1.
|
16
|
+
s.version = "$Release: 1.2.0 $".split()[1]
|
17
17
|
s.license = "MIT"
|
18
18
|
s.platform = Gem::Platform::RUBY
|
19
19
|
s.homepage = "https://github.com/kwatch/oktest/tree/ruby"
|
@@ -30,7 +30,7 @@ Oktest.rb is a new-style testing library for Ruby.
|
|
30
30
|
|
31
31
|
See https://github.com/kwatch/oktest/tree/ruby/ruby for details.
|
32
32
|
END
|
33
|
-
s.required_ruby_version = ">= 2.
|
33
|
+
s.required_ruby_version = ">= 2.0"
|
34
34
|
s.add_dependency "diff-lcs", "~> 1.0"
|
35
35
|
s.add_dependency "benry-recorder", "~> 1.0"
|
36
36
|
|
data/test/assertion_test.rb
CHANGED
data/test/filter_test.rb
CHANGED
data/test/fixture_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.2.0 $
|
5
5
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
6
6
|
### $License: MIT License $
|
7
7
|
###
|
@@ -116,6 +116,19 @@ END
|
|
116
116
|
assert_eq sout, expected
|
117
117
|
end
|
118
118
|
|
119
|
+
it "[!gyyst] overwrites keyword params by fixture values." do
|
120
|
+
Oktest.scope do
|
121
|
+
topic "topic#1" do
|
122
|
+
fixture(:x) {|y, z: 3| {y: y, z: z} }
|
123
|
+
fixture(:y) { 2 }
|
124
|
+
spec("not overwrite") {|x| p x }
|
125
|
+
spec("overwrite", fixture: {y: 4, z: 5}) {|x| p x }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
sout = run_all()
|
129
|
+
assert_eq sout, "{:y=>2, :z=>3}\n{:y=>4, :z=>5}\n"
|
130
|
+
end
|
131
|
+
|
119
132
|
it "[!4xghy] calls fixture block with context object as self." do
|
120
133
|
Oktest.scope do
|
121
134
|
topic "Parent" do
|
data/test/generator_test.rb
CHANGED
data/test/helper_test.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
###
|
2
|
-
### $Release: 1.
|
2
|
+
### $Release: 1.2.0 $
|
3
3
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
4
4
|
### $License: MIT License $
|
5
5
|
###
|
@@ -36,7 +36,7 @@ class SpecHelper_TC < TC
|
|
36
36
|
it "[!bc3l2] records invoked location." do
|
37
37
|
lineno = __LINE__ + 1
|
38
38
|
o = ok {"bar"}
|
39
|
-
assert o.location.start_with?("#{__FILE__}:#{lineno}:")
|
39
|
+
assert o.location.to_s.start_with?("#{__FILE__}:#{lineno}:")
|
40
40
|
end
|
41
41
|
it "[!mqtdy] not record invoked location when `Config.ok_location == false`." do
|
42
42
|
bkup = Oktest::Config.ok_location
|
@@ -60,7 +60,7 @@ class SpecHelper_TC < TC
|
|
60
60
|
it "[!agmx8] records invoked location." do
|
61
61
|
lineno = __LINE__ + 1
|
62
62
|
o = not_ok {"bar"}
|
63
|
-
assert o.location.start_with?("#{__FILE__}:#{lineno}:")
|
63
|
+
assert o.location.to_s.start_with?("#{__FILE__}:#{lineno}:")
|
64
64
|
end
|
65
65
|
it "[!a9508] not record invoked location when `Config.ok_location == false`." do
|
66
66
|
bkup = Oktest::Config.ok_location
|