oktest 1.3.1 → 1.5.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 +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
|