oktest 1.3.0 → 1.4.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 +116 -15
- data/Rakefile.rb +1 -1
- data/benchmark/run_all.rb +1 -0
- data/bin/oktest +3 -0
- data/lib/oktest.rb +223 -136
- data/oktest.gemspec +11 -11
- data/test/assertion_test.rb +19 -6
- data/test/filter_test.rb +2 -1
- data/test/fixture_test.rb +2 -1
- data/test/generator_test.rb +7 -4
- data/test/helper_test.rb +180 -8
- data/test/initialize.rb +2 -1
- data/test/mainapp_test.rb +85 -39
- data/test/matcher_test.rb +2 -1
- data/test/misc_test.rb +2 -1
- data/test/node_test.rb +36 -1
- data/test/reporter_test.rb +2 -1
- data/test/run_all.rb +1 -0
- data/test/runner_test.rb +2 -1
- data/test/tc.rb +1 -0
- data/test/util_test.rb +3 -2
- data/test/utilhelper_test.rb +2 -1
- data/test/visitor_test.rb +2 -1
- metadata +28 -15
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.4.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.4.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:
|
@@ -1284,7 +1303,7 @@ END
|
|
1284
1303
|
(@__at_end_blocks ||= []) << block
|
1285
1304
|
end
|
1286
1305
|
|
1287
|
-
def
|
1306
|
+
def capture_stdio(input="", tty: false, &b)
|
1288
1307
|
require 'stringio' unless defined?(StringIO)
|
1289
1308
|
bkup = [$stdin, $stdout, $stderr]
|
1290
1309
|
#; [!53mai] takes $stdin data.
|
@@ -1306,6 +1325,58 @@ END
|
|
1306
1325
|
$stdin, $stdout, $stderr = bkup
|
1307
1326
|
end
|
1308
1327
|
|
1328
|
+
#; [!qjmaa] 'capture_sio()' is an alias of 'capture_stdio()'.
|
1329
|
+
alias capture_sio capture_stdio
|
1330
|
+
|
1331
|
+
def capture_stdout(input="", tty: false, &b)
|
1332
|
+
#; [!4agii] same as `sout, serr = capture_stdio(); ok {serr} == ''`.
|
1333
|
+
#; [!may84] fails when stderr is not empty.
|
1334
|
+
sout, serr = capture_stdio(input, tty: tty, &b)
|
1335
|
+
serr == "" or
|
1336
|
+
raise FAIL_EXCEPTION, "Output of $stderr expected to be empty, but got: #{serr.inspect}"
|
1337
|
+
#; [!5n04e] returns output of stdout.
|
1338
|
+
return sout
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
def capture_stderr(input="", tty: false, &b)
|
1342
|
+
#; [!46tj4] same as `sout, serr = capture_stdio(); ok {sout} == ''`.
|
1343
|
+
#; [!3zh32] fails when stdout is not empty.
|
1344
|
+
sout, serr = capture_stdio(input, tty: tty, &b)
|
1345
|
+
sout == "" or
|
1346
|
+
raise FAIL_EXCEPTION, "Output of $stdout expected to be empty, but got: #{sout.inspect}"
|
1347
|
+
#; [!5vs64] returns output of stderr.
|
1348
|
+
return serr
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
def capture_command(command, input="", &error_handler)
|
1352
|
+
require 'open3' unless defined?(::Open3)
|
1353
|
+
#; [!wyp17] executes command with stdin data.
|
1354
|
+
sout, serr, pstat = ::Open3.capture3(command, :stdin_data=>input)
|
1355
|
+
#; [!jd63p] raises error if command failed.
|
1356
|
+
#; [!lsmgq] calls error handler block if command failed.
|
1357
|
+
#; [!vivq3] doesn't call error handler block if command finished successfully.
|
1358
|
+
#; [!nxw59] not raise error if command failed and error handler specified.
|
1359
|
+
if pstat.exitstatus != 0
|
1360
|
+
if block_given?()
|
1361
|
+
yield pstat
|
1362
|
+
else
|
1363
|
+
raise "Command failed with status (#{pstat.exitstatus}): `#{command}`"
|
1364
|
+
end
|
1365
|
+
end
|
1366
|
+
#; [!h5994] returns output of stdin and stderr.
|
1367
|
+
return sout, serr
|
1368
|
+
end
|
1369
|
+
|
1370
|
+
def capture_command!(command, input="", &error_handler)
|
1371
|
+
#; [!vlbpo] executes command with stdin data.
|
1372
|
+
#; [!yfohb] not raise error even if command failed.
|
1373
|
+
#; [!andyj] calls error handler block if command failed.
|
1374
|
+
#; [!xnkqc] doesn't call error handler block if command finished successfully.
|
1375
|
+
#; [!3xdgo] returns output of stdin and stderr.
|
1376
|
+
error_handler ||= proc do end
|
1377
|
+
capture_command(command, input, &error_handler)
|
1378
|
+
end
|
1379
|
+
|
1309
1380
|
def __do_dummy(val, recover, &b)
|
1310
1381
|
if block_given?()
|
1311
1382
|
begin
|
@@ -2580,7 +2651,8 @@ END
|
|
2580
2651
|
_transform(child_tuple, depth+1, buf)
|
2581
2652
|
end
|
2582
2653
|
buf << "\n"
|
2583
|
-
buf << "#{indent} end
|
2654
|
+
buf << "#{indent} end\n" if keyword == 'def'
|
2655
|
+
buf << "#{indent} end # #{topic}\n" unless keyword == 'def'
|
2584
2656
|
buf << "\n"
|
2585
2657
|
end
|
2586
2658
|
end
|
@@ -2607,6 +2679,11 @@ END
|
|
2607
2679
|
|
2608
2680
|
class MainApp
|
2609
2681
|
|
2682
|
+
def initialize(command=nil)
|
2683
|
+
@command = command || File.basename($0)
|
2684
|
+
@schema = option_schema()
|
2685
|
+
end
|
2686
|
+
|
2610
2687
|
def self.main(argv=nil)
|
2611
2688
|
#; [!tb6sx] returns 0 when no errors raised.
|
2612
2689
|
#; [!d5mql] returns 1 when a certain error raised.
|
@@ -2617,48 +2694,40 @@ END
|
|
2617
2694
|
#; [!jr49p] reports error when unknown option specified.
|
2618
2695
|
#; [!uqomj] reports error when required argument is missing.
|
2619
2696
|
#; [!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}")
|
2697
|
+
rescue Benry::CmdOpt::OptionError => exc
|
2698
|
+
$stderr.puts("[ERROR] #{exc.message}")
|
2629
2699
|
return 1
|
2630
2700
|
end
|
2631
2701
|
end
|
2632
2702
|
|
2633
2703
|
def run(*args)
|
2634
2704
|
color_enabled = nil
|
2635
|
-
opts = Options.new
|
2636
|
-
parser = option_parser(opts)
|
2637
2705
|
#; [!v5xie] parses $OKTEST_RB environment variable.
|
2638
2706
|
if ENV.key?('OKTEST_RB')
|
2639
|
-
|
2707
|
+
args = ENV['OKTEST_RB'].split() + args
|
2640
2708
|
end
|
2641
|
-
|
2642
|
-
|
2709
|
+
#; [!tt2gj] parses command options even after filenames.
|
2710
|
+
opts = parse_opts(args)
|
2711
|
+
filenames = args
|
2643
2712
|
#; [!9973n] '-h' or '--help' option prints help message.
|
2644
|
-
if opts
|
2713
|
+
if opts[:help]
|
2645
2714
|
puts help_message()
|
2646
2715
|
return 0
|
2647
2716
|
end
|
2648
2717
|
#; [!qqizl] '--version' option prints version number.
|
2649
|
-
if opts
|
2718
|
+
if opts[:version]
|
2650
2719
|
puts VERSION
|
2651
2720
|
return 0
|
2652
2721
|
end
|
2653
2722
|
#; [!dk8eg] '-S' or '--skeleton' option prints test code skeleton.
|
2654
|
-
if opts
|
2655
|
-
print
|
2723
|
+
if opts[:skeleton]
|
2724
|
+
print skeleton()
|
2656
2725
|
return 0
|
2657
2726
|
end
|
2658
2727
|
#; [!uxh5e] '-G' or '--generate' option prints test code.
|
2659
2728
|
#; [!wmxu5] '--generate=unaryop' option prints test code with unary op.
|
2660
|
-
if opts
|
2661
|
-
print generate(filenames, opts
|
2729
|
+
if opts[:generate]
|
2730
|
+
print generate(filenames, opts[:generate])
|
2662
2731
|
return 0
|
2663
2732
|
end
|
2664
2733
|
#; [!65vdx] prints help message if no arguments specified.
|
@@ -2668,12 +2737,12 @@ END
|
|
2668
2737
|
end
|
2669
2738
|
#; [!6ro7j] '--color=on' option enables output coloring forcedly.
|
2670
2739
|
#; [!vmw0q] '--color=off' option disables output coloring forcedly.
|
2671
|
-
if opts
|
2740
|
+
if opts[:color] != nil
|
2672
2741
|
color_enabled = Config.color_enabled
|
2673
|
-
Config.color_enabled =
|
2742
|
+
Config.color_enabled = opts[:color]
|
2674
2743
|
end
|
2675
2744
|
#; [!qs8ab] '--faster' chanages 'Config.ok_location' to false.
|
2676
|
-
if opts
|
2745
|
+
if opts[:faster]
|
2677
2746
|
Config.ok_location = false # will make 'ok{}' faster
|
2678
2747
|
end
|
2679
2748
|
#
|
@@ -2685,8 +2754,8 @@ END
|
|
2685
2754
|
#; [!8uvib] '-F tag=...' option filters by tag name.
|
2686
2755
|
#; [!m0iwm] '-F sid=...' option filters by spec id.
|
2687
2756
|
#; [!noi8i] '-F' option supports negative filter.
|
2688
|
-
if opts
|
2689
|
-
filter_obj = FILTER_CLASS.create_from(opts
|
2757
|
+
if opts[:filter]
|
2758
|
+
filter_obj = FILTER_CLASS.create_from(opts[:filter])
|
2690
2759
|
Oktest.filter(filter_obj)
|
2691
2760
|
end
|
2692
2761
|
#; [!bim36] changes auto-running to off.
|
@@ -2697,7 +2766,7 @@ END
|
|
2697
2766
|
#; [!ef5v7] '-s compact' or '-sc' option prints test results in compact mode.
|
2698
2767
|
#; [!244te] '-s plain' or '-sp' option prints test results in plain mode.
|
2699
2768
|
#; [!ai61w] '-s quiet' or '-sq' option prints test results in quiet mode.
|
2700
|
-
n_errors = Oktest.run(:style=>opts
|
2769
|
+
n_errors = Oktest.run(:style=>opts[:style])
|
2701
2770
|
#; [!dsrae] reports if 'ok()' called but assertion not performed.
|
2702
2771
|
AssertionObject.report_not_yet()
|
2703
2772
|
#; [!bzgiw] returns total number of failures and errors.
|
@@ -2709,74 +2778,70 @@ END
|
|
2709
2778
|
|
2710
2779
|
private
|
2711
2780
|
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2781
|
+
def option_schema()
|
2782
|
+
require 'benry/cmdopt' unless defined?(::Benry::CmdOpt)
|
2783
|
+
reporting_styles = REPORTER_CLASSES.keys.partition {|s| s.length > 1 }.flatten()
|
2784
|
+
schema = Benry::CmdOpt::Schema.new()
|
2785
|
+
schema.add(:help , "-h, --help" , "show help")
|
2786
|
+
schema.add(:version , " --version", "print version")
|
2787
|
+
schema.add(:style , "-s <reporting-style>", "verbose/simple/compact/plain/quiet, or v/s/c/p/q",
|
2788
|
+
enum: reporting_styles)
|
2789
|
+
#; [!71h2x] '-F ...' option will be error.
|
2790
|
+
#; [!j01y7] if filerting by '-F' matched nothing, then prints zero result.
|
2791
|
+
schema.add(:filter , "-F <key>=<pattern>", "filter topic or spec with pattern (see below)",
|
2792
|
+
rexp: /\A(topic|spec|tag|sid)(=|!=)/)
|
2793
|
+
#; [!dptgn] '--color' is same as '--color=on'.
|
2794
|
+
schema.add(:color , " --color[=<on|off>]", "enable/disable output coloring forcedly",
|
2795
|
+
type: TrueClass)
|
2796
|
+
schema.add(:skeleton, "-S, --skeleton", "print test code skeleton")
|
2797
|
+
schema.add(:generate, "-G, --generate[=<style>]", "generate test code skeleton from ruby file",
|
2798
|
+
enum: ['unaryop'])
|
2799
|
+
schema.add(:faster , " --faster" , "make 'ok{}' faster (for very large project)",
|
2800
|
+
hidden: true)
|
2801
|
+
return schema
|
2802
|
+
end
|
2803
|
+
|
2804
|
+
def parse_opts(args)
|
2805
|
+
parser = Benry::CmdOpt::Parser.new(@schema)
|
2806
|
+
return parser.parse(args, all: true)
|
2807
|
+
end
|
2808
|
+
|
2809
|
+
def help_message()
|
2810
|
+
command = @command
|
2811
|
+
schema = @schema
|
2812
|
+
#; [!v938d] help message will be colored only when stdout is a tty.
|
2813
|
+
if $stdout.tty?
|
2814
|
+
bold = proc {|s| "\e[1m#{s}\e[0m" } # bold
|
2815
|
+
header = proc {|s| "\e[36m#{s}\e[0m" } # cyan
|
2816
|
+
else
|
2817
|
+
bold = header = proc {|s| s }
|
2818
|
+
end
|
2819
|
+
return <<"END"
|
2820
|
+
#{bold.('Oktest')} (#{VERSION}) -- New style testing library
|
2715
2821
|
|
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.
|
2822
|
+
#{header.('Usage:')}
|
2823
|
+
$ #{bold.(command)} [<options>] [<file|directory>...]
|
2824
|
+
|
2825
|
+
#{header.('Options:')}
|
2826
|
+
#{schema.to_s.chomp}
|
2827
|
+
|
2828
|
+
#{header.('Filter Examples:')}
|
2829
|
+
$ #{command} -F topic=Hello # filter by topic
|
2830
|
+
$ #{command} -F spec='*hello*' # filter by spec
|
2831
|
+
$ #{command} -F tag=name # filter by tag name
|
2832
|
+
$ #{command} -F tag!=name # negative filter by tag name
|
2833
|
+
$ #{command} -F tag='{name1,name2}' # filter by multiple tag names
|
2834
|
+
|
2835
|
+
#{header.('Document:')}
|
2836
|
+
https://github.com/kwatch/oktest/blob/ruby/ruby/README.md
|
2774
2837
|
END
|
2838
|
+
end
|
2775
2839
|
|
2776
2840
|
def load_files(filenames)
|
2777
2841
|
filenames.each do |fname|
|
2842
|
+
#; [!k402d] raises error if file not found.
|
2778
2843
|
File.exist?(fname) or
|
2779
|
-
raise
|
2844
|
+
raise Benry::CmdOpt::OptionError, "#{fname}: not found."
|
2780
2845
|
end
|
2781
2846
|
filenames.each do |fname|
|
2782
2847
|
File.directory?(fname) ? load_dir(fname) : load(fname)
|
@@ -2801,49 +2866,15 @@ END
|
|
2801
2866
|
return buf.join()
|
2802
2867
|
end
|
2803
2868
|
|
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
|
-
|
2869
|
+
def skeleton()
|
2870
|
+
#; [!s2i1p] returns skeleton string of test script.
|
2871
|
+
#; [!opvik] skeleton string is valid ruby code.
|
2872
|
+
str = File.read(__FILE__, encoding: 'utf-8')
|
2873
|
+
return str.split(/^__END__\n/, 2)[1]
|
2838
2874
|
end
|
2839
2875
|
|
2840
2876
|
end
|
2841
2877
|
|
2842
|
-
end
|
2843
|
-
END
|
2844
|
-
|
2845
|
-
end
|
2846
|
-
|
2847
2878
|
|
2848
2879
|
def self.main(argv=nil)
|
2849
2880
|
status = MainApp.main(argv)
|
@@ -2876,3 +2907,59 @@ if __FILE__ == $0
|
|
2876
2907
|
$LOADED_FEATURES << File.expand_path(__FILE__) # avoid loading oktest.rb twice
|
2877
2908
|
Oktest.main() # run test scripts
|
2878
2909
|
end
|
2910
|
+
|
2911
|
+
|
2912
|
+
__END__
|
2913
|
+
# coding: utf-8
|
2914
|
+
|
2915
|
+
## see https://github.com/kwatch/oktest/blob/ruby/ruby/README.md for details.
|
2916
|
+
require 'oktest'
|
2917
|
+
|
2918
|
+
|
2919
|
+
## define common fixtures or helper methods in global scope block.
|
2920
|
+
## (strongly recommended to separate global scope block into a dedicated file.)
|
2921
|
+
Oktest.global_scope do
|
2922
|
+
|
2923
|
+
fixture :alice do # global fixture example
|
2924
|
+
{name: "Alice"}
|
2925
|
+
end
|
2926
|
+
|
2927
|
+
end
|
2928
|
+
|
2929
|
+
|
2930
|
+
## define test cases and fixtures in normal scope block.
|
2931
|
+
Oktest.scope do
|
2932
|
+
|
2933
|
+
fixture :bob do # local fixture example
|
2934
|
+
{name: "Bob"}
|
2935
|
+
end
|
2936
|
+
|
2937
|
+
topic Class do
|
2938
|
+
|
2939
|
+
before do nil end
|
2940
|
+
after do nil end
|
2941
|
+
before_all do nil end
|
2942
|
+
after_all do nil end
|
2943
|
+
|
2944
|
+
topic '#method_name()' do
|
2945
|
+
|
2946
|
+
spec "1+1 should be 2." do
|
2947
|
+
ok {1+1} == 2
|
2948
|
+
end
|
2949
|
+
|
2950
|
+
spec "1/0 should raise error." do
|
2951
|
+
pr = proc { 1/0 }
|
2952
|
+
ok {pr}.raise?(ZeroDivisionError, /divided by 0/)
|
2953
|
+
end
|
2954
|
+
|
2955
|
+
spec "fixture injection examle." do
|
2956
|
+
|alice, bob|
|
2957
|
+
ok {alice[:name]} == "Alice"
|
2958
|
+
ok {bob[:name]} == "Bob"
|
2959
|
+
end
|
2960
|
+
|
2961
|
+
end
|
2962
|
+
|
2963
|
+
end
|
2964
|
+
|
2965
|
+
end
|
data/oktest.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.4.0 $
|
5
5
|
### $License: MIT License $
|
6
6
|
### $Copyright: copyright(c) 2011-2024 kuwata-lab.com all rights reserved $
|
7
7
|
###
|
@@ -13,25 +13,25 @@ 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.4.0 $".split()[1]
|
17
17
|
s.license = "MIT"
|
18
18
|
s.platform = Gem::Platform::RUBY
|
19
|
-
s.homepage = "https://github.com/kwatch/oktest/tree/ruby"
|
20
|
-
s.summary = "new style testing library"
|
19
|
+
s.homepage = "https://github.com/kwatch/oktest/tree/ruby/ruby"
|
20
|
+
s.summary = "a new style testing library"
|
21
21
|
s.description = <<'END'
|
22
22
|
Oktest.rb is a new-style testing library for Ruby.
|
23
|
+
You can write `ok {1+1} == 2` instead of `assert_equal 2, 1+1` or
|
24
|
+
`expect(1+1).to eq 2`.
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
* Filtering testcases by pattern or tags.
|
28
|
-
* Blue/red color instead of green/red for accesability.
|
29
|
-
* Small code size (about 2300 lines) and good performance.
|
26
|
+
In addition, Oktest.rb supports **Fixture injection** feature
|
27
|
+
inspired by dependency injection and **JSON Matcher** feature
|
28
|
+
similar to JSON schema.
|
30
29
|
|
31
30
|
See https://github.com/kwatch/oktest/tree/ruby/ruby for details.
|
32
31
|
END
|
33
|
-
s.required_ruby_version = ">= 2.
|
32
|
+
s.required_ruby_version = ">= 2.4"
|
34
33
|
s.add_dependency "diff-lcs", "~> 1.0"
|
34
|
+
s.add_dependency "benry-cmdopt", "~> 2.3"
|
35
35
|
s.add_dependency "benry-recorder", "~> 1.0"
|
36
36
|
|
37
37
|
## files
|
data/test/assertion_test.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.4.0 $
|
5
6
|
### $Copyright: copyright(c) 2011-2024 kuwata-lab.com all rights reserved $
|
6
7
|
### $License: MIT License $
|
7
8
|
###
|
@@ -340,10 +341,10 @@ END
|
|
340
341
|
errmsg = "$<actual>.equal?($<expected>): failed.\n"\
|
341
342
|
" $<actual>: \"SOS\"\n"\
|
342
343
|
" $<expected>: \"SOS\"\n"
|
343
|
-
FAIL!(errmsg) { ok {'SOS'}.same?('SOS') }
|
344
|
+
FAIL!(errmsg) { ok {'SOS'.dup}.same?('SOS') }
|
344
345
|
end
|
345
346
|
it "[!dwtig] is avaialbe with NOT." do
|
346
|
-
PASS! { ok {'SOS'}.NOT.same? 'SOS' }
|
347
|
+
PASS! { ok {'SOS'.dup}.NOT.same? 'SOS' }
|
347
348
|
errmsg = "$<actual>.equal?($<expected>) == false: failed.\n"\
|
348
349
|
" $<actual>: :SOS\n"\
|
349
350
|
" $<expected>: :SOS\n"
|
@@ -415,7 +416,7 @@ END
|
|
415
416
|
it "[!sljta] raises TypeError when boolean method returned non-boolean value." do
|
416
417
|
errmsg = "ok(): String#sos?() expected to return true or false, but got 1."
|
417
418
|
ERROR!(TypeError, errmsg) do
|
418
|
-
s = "SOS"
|
419
|
+
s = "SOS".dup
|
419
420
|
def s.sos?; return 1; end
|
420
421
|
ok {s}.sos?
|
421
422
|
end
|
@@ -429,7 +430,7 @@ END
|
|
429
430
|
errmsg = "$<actual>.bla?(#{str}): failed.\n"\
|
430
431
|
" $<actual>: \"Blabla\""
|
431
432
|
FAIL!(errmsg) do
|
432
|
-
s = "Blabla"
|
433
|
+
s = "Blabla".dup
|
433
434
|
def s.bla?(*a, **k); return false; end
|
434
435
|
ok {s}.bla?(123, "abc", x: "45", y: true)
|
435
436
|
end
|
@@ -630,6 +631,18 @@ END
|
|
630
631
|
end
|
631
632
|
end
|
632
633
|
|
634
|
+
describe '#raise_nothing?' do
|
635
|
+
it "[!leqey] do nothing without calling proc object." do
|
636
|
+
pr = proc { 1/0 }
|
637
|
+
ERROR!(ZeroDivisionError) { ok {pr}.raise_nothing? }
|
638
|
+
end
|
639
|
+
it "[!a61b7] not available with `.NOT`." do
|
640
|
+
pr = proc { nil }
|
641
|
+
errmsg = "`raise_nothing?()` is not available with `.NOT`."
|
642
|
+
ERROR!(Oktest::OktestError, errmsg) { ok {pr}.NOT.raise_nothing? }
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
633
646
|
describe '#thrown?' do
|
634
647
|
it "[!w7935] raises ArgumentError when arg of 'thrown?()' is nil." do
|
635
648
|
ERROR!(ArgumentError, "throw?(nil): expected tag required.") do
|
@@ -646,7 +659,7 @@ END
|
|
646
659
|
pr = proc { throw "sym" }
|
647
660
|
expected = ("Thrown tag \"sym\" is equal to but not same as expected.\n"\
|
648
661
|
" (`\"sym\".equal?(\"sym\")` should be true but not.)")
|
649
|
-
FAIL!(expected) { ok {pr}.throw?("sym") }
|
662
|
+
FAIL!(expected) { ok {pr}.throw?("sym".dup) }
|
650
663
|
end
|
651
664
|
it "[!flgwy] assertion fails when thrown tag is different from expectd." do
|
652
665
|
FAIL!(":sym4 should be thrown but actually :sym9 thrown.") do
|
data/test/filter_test.rb
CHANGED
data/test/fixture_test.rb
CHANGED
data/test/generator_test.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
###
|
2
|
-
### $Release: 1.
|
5
|
+
### $Release: 1.4.0 $
|
3
6
|
### $Copyright: copyright(c) 2011-2024 kuwata-lab.com all rights reserved $
|
4
7
|
### $License: MIT License $
|
5
8
|
###
|
@@ -56,7 +59,7 @@ END
|
|
56
59
|
|
57
60
|
spec "returns greeting message."
|
58
61
|
|
59
|
-
end
|
62
|
+
end
|
60
63
|
|
61
64
|
|
62
65
|
end # Hello
|
@@ -78,7 +81,7 @@ END
|
|
78
81
|
|
79
82
|
- spec("returns greeting message.")
|
80
83
|
|
81
|
-
end
|
84
|
+
end
|
82
85
|
|
83
86
|
|
84
87
|
end # Hello
|
@@ -108,7 +111,7 @@ Oktest.scope do
|
|
108
111
|
|
109
112
|
spec "returns greeting message."
|
110
113
|
|
111
|
-
end
|
114
|
+
end
|
112
115
|
|
113
116
|
|
114
117
|
end # Hello
|