oktest 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/oktest.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 1.1.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.1.1 $'.split()[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 = caller(1).first # caller() makes performance slower, but necessary.
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 = caller(1).first # caller() makes performance slower, but necessary.
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="") #:nodoc:
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 = caller(1).first # caller() makes performance slower, but necessary.
1142
- filename = location =~ /:\d+/ ? $` : nil
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 = caller(1).first # caller() makes performance slower, but necessary.
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 = caller(1).first # caller() makes performance slower, but necessary.
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([caller(1).first])
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 = caller(1).first # ex: "foo_test.rb:123:in ...."
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=nil, _resolved={}, _resolving=[])
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
- _resolved[:this_topic] = node.target if !_resolved.key?(:this_topic) && node.topic?
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
- _resolved[:this_spec] = spec.desc if !_resolved.key?(:this_spec)
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, _resolved, _resolving)
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=nil, _resolved={}, _resolving=[])
1662
- return _resolved[name] if _resolved.key?(name)
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, _resolved, _resolving)
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
- val = context.instance_eval(&block)
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
- _resolved[name] = val
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, _resolved, _resolving)
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, _resolved, _resolving)
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[22m"; end
2346
- def black s; return "\e[1;30m#{s}\e[0m"; end
2347
- def red s; return "\e[1;31m#{s}\e[0m"; end
2348
- def green s; return "\e[1;32m#{s}\e[0m"; end
2349
- def yellow s; return "\e[1;33m#{s}\e[0m"; end
2350
- def blue s; return "\e[1;34m#{s}\e[0m"; end
2351
- def magenta s; return "\e[1;35m#{s}\e[0m"; end
2352
- def cyan s; return "\e[1;36m#{s}\e[0m"; end
2353
- def white s; return "\e[1;37m#{s}\e[0m"; end
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 ? blue(s) : s; end
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 ? red(s) : s; end
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] '-C' or '--create' option prints test code skeleton.
2509
- if opts.create
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, :create, :generate, :faster
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('-C', '--create') { opts.create = true }
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
- -C, --create : print test code skeleton
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.1.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.1.1 $".split()[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.3"
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
 
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 1.1.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
  ###
data/test/filter_test.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 1.1.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
  ###
data/test/fixture_test.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 1.1.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
@@ -1,5 +1,5 @@
1
1
  ###
2
- ### $Release: 1.1.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
  ###
data/test/helper_test.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  ###
2
- ### $Release: 1.1.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
data/test/initialize.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  ###
4
- ### $Release: 1.1.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
  ###