oktest 1.3.1 → 1.5.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/README.md +156 -18
- data/Rakefile.rb +1 -1
- data/benchmark/run_all.rb +1 -0
- data/bin/oktest +3 -0
- data/lib/oktest.rb +253 -143
- data/oktest.gemspec +4 -3
- data/test/{run_all.rb → all.rb} +1 -0
- data/test/assertion_test.rb +244 -229
- data/test/filter_test.rb +123 -120
- data/test/fixture_test.rb +34 -32
- data/test/generator_test.rb +26 -22
- data/test/helper_test.rb +382 -204
- data/test/init.rb +44 -0
- data/test/mainapp_test.rb +249 -199
- data/test/matcher_test.rb +157 -126
- data/test/misc_test.rb +32 -30
- data/test/nanot.rb +307 -0
- data/test/node_test.rb +321 -242
- data/test/reporter_test.rb +250 -208
- data/test/runner_test.rb +102 -100
- data/test/util_test.rb +197 -193
- data/test/utilhelper_test.rb +36 -38
- data/test/visitor_test.rb +55 -50
- metadata +21 -7
- data/test/initialize.rb +0 -21
- data/test/tc.rb +0 -127
data/lib/oktest.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
###
|
4
|
-
### $Release: 1.
|
5
|
+
### $Release: 1.5.0 $
|
5
6
|
### $Copyright: copyright(c) 2011-2024 kuwata-lab.com all rights reserved $
|
6
7
|
### $License: MIT License $
|
7
8
|
###
|
@@ -12,7 +13,7 @@ require 'set'
|
|
12
13
|
module Oktest
|
13
14
|
|
14
15
|
|
15
|
-
VERSION = '$Release: 1.
|
16
|
+
VERSION = '$Release: 1.5.0 $'.split()[1]
|
16
17
|
|
17
18
|
|
18
19
|
class OktestError < StandardError
|
@@ -380,6 +381,18 @@ module Oktest
|
|
380
381
|
return exc
|
381
382
|
end
|
382
383
|
|
384
|
+
def raise_nothing?()
|
385
|
+
__done()
|
386
|
+
#; [!leqey] do nothing without calling proc object.
|
387
|
+
proc_obj = @actual
|
388
|
+
if @bool
|
389
|
+
proc_obj.call
|
390
|
+
#; [!a61b7] not available with `.NOT`.
|
391
|
+
else
|
392
|
+
raise OktestError, "`raise_nothing?()` is not available with `.NOT`."
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
383
396
|
def throw?(expected)
|
384
397
|
__done()
|
385
398
|
proc_obj = @actual
|
@@ -858,17 +871,23 @@ END
|
|
858
871
|
end
|
859
872
|
|
860
873
|
def self.case_when(desc, tag: nil, &block)
|
861
|
-
#; [!g3cvh] returns topic object.
|
862
874
|
#; [!ofw1i] target is a description starting with 'When '.
|
863
|
-
|
875
|
+
#; [!53qxv] not add 'When ' if description starts with it.
|
876
|
+
rexp = /^(\[!\w+\] )?[wW]hen\b/
|
877
|
+
desc2 = desc =~ rexp ? desc : "When #{desc}"
|
878
|
+
#; [!g3cvh] returns topic object.
|
879
|
+
return __case_when(desc2, tag, &block)
|
864
880
|
end
|
865
881
|
|
866
882
|
def self.case_else(desc=nil, tag: nil, &block)
|
867
883
|
#; [!hs1to] 1st parameter is optional.
|
868
|
-
desc
|
869
|
-
#; [!oww4b] returns topic object.
|
884
|
+
desc ||= "Else"
|
870
885
|
#; [!j5gnp] target is a description which is 'Else'.
|
871
|
-
|
886
|
+
#; [!3nn8d] not add 'Else ' if description starts with it.
|
887
|
+
rexp = /^(\[!\w+\] )?[eE]lse\b/
|
888
|
+
desc2 = desc =~ rexp ? desc : "Else #{desc}"
|
889
|
+
#; [!oww4b] returns topic object.
|
890
|
+
return __case_when(desc2, tag, &block)
|
872
891
|
end
|
873
892
|
|
874
893
|
def self.__case_when(desc, tag, &block) #:nodoc:
|
@@ -1106,6 +1125,13 @@ END
|
|
1106
1125
|
attr_reader :target
|
1107
1126
|
attr_writer :_prefix
|
1108
1127
|
|
1128
|
+
def run_block_in_context_class(&block)
|
1129
|
+
#; [!i2kvj] run block in context class.
|
1130
|
+
#; [!pr3vj] run block with topic target as an argument.
|
1131
|
+
target = @target
|
1132
|
+
@context_class.class_exec(target, &block)
|
1133
|
+
end
|
1134
|
+
|
1109
1135
|
def _prefix
|
1110
1136
|
@_prefix || '*'
|
1111
1137
|
end
|
@@ -1215,6 +1241,13 @@ END
|
|
1215
1241
|
@_in_scope = false
|
1216
1242
|
end
|
1217
1243
|
|
1244
|
+
def self.topic(target, &block)
|
1245
|
+
#; [!c5j3f] same as `Oktest.scope do topic target do ... end end`.
|
1246
|
+
self.scope do
|
1247
|
+
topic(target, &block)
|
1248
|
+
end
|
1249
|
+
end
|
1250
|
+
|
1218
1251
|
|
1219
1252
|
module SpecHelper
|
1220
1253
|
|
@@ -1284,7 +1317,7 @@ END
|
|
1284
1317
|
(@__at_end_blocks ||= []) << block
|
1285
1318
|
end
|
1286
1319
|
|
1287
|
-
def
|
1320
|
+
def capture_stdio(input="", tty: false, &b)
|
1288
1321
|
require 'stringio' unless defined?(StringIO)
|
1289
1322
|
bkup = [$stdin, $stdout, $stderr]
|
1290
1323
|
#; [!53mai] takes $stdin data.
|
@@ -1306,6 +1339,58 @@ END
|
|
1306
1339
|
$stdin, $stdout, $stderr = bkup
|
1307
1340
|
end
|
1308
1341
|
|
1342
|
+
#; [!qjmaa] 'capture_sio()' is an alias of 'capture_stdio()'.
|
1343
|
+
alias capture_sio capture_stdio
|
1344
|
+
|
1345
|
+
def capture_stdout(input="", tty: false, &b)
|
1346
|
+
#; [!4agii] same as `sout, serr = capture_stdio(); ok {serr} == ''`.
|
1347
|
+
#; [!may84] fails when stderr is not empty.
|
1348
|
+
sout, serr = capture_stdio(input, tty: tty, &b)
|
1349
|
+
serr == "" or
|
1350
|
+
raise FAIL_EXCEPTION, "Output of $stderr expected to be empty, but got: #{serr.inspect}"
|
1351
|
+
#; [!5n04e] returns output of stdout.
|
1352
|
+
return sout
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
def capture_stderr(input="", tty: false, &b)
|
1356
|
+
#; [!46tj4] same as `sout, serr = capture_stdio(); ok {sout} == ''`.
|
1357
|
+
#; [!3zh32] fails when stdout is not empty.
|
1358
|
+
sout, serr = capture_stdio(input, tty: tty, &b)
|
1359
|
+
sout == "" or
|
1360
|
+
raise FAIL_EXCEPTION, "Output of $stdout expected to be empty, but got: #{sout.inspect}"
|
1361
|
+
#; [!5vs64] returns output of stderr.
|
1362
|
+
return serr
|
1363
|
+
end
|
1364
|
+
|
1365
|
+
def capture_command(command, input="", &error_handler)
|
1366
|
+
require 'open3' unless defined?(::Open3)
|
1367
|
+
#; [!wyp17] executes command with stdin data.
|
1368
|
+
sout, serr, pstat = ::Open3.capture3(command, :stdin_data=>input)
|
1369
|
+
#; [!jd63p] raises error if command failed.
|
1370
|
+
#; [!lsmgq] calls error handler block if command failed.
|
1371
|
+
#; [!vivq3] doesn't call error handler block if command finished successfully.
|
1372
|
+
#; [!nxw59] not raise error if command failed and error handler specified.
|
1373
|
+
if pstat.exitstatus != 0
|
1374
|
+
if block_given?()
|
1375
|
+
yield pstat
|
1376
|
+
else
|
1377
|
+
raise "Command failed with status (#{pstat.exitstatus}): `#{command}`"
|
1378
|
+
end
|
1379
|
+
end
|
1380
|
+
#; [!h5994] returns output of stdin and stderr.
|
1381
|
+
return sout, serr
|
1382
|
+
end
|
1383
|
+
|
1384
|
+
def capture_command!(command, input="", &error_handler)
|
1385
|
+
#; [!vlbpo] executes command with stdin data.
|
1386
|
+
#; [!yfohb] not raise error even if command failed.
|
1387
|
+
#; [!andyj] calls error handler block if command failed.
|
1388
|
+
#; [!xnkqc] doesn't call error handler block if command finished successfully.
|
1389
|
+
#; [!3xdgo] returns output of stdin and stderr.
|
1390
|
+
error_handler ||= proc do end
|
1391
|
+
capture_command(command, input, &error_handler)
|
1392
|
+
end
|
1393
|
+
|
1309
1394
|
def __do_dummy(val, recover, &b)
|
1310
1395
|
if block_given?()
|
1311
1396
|
begin
|
@@ -2097,9 +2182,6 @@ END
|
|
2097
2182
|
end
|
2098
2183
|
|
2099
2184
|
|
2100
|
-
REPORTER_CLASS = VerboseReporter
|
2101
|
-
|
2102
|
-
|
2103
2185
|
REPORTER_CLASSES = {
|
2104
2186
|
'verbose' => VerboseReporter, 'v' => VerboseReporter,
|
2105
2187
|
'simple' => SimpleReporter, 's' => SimpleReporter,
|
@@ -2108,10 +2190,22 @@ END
|
|
2108
2190
|
'quiet' => QuietReporter, 'q' => QuietReporter,
|
2109
2191
|
}
|
2110
2192
|
|
2193
|
+
DEFAULT_REPORTING_STYLE = 'verbose'
|
2194
|
+
|
2195
|
+
def self.DEFAULT_REPORTING_STYLE=(style)
|
2196
|
+
#; [!lbufd] raises error if unknown style specified.
|
2197
|
+
REPORTER_CLASSES.key?(style) or
|
2198
|
+
raise ArgumentError, "#{style}: Unknown reporting style."
|
2199
|
+
#; [!dsbmo] changes value of default reporting style.
|
2200
|
+
remove_const :DEFAULT_REPORTING_STYLE
|
2201
|
+
const_set :DEFAULT_REPORTING_STYLE, style
|
2202
|
+
end
|
2203
|
+
|
2111
2204
|
|
2112
2205
|
def self.run(reporter: nil, style: nil)
|
2113
2206
|
#; [!6xn3t] creates reporter object according to 'style:' keyword arg.
|
2114
|
-
|
2207
|
+
style ||= DEFAULT_REPORTING_STYLE
|
2208
|
+
klass = REPORTER_CLASSES[style] or
|
2115
2209
|
raise ArgumentError, "#{style.inspect}: unknown style."
|
2116
2210
|
reporter ||= klass.new
|
2117
2211
|
#; [!mn451] run test cases.
|
@@ -2419,12 +2513,12 @@ END
|
|
2419
2513
|
public
|
2420
2514
|
|
2421
2515
|
def filter_children!(node)
|
2422
|
-
_filter_children!(node)
|
2516
|
+
_filter_children!(node, 0)
|
2423
2517
|
end
|
2424
2518
|
|
2425
2519
|
private
|
2426
2520
|
|
2427
|
-
def _filter_children!(node) #:nodoc:
|
2521
|
+
def _filter_children!(node, _depth) #:nodoc:
|
2428
2522
|
#; [!r6g6a] supports negative filter by topic.
|
2429
2523
|
#; [!doozg] supports negative filter by spec.
|
2430
2524
|
#; [!ntv44] supports negative filter by tag name.
|
@@ -2445,7 +2539,7 @@ END
|
|
2445
2539
|
removes << i unless positive
|
2446
2540
|
#; [!mz6id] can filter nested topics.
|
2447
2541
|
elsif item.is_a?(Node)
|
2448
|
-
removes << i unless _filter_children!(item)
|
2542
|
+
removes << i unless _filter_children!(item, _depth+1)
|
2449
2543
|
#; [!1jphf] can filter specs from nested topics.
|
2450
2544
|
elsif item.is_a?(SpecLeaf)
|
2451
2545
|
removes << i if positive
|
@@ -2580,7 +2674,8 @@ END
|
|
2580
2674
|
_transform(child_tuple, depth+1, buf)
|
2581
2675
|
end
|
2582
2676
|
buf << "\n"
|
2583
|
-
buf << "#{indent} end
|
2677
|
+
buf << "#{indent} end\n" if keyword == 'def'
|
2678
|
+
buf << "#{indent} end # #{topic}\n" unless keyword == 'def'
|
2584
2679
|
buf << "\n"
|
2585
2680
|
end
|
2586
2681
|
end
|
@@ -2607,6 +2702,11 @@ END
|
|
2607
2702
|
|
2608
2703
|
class MainApp
|
2609
2704
|
|
2705
|
+
def initialize(command=nil)
|
2706
|
+
@command = command || File.basename($0)
|
2707
|
+
@schema = option_schema()
|
2708
|
+
end
|
2709
|
+
|
2610
2710
|
def self.main(argv=nil)
|
2611
2711
|
#; [!tb6sx] returns 0 when no errors raised.
|
2612
2712
|
#; [!d5mql] returns 1 when a certain error raised.
|
@@ -2617,48 +2717,40 @@ END
|
|
2617
2717
|
#; [!jr49p] reports error when unknown option specified.
|
2618
2718
|
#; [!uqomj] reports error when required argument is missing.
|
2619
2719
|
#; [!8i755] reports error when argument is invalid.
|
2620
|
-
rescue
|
2621
|
-
|
2622
|
-
when OptionParser::InvalidOption ; s = "unknown option."
|
2623
|
-
when OptionParser::InvalidArgument ; s = "invalid argument."
|
2624
|
-
when OptionParser::MissingArgument ; s = "argument required."
|
2625
|
-
else ; s = nil
|
2626
|
-
end
|
2627
|
-
msg = s ? "#{exc.args.join(' ')}: #{s}" : exc.message
|
2628
|
-
$stderr.puts("#{File.basename($0)}: #{msg}")
|
2720
|
+
rescue Benry::CmdOpt::OptionError => exc
|
2721
|
+
$stderr.puts("[ERROR] #{exc.message}")
|
2629
2722
|
return 1
|
2630
2723
|
end
|
2631
2724
|
end
|
2632
2725
|
|
2633
2726
|
def run(*args)
|
2634
2727
|
color_enabled = nil
|
2635
|
-
opts = Options.new
|
2636
|
-
parser = option_parser(opts)
|
2637
2728
|
#; [!v5xie] parses $OKTEST_RB environment variable.
|
2638
2729
|
if ENV.key?('OKTEST_RB')
|
2639
|
-
|
2730
|
+
args = ENV['OKTEST_RB'].split() + args
|
2640
2731
|
end
|
2641
|
-
|
2642
|
-
|
2732
|
+
#; [!tt2gj] parses command options even after filenames.
|
2733
|
+
opts = parse_opts(args)
|
2734
|
+
filenames = args
|
2643
2735
|
#; [!9973n] '-h' or '--help' option prints help message.
|
2644
|
-
if opts
|
2736
|
+
if opts[:help]
|
2645
2737
|
puts help_message()
|
2646
2738
|
return 0
|
2647
2739
|
end
|
2648
2740
|
#; [!qqizl] '--version' option prints version number.
|
2649
|
-
if opts
|
2741
|
+
if opts[:version]
|
2650
2742
|
puts VERSION
|
2651
2743
|
return 0
|
2652
2744
|
end
|
2653
2745
|
#; [!dk8eg] '-S' or '--skeleton' option prints test code skeleton.
|
2654
|
-
if opts
|
2655
|
-
print
|
2746
|
+
if opts[:skeleton]
|
2747
|
+
print skeleton()
|
2656
2748
|
return 0
|
2657
2749
|
end
|
2658
2750
|
#; [!uxh5e] '-G' or '--generate' option prints test code.
|
2659
2751
|
#; [!wmxu5] '--generate=unaryop' option prints test code with unary op.
|
2660
|
-
if opts
|
2661
|
-
print generate(filenames, opts
|
2752
|
+
if opts[:generate]
|
2753
|
+
print generate(filenames, opts[:generate])
|
2662
2754
|
return 0
|
2663
2755
|
end
|
2664
2756
|
#; [!65vdx] prints help message if no arguments specified.
|
@@ -2668,12 +2760,12 @@ END
|
|
2668
2760
|
end
|
2669
2761
|
#; [!6ro7j] '--color=on' option enables output coloring forcedly.
|
2670
2762
|
#; [!vmw0q] '--color=off' option disables output coloring forcedly.
|
2671
|
-
if opts
|
2763
|
+
if opts[:color] != nil
|
2672
2764
|
color_enabled = Config.color_enabled
|
2673
|
-
Config.color_enabled =
|
2765
|
+
Config.color_enabled = opts[:color]
|
2674
2766
|
end
|
2675
2767
|
#; [!qs8ab] '--faster' chanages 'Config.ok_location' to false.
|
2676
|
-
if opts
|
2768
|
+
if opts[:faster]
|
2677
2769
|
Config.ok_location = false # will make 'ok{}' faster
|
2678
2770
|
end
|
2679
2771
|
#
|
@@ -2685,8 +2777,8 @@ END
|
|
2685
2777
|
#; [!8uvib] '-F tag=...' option filters by tag name.
|
2686
2778
|
#; [!m0iwm] '-F sid=...' option filters by spec id.
|
2687
2779
|
#; [!noi8i] '-F' option supports negative filter.
|
2688
|
-
if opts
|
2689
|
-
filter_obj = FILTER_CLASS.create_from(opts
|
2780
|
+
if opts[:filter]
|
2781
|
+
filter_obj = FILTER_CLASS.create_from(opts[:filter])
|
2690
2782
|
Oktest.filter(filter_obj)
|
2691
2783
|
end
|
2692
2784
|
#; [!bim36] changes auto-running to off.
|
@@ -2697,7 +2789,7 @@ END
|
|
2697
2789
|
#; [!ef5v7] '-s compact' or '-sc' option prints test results in compact mode.
|
2698
2790
|
#; [!244te] '-s plain' or '-sp' option prints test results in plain mode.
|
2699
2791
|
#; [!ai61w] '-s quiet' or '-sq' option prints test results in quiet mode.
|
2700
|
-
n_errors = Oktest.run(:style=>opts
|
2792
|
+
n_errors = Oktest.run(:style=>opts[:style])
|
2701
2793
|
#; [!dsrae] reports if 'ok()' called but assertion not performed.
|
2702
2794
|
AssertionObject.report_not_yet()
|
2703
2795
|
#; [!bzgiw] returns total number of failures and errors.
|
@@ -2709,74 +2801,70 @@ END
|
|
2709
2801
|
|
2710
2802
|
private
|
2711
2803
|
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2804
|
+
def option_schema()
|
2805
|
+
require 'benry/cmdopt' unless defined?(::Benry::CmdOpt)
|
2806
|
+
reporting_styles = REPORTER_CLASSES.keys.partition {|s| s.length > 1 }.flatten()
|
2807
|
+
schema = Benry::CmdOpt::Schema.new()
|
2808
|
+
schema.add(:help , "-h, --help" , "show help")
|
2809
|
+
schema.add(:version , " --version", "print version")
|
2810
|
+
schema.add(:style , "-s <reporting-style>", "verbose/simple/compact/plain/quiet, or v/s/c/p/q",
|
2811
|
+
enum: reporting_styles)
|
2812
|
+
#; [!71h2x] '-F ...' option will be error.
|
2813
|
+
#; [!j01y7] if filerting by '-F' matched nothing, then prints zero result.
|
2814
|
+
schema.add(:filter , "-F <key>=<pattern>", "filter topic or spec with pattern (see below)",
|
2815
|
+
rexp: /\A(topic|spec|tag|sid)(=|!=)/)
|
2816
|
+
#; [!dptgn] '--color' is same as '--color=on'.
|
2817
|
+
schema.add(:color , " --color[=<on|off>]", "enable/disable output coloring forcedly",
|
2818
|
+
type: TrueClass)
|
2819
|
+
schema.add(:skeleton, "-S, --skeleton", "print test code skeleton")
|
2820
|
+
schema.add(:generate, "-G, --generate[=<style>]", "generate test code skeleton from ruby file",
|
2821
|
+
enum: ['unaryop'])
|
2822
|
+
schema.add(:faster , " --faster" , "make 'ok{}' faster (for very large project)",
|
2823
|
+
hidden: true)
|
2824
|
+
return schema
|
2825
|
+
end
|
2826
|
+
|
2827
|
+
def parse_opts(args)
|
2828
|
+
parser = Benry::CmdOpt::Parser.new(@schema)
|
2829
|
+
return parser.parse(args, all: true)
|
2830
|
+
end
|
2831
|
+
|
2832
|
+
def help_message()
|
2833
|
+
command = @command
|
2834
|
+
schema = @schema
|
2835
|
+
#; [!v938d] help message will be colored only when stdout is a tty.
|
2836
|
+
if $stdout.tty?
|
2837
|
+
bold = proc {|s| "\e[1m#{s}\e[0m" } # bold
|
2838
|
+
header = proc {|s| "\e[36m#{s}\e[0m" } # cyan
|
2839
|
+
else
|
2840
|
+
bold = header = proc {|s| s }
|
2841
|
+
end
|
2842
|
+
return <<"END"
|
2843
|
+
#{bold.('Oktest')} (#{VERSION}) -- New style testing library
|
2715
2844
|
|
2716
|
-
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2728
|
-
|
2729
|
-
|
2730
|
-
|
2731
|
-
opts.filter = val
|
2732
|
-
}
|
2733
|
-
parser.on( '--color[={on|off}]') {|val|
|
2734
|
-
#; [!9nr94] '--color=true' option raises error.
|
2735
|
-
val.nil? || val == 'on' || val == 'off' or
|
2736
|
-
raise OptionParser::InvalidArgument, val
|
2737
|
-
#; [!dptgn] '--color' is same as '--color=on'.
|
2738
|
-
opts.color = val || 'on'
|
2739
|
-
}
|
2740
|
-
parser.on('-S', '--skeleton') { opts.skeleton = true }
|
2741
|
-
parser.on('-G', '--generate[=styleoption]') {|val|
|
2742
|
-
val.nil? || val == 'unaryop' or
|
2743
|
-
raise OptionParser::InvalidArgument, val
|
2744
|
-
opts.generate = val || true
|
2745
|
-
}
|
2746
|
-
parser.on( '--faster') { opts.faster = true }
|
2747
|
-
return parser
|
2748
|
-
end
|
2749
|
-
|
2750
|
-
def help_message(command=nil)
|
2751
|
-
command ||= File.basename($0)
|
2752
|
-
return HELP_MESSAGE % {command: command}
|
2753
|
-
end
|
2754
|
-
|
2755
|
-
HELP_MESSAGE = <<'END'.gsub(/^#.*\n/, '')
|
2756
|
-
Usage: %{command} [<options>] [<file-or-directory>...]
|
2757
|
-
-h, --help : show help
|
2758
|
-
--version : print version
|
2759
|
-
-s <REPORT-STYLE> : verbose/simple/compact/plain/quiet, or v/s/c/p/q
|
2760
|
-
-F <PATTERN> : filter topic or spec with pattern (see below)
|
2761
|
-
--color[={on|off}] : enable/disable output coloring forcedly
|
2762
|
-
-S, --skeleton : print test code skeleton
|
2763
|
-
-G, --generate : generate test code skeleton from ruby file
|
2764
|
-
# --faster : make 'ok{}' faster (for very large project)
|
2765
|
-
|
2766
|
-
Filter examples:
|
2767
|
-
$ oktest -F topic=Hello # filter by topic
|
2768
|
-
$ oktest -F spec='*hello*' # filter by spec
|
2769
|
-
$ oktest -F tag=name # filter by tag name
|
2770
|
-
$ oktest -F tag!=name # negative filter by tag name
|
2771
|
-
$ oktest -F tag='{name1,name2}' # filter by multiple tag names
|
2772
|
-
|
2773
|
-
See https://github.com/kwatch/oktest/blob/ruby/ruby/README.md for details.
|
2845
|
+
#{header.('Usage:')}
|
2846
|
+
$ #{bold.(command)} [<options>] [<file|directory>...]
|
2847
|
+
|
2848
|
+
#{header.('Options:')}
|
2849
|
+
#{schema.to_s.chomp}
|
2850
|
+
|
2851
|
+
#{header.('Filter Examples:')}
|
2852
|
+
$ #{command} -F topic=Hello # filter by topic
|
2853
|
+
$ #{command} -F spec='*hello*' # filter by spec
|
2854
|
+
$ #{command} -F tag=name # filter by tag name
|
2855
|
+
$ #{command} -F tag!=name # negative filter by tag name
|
2856
|
+
$ #{command} -F tag='{name1,name2}' # filter by multiple tag names
|
2857
|
+
|
2858
|
+
#{header.('Document:')}
|
2859
|
+
https://github.com/kwatch/oktest/blob/ruby/ruby/README.md
|
2774
2860
|
END
|
2861
|
+
end
|
2775
2862
|
|
2776
2863
|
def load_files(filenames)
|
2777
2864
|
filenames.each do |fname|
|
2865
|
+
#; [!k402d] raises error if file not found.
|
2778
2866
|
File.exist?(fname) or
|
2779
|
-
raise
|
2867
|
+
raise Benry::CmdOpt::OptionError, "#{fname}: not found."
|
2780
2868
|
end
|
2781
2869
|
filenames.each do |fname|
|
2782
2870
|
File.directory?(fname) ? load_dir(fname) : load(fname)
|
@@ -2801,49 +2889,15 @@ END
|
|
2801
2889
|
return buf.join()
|
2802
2890
|
end
|
2803
2891
|
|
2804
|
-
|
2805
|
-
|
2806
|
-
|
2807
|
-
|
2808
|
-
|
2809
|
-
|
2810
|
-
Oktest.scope do
|
2811
|
-
|
2812
|
-
fixture :alice do
|
2813
|
-
{name: "Alice"}
|
2814
|
-
end
|
2815
|
-
fixture :bob do
|
2816
|
-
{name: "Bob"}
|
2817
|
-
end
|
2818
|
-
|
2819
|
-
topic Class do
|
2820
|
-
|
2821
|
-
before do nil end
|
2822
|
-
after do nil end
|
2823
|
-
before_all do nil end
|
2824
|
-
after_all do nil end
|
2825
|
-
|
2826
|
-
topic '#method_name()' do
|
2827
|
-
|
2828
|
-
spec "1+1 should be 2." do
|
2829
|
-
ok {1+1} == 2
|
2830
|
-
end
|
2831
|
-
|
2832
|
-
spec "fixture injection examle." do
|
2833
|
-
|alice, bob|
|
2834
|
-
ok {alice[:name]} == "Alice"
|
2835
|
-
ok {bob[:name]} == "Bob"
|
2836
|
-
end
|
2837
|
-
|
2892
|
+
def skeleton()
|
2893
|
+
#; [!s2i1p] returns skeleton string of test script.
|
2894
|
+
#; [!opvik] skeleton string is valid ruby code.
|
2895
|
+
str = File.read(__FILE__, encoding: 'utf-8')
|
2896
|
+
return str.split(/^__END__\n/, 2)[1]
|
2838
2897
|
end
|
2839
2898
|
|
2840
2899
|
end
|
2841
2900
|
|
2842
|
-
end
|
2843
|
-
END
|
2844
|
-
|
2845
|
-
end
|
2846
|
-
|
2847
2901
|
|
2848
2902
|
def self.main(argv=nil)
|
2849
2903
|
status = MainApp.main(argv)
|
@@ -2876,3 +2930,59 @@ if __FILE__ == $0
|
|
2876
2930
|
$LOADED_FEATURES << File.expand_path(__FILE__) # avoid loading oktest.rb twice
|
2877
2931
|
Oktest.main() # run test scripts
|
2878
2932
|
end
|
2933
|
+
|
2934
|
+
|
2935
|
+
__END__
|
2936
|
+
# coding: utf-8
|
2937
|
+
|
2938
|
+
## see https://github.com/kwatch/oktest/blob/ruby/ruby/README.md for details.
|
2939
|
+
require 'oktest'
|
2940
|
+
|
2941
|
+
|
2942
|
+
## define common fixtures or helper methods in global scope block.
|
2943
|
+
## (strongly recommended to separate global scope block into a dedicated file.)
|
2944
|
+
Oktest.global_scope do
|
2945
|
+
|
2946
|
+
fixture :alice do # global fixture example
|
2947
|
+
{name: "Alice"}
|
2948
|
+
end
|
2949
|
+
|
2950
|
+
end
|
2951
|
+
|
2952
|
+
|
2953
|
+
## define test cases and fixtures in normal scope block.
|
2954
|
+
Oktest.scope do
|
2955
|
+
|
2956
|
+
fixture :bob do # local fixture example
|
2957
|
+
{name: "Bob"}
|
2958
|
+
end
|
2959
|
+
|
2960
|
+
topic Class do
|
2961
|
+
|
2962
|
+
before do nil end
|
2963
|
+
after do nil end
|
2964
|
+
before_all do nil end
|
2965
|
+
after_all do nil end
|
2966
|
+
|
2967
|
+
topic '#method_name()' do
|
2968
|
+
|
2969
|
+
spec "1+1 should be 2." do
|
2970
|
+
ok {1+1} == 2
|
2971
|
+
end
|
2972
|
+
|
2973
|
+
spec "1/0 should raise error." do
|
2974
|
+
pr = proc { 1/0 }
|
2975
|
+
ok {pr}.raise?(ZeroDivisionError, /divided by 0/)
|
2976
|
+
end
|
2977
|
+
|
2978
|
+
spec "fixture injection examle." do
|
2979
|
+
|alice, bob|
|
2980
|
+
ok {alice[:name]} == "Alice"
|
2981
|
+
ok {bob[:name]} == "Bob"
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
end
|
2985
|
+
|
2986
|
+
end
|
2987
|
+
|
2988
|
+
end
|
data/oktest.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.5.0 $
|
5
5
|
### $License: MIT License $
|
6
6
|
### $Copyright: copyright(c) 2011-2024 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.5.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/ruby"
|
@@ -31,6 +31,7 @@ See https://github.com/kwatch/oktest/tree/ruby/ruby for details.
|
|
31
31
|
END
|
32
32
|
s.required_ruby_version = ">= 2.4"
|
33
33
|
s.add_dependency "diff-lcs", "~> 1.0"
|
34
|
+
s.add_dependency "benry-cmdopt", "~> 2.3"
|
34
35
|
s.add_dependency "benry-recorder", "~> 1.0"
|
35
36
|
|
36
37
|
## files
|
@@ -40,5 +41,5 @@ END
|
|
40
41
|
s.files = files
|
41
42
|
s.executables = ['oktest']
|
42
43
|
s.bindir = 'bin'
|
43
|
-
s.test_file = 'test/
|
44
|
+
s.test_file = 'test/all.rb'
|
44
45
|
end
|