rubyment 0.6.25520645 → 0.6.25524898

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rubyment.rb +414 -62
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac992ef2ff77f2b3f5a7e1a392c4a0c36f40c893
4
- data.tar.gz: 87ac55e2f114f278ed74dc13c6f689f265781405
3
+ metadata.gz: 1796154aae62fc1c6039aa65156e3a4d1673be7f
4
+ data.tar.gz: 0c1cc1f4952df5d65a4d0e1ed545dfebc7dcff42
5
5
  SHA512:
6
- metadata.gz: 583ca6633c08eb781326c4abb175c4c56ba4e976029ff373e8bc7e4945ab94769db2add9bf872acf7e9e27bdfdf69aac1c6e48dd44fc96c2a33e97f6d7619d2c
7
- data.tar.gz: 06bae45d3ba2a8c5d3d3cc2845ae2a1b1dd04079c981f04ac0437cf885f3218608bd0b25a5814fb65bc4cb00991dacaf95ed06408f4b6dde619a631eebc4041b
6
+ metadata.gz: b1f36db082abf40f95df2005b3d419922d52dc7ea86e7befbf6d12a639669e959e7dca3b70a4000aca7584198fd29c05714ce312d57c058b0a00b232c5ab32a7
7
+ data.tar.gz: 741062ad9787a496f85af8aaabf3c05d4c16e93e09459e7c8411a52ee875a211499648e94af987450c2a5dc18b2f3cfe84ea12e57126f509c9711042dc9962df
data/lib/rubyment.rb CHANGED
@@ -66,7 +66,7 @@ end
66
66
  # STDOUT, just qualified output:
67
67
  # only if the function is expected
68
68
  # to output something
69
- class Rubyment
69
+ module RubymentModule
70
70
 
71
71
  # this class very often needs to split
72
72
  # first argument and remaining elements.
@@ -2671,8 +2671,8 @@ require '#{gem_name}'
2671
2671
  end
2672
2672
 
2673
2673
 
2674
- # makes an OpenSSL server
2675
- # @param [splat] +args+, an splat whose elements are expected to be:
2674
+ # makes one or more OpenSSL server
2675
+ # @param [Array] +args+, an +Array+ whose elements are expected to be:
2676
2676
  # +listening_port+:: [String, Integer] port to listen
2677
2677
  # +ip_addr+:: [String, nil] ip (no hostname) to bind the server. 0, nil, false, empty string will bind to all addresses possible. 0.0.0.0 => binds to all ipv4 . ::0 to all ipv4 and ipv6
2678
2678
  # +admit_plain+:: [Boolean] if +true+, tries to create a normal +TCPServer+, if not possible to create +SSLServer+ (default: +false+, for preventing unadvertnt non-SSL server creation)
@@ -2681,9 +2681,11 @@ require '#{gem_name}'
2681
2681
  # +cert_pem_file+:: [String] argument to be given to +OpenSSL::SSL::SSLContext.cert+ method, after calling +OpenSSL::X509::Certificate+. It's the "Context certificate" accordingly to its ruby-doc page. letsencrypt example: +"/etc/letsencrypt/live/#{domain}/fullchain.pem"+ (now it's accepted to pass the file contents instead, both must work).
2682
2682
  # +extra_cert_pem_files+:: [Array] array of strings. Each string will be mapped with +OpenSSL::SSL::SSLContext.new+, and the resulting array is given to +OpenSSL::SSL::SSLContext.extra_chain_cert+. "An Array of extra X509 certificates to be added to the certificate chain" accordingly to its ruby-doc. letsencryptexample: +["/etc/letsencrypt/live/#{domain}/chain.pem"]+ (now it's accepted to pass the file contents instead, both must work).
2683
2683
  # +output_exception+:: [Bool] output exceptions even if they are admitted?
2684
+ # +plain_servers+:: [TCPServer, Array of TCPServer] if given, ignores +listening_port+ and +ip_addr+, does not create a +TCPServer+ and just creates an +SSLServer+ out of this one. If an +Array+ of +TCPServer+ is provided instead, it will create one +SSLServer+ to each of those +TCPServer+.
2684
2685
  #
2685
- # @return [OpenSSL::SSL::SSLServer] returns an ssl server, which can be used to accept connections.
2686
- def ssl_make_server *args
2686
+ # @return [Array] returns an #Array whose elements are:
2687
+ # +servers+:: [Array of OpenSSL::SSL::SSLServer or of TCPServer] depending on +admit_plain+ and in the success of the creation of +SSLServers+.
2688
+ def ssl_make_servers args=ARGV
2687
2689
  stderr = @memory[:stderr]
2688
2690
  listening_port,
2689
2691
  ip_addr,
@@ -2693,6 +2695,7 @@ require '#{gem_name}'
2693
2695
  cert_pem_file,
2694
2696
  extra_cert_pem_files,
2695
2697
  output_exception,
2698
+ plain_servers,
2696
2699
  reserved = args
2697
2700
  debug = debug.nne
2698
2701
  extra_cert_pem_files = extra_cert_pem_files.nne []
@@ -2713,32 +2716,140 @@ require '#{gem_name}'
2713
2716
  }
2714
2717
  cert_pem_file = file_read [cert_pem_file, nil, nil, cert_pem_file]
2715
2718
  priv_pemfile = file_read [priv_pemfile, nil, nil, priv_pemfile]
2716
-
2717
2719
  require 'socket'
2718
- plain_server = TCPServer.new ip_addr, listening_port
2719
- ssl_server = runea [admit_plain, output_exception, "nil on exception"] {
2720
- require 'openssl'
2721
- ssl_context = OpenSSL::SSL::SSLContext.new
2722
- ssl_context.extra_chain_cert =
2723
- # TODO: extra_cert_pem_files could also accept strings instead
2724
- extra_cert_pem_files
2725
- .map(&OpenSSL::X509::Certificate.method(:new))
2726
- ssl_context.cert = OpenSSL::X509::Certificate
2727
- .new cert_pem_file
2728
- ssl_context.key = OpenSSL::PKey::RSA
2729
- .new priv_pemfile
2730
- ssl_server = OpenSSL::SSL::SSLServer
2731
- .new plain_server, ssl_context
2732
- ssl_server
2720
+ plain_servers ||= TCPServer.new ip_addr, listening_port
2721
+ plain_servers = containerize plain_servers
2722
+
2723
+ servers = plain_servers.map { |plain_server|
2724
+ ssl_server = runea [
2725
+ admit_plain,
2726
+ output_exception,
2727
+ "nil on exception"] {
2728
+ require 'openssl'
2729
+ ssl_context = OpenSSL::SSL::SSLContext.new
2730
+ ssl_context.extra_chain_cert =
2731
+ extra_cert_pem_files
2732
+ .map(&OpenSSL::X509::Certificate.method(:new))
2733
+ ssl_context.cert = OpenSSL::X509::Certificate
2734
+ .new cert_pem_file
2735
+ ssl_context.key = OpenSSL::PKey::RSA
2736
+ .new priv_pemfile
2737
+ ssl_server = OpenSSL::SSL::SSLServer
2738
+ .new plain_server, ssl_context
2739
+ ssl_server
2740
+ }
2741
+ server = ssl_server || admit_plain && plain_server
2733
2742
  }
2743
+ debug && (stderr.puts "will return #{[servers]}")
2744
+ debug && (stderr.puts "#{__method__} returning")
2745
+ [servers]
2746
+ end
2734
2747
 
2735
- rv = ssl_server || admit_plain && plain_server
2748
+
2749
+ # makes an OpenSSL server
2750
+ # just an interface to the more powerful
2751
+ # recommended #ssl_make_servers
2752
+ # (kept for respecting open-closed principle)
2753
+ # @param [splat] +args+, an splat whose elements are expected to be:
2754
+ # +listening_port+:: [String, Integer] port to listen
2755
+ # +ip_addr+:: [String, nil] ip (no hostname) to bind the server. 0, nil, false, empty string will bind to all addresses possible. 0.0.0.0 => binds to all ipv4 . ::0 to all ipv4 and ipv6
2756
+ # +admit_plain+:: [Boolean] if +true+, tries to create a normal +TCPServer+, if not possible to create +SSLServer+ (default: +false+, for preventing unadvertnt non-SSL server creation)
2757
+ # +debug+:: [Object] for future use
2758
+ # +priv_pemfile+:: [String] argument to be given to +OpenSSL::SSL::SSLContext.key+ method, after calling +OpenSSL::PKey::RSA.new+ with it. It's the private key file. letsencrypt example: +"/etc/letsencrypt/live/#{domain}/privkey.pem"+ (now it's accepted to pass the file contents instead, both must work).
2759
+ # +cert_pem_file+:: [String] argument to be given to +OpenSSL::SSL::SSLContext.cert+ method, after calling +OpenSSL::X509::Certificate+. It's the "Context certificate" accordingly to its ruby-doc page. letsencrypt example: +"/etc/letsencrypt/live/#{domain}/fullchain.pem"+ (now it's accepted to pass the file contents instead, both must work).
2760
+ # +extra_cert_pem_files+:: [Array] array of strings. Each string will be mapped with +OpenSSL::SSL::SSLContext.new+, and the resulting array is given to +OpenSSL::SSL::SSLContext.extra_chain_cert+. "An Array of extra X509 certificates to be added to the certificate chain" accordingly to its ruby-doc. letsencryptexample: +["/etc/letsencrypt/live/#{domain}/chain.pem"]+ (now it's accepted to pass the file contents instead, both must work).
2761
+ # +output_exception+:: [Bool] output exceptions even if they are admitted?
2762
+ # +plain_server+:: [TCPServer] if given, ignores +listening_port+ and +ip_addr+, does not create a +TCPServer+ and just creates an +SSLServer+ out of this one.
2763
+ #
2764
+ # @return [OpenSSL::SSL::SSLServer] returns an ssl server, which can be used to accept connections.
2765
+ def ssl_make_server *args
2766
+ stderr = @memory[:stderr]
2767
+ listening_port,
2768
+ ip_addr,
2769
+ debug,
2770
+ admit_plain,
2771
+ priv_pemfile,
2772
+ cert_pem_file,
2773
+ extra_cert_pem_files,
2774
+ output_exception,
2775
+ plain_server,
2776
+ reserved = args
2777
+ debug = debug.nne
2778
+ debug && (stderr.puts "#{__method__} starting")
2779
+ rv = (ssl_make_servers [
2780
+ listening_port,
2781
+ ip_addr,
2782
+ debug,
2783
+ admit_plain,
2784
+ priv_pemfile,
2785
+ cert_pem_file,
2786
+ extra_cert_pem_files,
2787
+ output_exception,
2788
+ plain_server,
2789
+ ]).first.first
2736
2790
  debug && (stderr.puts "will return #{rv}")
2737
2791
  debug && (stderr.puts "#{__method__} returning")
2738
2792
  rv
2739
2793
  end
2740
2794
 
2741
2795
 
2796
+ # opens one or more TCP and/or SSL server accepting connections.
2797
+ # @param [Array] +args+, an +Array+ whose elements are expected to be:
2798
+ # +listening_port+:: [String, Integer] port to listen
2799
+ # +ip_addr+:: [String, nil] ip (no hostname) to bind the server. 0, nil, false, empty string will bind to all addresses possible. 0.0.0.0 => binds to all ipv4 . ::0 to all ipv4 and ipv6
2800
+ # +admit_plain+:: [Boolean] if +true+, tries to create a normal +TCPServer+, if not possible to create +SSLServer+ (default: +false+, for preventing unadvertnt non-SSL server creation)
2801
+ # +debug+:: [Object] for future use
2802
+ # +callback_method+:: [String, Method] method to call when a client connects. The method must accept a socket as parameter.
2803
+ # +callback_method_args+:: [Array] args to be given to the call_back_method. Note that the type differs from #tcp_server_plain (which takes splat)
2804
+ #
2805
+ # @return [Array] returns a , an +Array+ whose elements are:
2806
+ # +threads+:: [Array of Thread] returns an Array of Thread object looping for accepting incoming connections (call join on those object for waiting for its completion).
2807
+ def tcp_ssl_servers args = ARGV
2808
+ stderr = @memory[:stderr]
2809
+ listening_port,
2810
+ ip_addr,
2811
+ debug,
2812
+ admit_plain,
2813
+ callback_method,
2814
+ callback_method_args,
2815
+ priv_pemfile,
2816
+ cert_pem_file,
2817
+ extra_cert_pem_files,
2818
+ output_exception,
2819
+ reserved = args
2820
+
2821
+ server = (ssl_make_servers [
2822
+ listening_port,
2823
+ ip_addr,
2824
+ debug,
2825
+ admit_plain,
2826
+ priv_pemfile,
2827
+ cert_pem_file,
2828
+ extra_cert_pem_files,
2829
+ output_exception,
2830
+ ]).first.first
2831
+ debug.nne && (stderr.puts server)
2832
+ Thread.start {
2833
+ loop {
2834
+ client = runea ["yes, rescue",
2835
+ "yes, output exception",
2836
+ "nil on exception"
2837
+ ] {
2838
+ server.accept
2839
+ }
2840
+ Thread.start(client) { |client|
2841
+ debug.nne && (stderr.puts Thread.current)
2842
+ debug.nne && (stderr.puts client)
2843
+ runoe {
2844
+ to_method([callback_method])
2845
+ .call([client] + callback_method_args)
2846
+ }
2847
+ }
2848
+ }
2849
+ }
2850
+ end
2851
+
2852
+
2742
2853
  # opens an SSL server accepting connections.
2743
2854
  # @param [Array] +args+, an +Array+ whose elements are expected to be:
2744
2855
  # +listening_port+:: [String, Integer] port to listen
@@ -2765,7 +2876,7 @@ require '#{gem_name}'
2765
2876
  output_exception,
2766
2877
  reserved = args
2767
2878
 
2768
- server = ssl_make_server(
2879
+ server = (ssl_make_servers [
2769
2880
  listening_port,
2770
2881
  ip_addr,
2771
2882
  debug,
@@ -2774,7 +2885,7 @@ require '#{gem_name}'
2774
2885
  cert_pem_file,
2775
2886
  extra_cert_pem_files,
2776
2887
  output_exception,
2777
- )
2888
+ ]).first.first
2778
2889
  debug.nne && (stderr.puts server)
2779
2890
  Thread.start {
2780
2891
  loop {
@@ -3361,6 +3472,15 @@ n8mFEtUKobsK
3361
3472
  end
3362
3473
 
3363
3474
 
3475
+ # runs a command in a shell (requires 'open3')
3476
+ # returns stdout and stderr output mixed
3477
+ # @param [Array] +args+, an +Array+ whose elements are expected to be:
3478
+ # +command+:: [String] command to be executed
3479
+ # @return [Array] returns an #Array whose elements are:
3480
+ # +stdoutanderr+:: [Array of Strings] mix of stdout and stderr output
3481
+ # +stdin+:: [IO]
3482
+ # +wait_thr+:: [Thread]
3483
+ # +success?+:: [TrueClass, FalseClass]
3364
3484
  def shell_popen2e_command args=[]
3365
3485
  command,
3366
3486
  reserved = args
@@ -3370,6 +3490,16 @@ n8mFEtUKobsK
3370
3490
  end
3371
3491
 
3372
3492
 
3493
+ # runs a command in a shell (requires 'open3')
3494
+ # returns stdout and stderr output separated
3495
+ # @param [Array] +args+, an +Array+ whose elements are expected to be:
3496
+ # +command+:: [String] command to be executed
3497
+ # @return [Array] returns an #Array whose elements are:
3498
+ # +stdout+:: [Array of Strings] stdout output
3499
+ # +stderr+:: [Array of Strings] stderr output
3500
+ # +stdin+:: [IO]
3501
+ # +wait_thr+:: [Thread]
3502
+ # +success?+:: [TrueClass, FalseClass]
3373
3503
  def shell_popen3_command args=[]
3374
3504
  command,
3375
3505
  reserved = args
@@ -3379,6 +3509,51 @@ n8mFEtUKobsK
3379
3509
  end
3380
3510
 
3381
3511
 
3512
+ # test #rest_request
3513
+ # for now, the parameters must still be hardcoded.
3514
+ def test__rest_request__with_ayt args=ARGV
3515
+ require 'json'
3516
+ stderr = @memory[:stderr]
3517
+
3518
+ url = "https://owl.loftweb.nl:55031/4/3-roOomydev"
3519
+ json =<<-ENDHEREDOC
3520
+ {
3521
+ "operation" : "AYT",
3522
+ "version" : {
3523
+ "client" : "X",
3524
+ "protocol" : {
3525
+ "domain_model" : "4",
3526
+ "API" : "3"
3527
+ }
3528
+ }
3529
+ }
3530
+ ENDHEREDOC
3531
+ payload = "#{json}"
3532
+
3533
+ auth_user = "web"
3534
+ password = "vadim"
3535
+ method = :post
3536
+ method = :get
3537
+ timeout = 600
3538
+ verify_ssl = true
3539
+ payload = "#{json}"
3540
+ headers = ""
3541
+ request_execution = send :rest_request, [
3542
+ url,
3543
+ payload,
3544
+ verify_ssl,
3545
+ headers,
3546
+ method,
3547
+ auth_user,
3548
+ password,
3549
+ timeout,
3550
+ ]
3551
+ parsed_json = JSON.parse request_execution.to_s
3552
+ stderr.puts parsed_json
3553
+ [parsed_json]
3554
+ end
3555
+
3556
+
3382
3557
  # test for functions that adds syntatic sugar to
3383
3558
  # exceptions.
3384
3559
  def test__rune_functions args = ARGV
@@ -3433,51 +3608,228 @@ n8mFEtUKobsK
3433
3608
  end
3434
3609
 
3435
3610
 
3436
- # test #rest_request
3437
- # for now, the parameters must still be hardcoded.
3438
- def test__rest_request__with_ayt args=ARGV
3439
- require 'json'
3611
+ # tests if +operand_1+ is only
3612
+ # composed by a repetition of +operand_2+
3613
+ # @param [Array] +args+, an +Array+ whose elements are expected to be:
3614
+ # +operand_1+:: [String]
3615
+ # +operand_2+:: [String]
3616
+ # +min_repetitions+:: [FixNum] minimum of times +operand_2+ is required to appear in +operand_1+ (default: +0+). Note that in +args=["", "X", 0]+, +operand_1=""+ will be returned, because "" is a composition of +0+ times "X".
3617
+ # @return [String, FalseClass] returns +operand_1+ if it is only
3618
+ # composed by a repetition of +operand_2+, otherwise +false+
3619
+ def string_repetition args=[]
3440
3620
  stderr = @memory[:stderr]
3441
-
3442
- url = "https://owl.loftweb.nl:55031/4/3-roOomydev"
3443
- json =<<-ENDHEREDOC
3444
- {
3445
- "operation" : "AYT",
3446
- "version" : {
3447
- "client" : "X",
3448
- "protocol" : {
3449
- "domain_model" : "4",
3450
- "API" : "3"
3451
- }
3452
- }
3621
+ operand_1,
3622
+ operand_2,
3623
+ min_repetitions,
3624
+ reserved = args
3625
+ debug = debug.nne
3626
+ debug.nne && (stderr.puts "#{__method__} starting")
3627
+ debug && (stderr.puts "args=#{args.inspect}")
3628
+ debug.nne && (stderr.puts "#{__method__} starting")
3629
+ debug && (stderr.puts "args=#{args.inspect}")
3630
+ debug && (stderr.puts "will return #{is_string_repetition}")
3631
+ debug && (stderr.puts "#{__method__} returning")
3632
+ matches = operand_1.to_s.scan operand_2
3633
+ amout_of_matches = matches.size
3634
+ min_repetitions = min_repetitions.nne 0
3635
+ is_string_repetition = (
3636
+ debug && (stderr.puts '(#{amout_of_matches} >= #{min_repetitions}) && (#{operand_2.size} * #{amout_of_matches} == #{operand_1.size})')
3637
+ debug && (stderr.puts "(#{amout_of_matches} >= #{min_repetitions}) && (#{operand_2.size} * #{amout_of_matches} == #{operand_1.size})")
3638
+ # if operand_2 was matched N times, and the sum
3639
+ # of those N matched sizes is the same
3640
+ (amout_of_matches >= min_repetitions) && (operand_2.size * amout_of_matches == operand_1.size) || false
3641
+ ) && operand_1
3642
+ debug && (stderr.puts "will return #{is_string_repetition}")
3643
+ debug && (stderr.puts "#{__method__} returning")
3644
+ is_string_repetition
3645
+ end
3646
+
3647
+
3648
+ # takes a flatten array and makes it deeper, starting a new array
3649
+ # everytime it finds the string +"["+. +"]"+ stops the array (and
3650
+ # return to the upper one). To reserve the possibility of
3651
+ # representing "[" or "]", everytime a string contains only those
3652
+ # chars, repeteaded any number of times, starting from 2, one of
3653
+ # them will be removed. So +"[["+ will be left as +"["+ and
3654
+ # +"]]]"+ will be left as +"]]"+.
3655
+ # if the provided array is not flatten, it has an undefined
3656
+ # behaviour (it will either a - transverse the sub-arrays
3657
+ # or b - don't transverse it, leaving it untouched. while
3658
+ # the a is the planned effect, initially only a may will
3659
+ # be implemented).
3660
+ # @param [Array] +args+, the array to be operadated
3661
+ # @return [Array] returns the modified, deep, #Array
3662
+ def array_unflatten_base_shallow args=[]
3663
+ reserved_tokens = [
3664
+ [ "[", :up],
3665
+ [ "]", :down.to_nil],
3666
+ ]
3667
+ rv = []
3668
+ array_operand = []
3669
+ array_operands_stack = []
3670
+ args.each_with_index {|e, index|
3671
+ reserved_tokens.map { |reserved_token|
3672
+ rtoken, is_up_token = reserved_token
3673
+
3674
+ repetition_test = string_repetition [e, rtoken, 1]
3675
+ (
3676
+ # case A: e is exactly the reserved token.
3677
+ # start or finish an array
3678
+ # note: if rtoken is false, it will succeed this
3679
+ # test.
3680
+ (repetition_test == rtoken) && (
3681
+ is_up_token && (
3682
+ array_operands_stack.push array_operand
3683
+ array_operand = Array.new
3684
+ ) || (
3685
+ array_operand = array_operands_stack.pop
3686
+ )
3687
+ )
3688
+ ) || (
3689
+ # case B: is a a repetition with at least 2
3690
+ # occurrences of the reserved token. remove one.
3691
+ # (and add it to the current array)
3692
+ repetition_test && (
3693
+ array_operand.push(e.sub! rtoken, "")
3694
+ )
3695
+ ) || (
3696
+ # case C: no repetition. (just add e to
3697
+ # the current array.)
3698
+ array_operand.push e
3699
+ )
3700
+ }
3453
3701
  }
3454
- ENDHEREDOC
3455
- payload = "#{json}"
3702
+ array_operand
3703
+ end
3704
+
3705
+ # test for #string_repetition
3706
+ def test__array_unflatten_base_shallow args=[]
3707
+ test_cases ||= [
3708
+ # [ :id, :expectation, :actual_params ],
3709
+ # array_unflatten_base_shallow
3710
+ [ "any test", [ :a, [ :b ], :c], [
3711
+ :array_unflatten_base_shallow, [
3712
+ :a, "[", :b, "]", :c
3713
+ ]
3714
+ ],
3715
+ ],
3456
3716
 
3457
- auth_user = "web"
3458
- password = "vadim"
3459
- method = :post
3460
- method = :get
3461
- timeout = 600
3462
- verify_ssl = true
3463
- payload = "#{json}"
3464
- headers = ""
3465
- request_execution = send :rest_request, [
3466
- url,
3467
- payload,
3468
- verify_ssl,
3469
- headers,
3470
- method,
3471
- auth_user,
3472
- password,
3473
- timeout,
3474
3717
  ]
3475
- parsed_json = JSON.parse request_execution.to_s
3476
- stderr.puts parsed_json
3477
- [parsed_json]
3718
+ test__tester test_cases
3719
+ end
3720
+
3721
+ def test__tester args=[]
3722
+ expectation = {}
3723
+ actual = {}
3724
+ test_cases = args
3725
+ test_cases ||= [
3726
+ # [ :id, :expectation, :actual_params ],
3727
+ ]
3728
+ test_cases.each_with_index{ |test_case|
3729
+ test_case_id, test_expectation, actual_params = test_case
3730
+ result = send actual_params[0], actual_params[1]
3731
+ expectation[test_case_id] = test_expectation
3732
+ actual[test_case_id] = result
3733
+ }
3734
+ judgement = actual.keys.map {|test_case|
3735
+ [expectation[test_case], actual[test_case] , test_case]
3736
+ }.map(&method("expect_equal")).all?
3737
+ end
3738
+
3739
+
3740
+ # test for #string_repetition
3741
+ def test__string_repetition args=[]
3742
+ expectation = {}
3743
+ actual = {}
3744
+ test_case = 1
3745
+ operand_1 = "XXX"
3746
+ operand_2 = "X"
3747
+ # expectation and actual inverted.
3748
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3749
+ actual[test_case] = operand_1
3750
+
3751
+ test_case = 2
3752
+ operand_1 = "X"
3753
+ operand_2 = "X"
3754
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3755
+ actual[test_case] = operand_1
3756
+
3757
+ test_case = 3
3758
+ operand_1 = "XyXy"
3759
+ operand_2 = "XyXy"
3760
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3761
+ actual[test_case] = operand_1
3762
+
3763
+ test_case = 4
3764
+ operand_1 = "XyXy"
3765
+ operand_2 = "XXyy"
3766
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3767
+ actual[test_case] = false
3768
+
3769
+ test_case = 6
3770
+ operand_1 = ""
3771
+ operand_2 = ""
3772
+ expectation[test_case] = string_repetition [operand_1, operand_2, 0]
3773
+ actual[test_case] = operand_1
3774
+
3775
+ test_case = 7
3776
+ operand_1 = ""
3777
+ operand_2 = ""
3778
+ expectation[test_case] = string_repetition [operand_1, operand_2, 1]
3779
+ actual[test_case] = operand_1
3780
+
3781
+ test_case = 7
3782
+ operand_1 = ""
3783
+ operand_2 = "X"
3784
+ expectation[test_case] = string_repetition [operand_1, operand_2, 0]
3785
+ # "X"*0 = ""
3786
+ actual[test_case] = operand_1
3787
+
3788
+ test_case = 8
3789
+ operand_1 = ""
3790
+ operand_2 = "X"
3791
+ expectation[test_case] = string_repetition [operand_1, operand_2, 1]
3792
+ # "X"*0 = "", but minimum is set to 1
3793
+ actual[test_case] = false
3794
+
3795
+ test_case = 9
3796
+ operand_1 = "XyXy"
3797
+ operand_2 = "Xy"
3798
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3799
+ actual[test_case] = operand_1
3800
+
3801
+ test_case = 10
3802
+ operand_1 = "XyXy"
3803
+ operand_2 = ""
3804
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3805
+ # clearly "" appears in "XyXy" infinity times, but "XyXy" is no
3806
+ # repetition of ""
3807
+ actual[test_case] = false
3808
+
3809
+ test_case = 11
3810
+ operand_1 = "XyXy"
3811
+ operand_2 = "Xy"
3812
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3813
+ actual[test_case] = operand_1
3814
+
3815
+ test_case = 12
3816
+ operand_1 = "X"
3817
+ operand_2 = "XXX"
3818
+ expectation[test_case] = string_repetition [operand_1, operand_2]
3819
+ actual[test_case] = false
3820
+
3821
+ judgement = actual.keys.map {|test_case|
3822
+ [expectation[test_case], actual[test_case] , test_case]
3823
+ }.map(&method("expect_equal")).all?
3478
3824
  end
3479
3825
 
3480
3826
 
3827
+
3828
+ end
3829
+
3830
+
3831
+ class Rubyment
3832
+ include RubymentModule
3481
3833
  end
3482
3834
 
3483
3835
  (__FILE__ == $0) && Rubyment.new({:invoke => ARGV})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.25520645
4
+ version: 0.6.25524898
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribamar Santarosa