sexp_processor 4.12.0 → 4.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +47 -0
- data/Manifest.txt +1 -0
- data/Rakefile +2 -0
- data/lib/pt_testcase.rb +13 -15
- data/lib/sexp.rb +14 -1053
- data/lib/sexp_matcher.rb +1100 -0
- data/lib/sexp_processor.rb +2 -2
- data/test/test_sexp.rb +189 -132
- data/test/test_sexp_processor.rb +2 -2
- metadata +18 -16
- metadata.gz.sig +0 -0
data/lib/sexp_processor.rb
CHANGED
@@ -34,7 +34,7 @@ require "sexp"
|
|
34
34
|
class SexpProcessor
|
35
35
|
|
36
36
|
# duh
|
37
|
-
VERSION = "4.
|
37
|
+
VERSION = "4.15.0"
|
38
38
|
|
39
39
|
##
|
40
40
|
# Automatically shifts off the Sexp type before handing the
|
@@ -317,7 +317,7 @@ class SexpProcessor
|
|
317
317
|
|
318
318
|
def assert_type list, typ
|
319
319
|
raise SexpTypeError, "Expected type #{typ.inspect} in #{list.inspect}" if
|
320
|
-
not Array === list or list.
|
320
|
+
not Array === list or list.sexp_type != typ
|
321
321
|
end
|
322
322
|
|
323
323
|
def error_handler type, exp = nil # :nodoc:
|
data/test/test_sexp.rb
CHANGED
@@ -233,16 +233,16 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
233
233
|
end
|
234
234
|
|
235
235
|
def test_equal3_subset_match
|
236
|
-
assert_match s{
|
237
|
-
assert_equal3 s{
|
238
|
-
assert_equal3 s{
|
239
|
-
assert_equal3 s{
|
240
|
-
assert_equal3 s{
|
236
|
+
assert_match s{q(:a)}, s(s(:a), s(:b)) # left - =~
|
237
|
+
assert_equal3 s{q(:a)}, s(s(:a), s(:b)) # left - ===
|
238
|
+
assert_equal3 s{q(:a)}, s(:blah, s(:a ), s(:b)) # mid 1
|
239
|
+
assert_equal3 s{q(:a, 1)}, s(:blah, s(:a, 1), s(:b)) # mid 2
|
240
|
+
assert_equal3 s{q(:a)}, s(:blah, s(:blah, s(:a))) # left deeper
|
241
241
|
end
|
242
242
|
|
243
243
|
def test_equalstilde_fancy
|
244
|
-
assert_match s{
|
245
|
-
assert_match s(:a, s(:b), :c), s{
|
244
|
+
assert_match s{ q(:b) }, s(:a, s(:b), :c)
|
245
|
+
assert_match s(:a, s(:b), :c), s{ q(:b) }
|
246
246
|
|
247
247
|
e = assert_raises ArgumentError do
|
248
248
|
s(:b) =~ s(:a, s(:b), :c)
|
@@ -256,8 +256,8 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
256
256
|
end
|
257
257
|
|
258
258
|
def test_equalstilde_plain
|
259
|
-
s{
|
260
|
-
s(:data) =~ s{
|
259
|
+
s{ q(:re) } =~ s(:data) # pattern on LHS
|
260
|
+
s(:data) =~ s{ q(:re) } # pattern on RHS
|
261
261
|
|
262
262
|
e = assert_raises ArgumentError do
|
263
263
|
s(:re) =~ s(:data) # no pattern
|
@@ -297,10 +297,10 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
297
297
|
end
|
298
298
|
|
299
299
|
def test_gsub_matcher
|
300
|
-
assert_gsub s(:a, :b, :c), s(:a, s(:b, 42), :c), s{
|
301
|
-
assert_gsub s(:a, s(:b), :c), s(:a, s(:b), :c), s{
|
302
|
-
assert_gsub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{
|
303
|
-
assert_gsub s(:a, s(:q), :c), s(:a, s(:q), :c), s{
|
300
|
+
assert_gsub s(:a, :b, :c), s(:a, s(:b, 42), :c), s{ q(:b, _) }, :b
|
301
|
+
assert_gsub s(:a, s(:b), :c), s(:a, s(:b), :c), s{ q(:b, _) }, :b
|
302
|
+
assert_gsub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{ q(:b, _) }, :b
|
303
|
+
assert_gsub s(:a, s(:q), :c), s(:a, s(:q), :c), s{ q(:b, _) }, :b
|
304
304
|
end
|
305
305
|
|
306
306
|
def with_env key
|
@@ -529,8 +529,6 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
529
529
|
def test_shift
|
530
530
|
skip_if_strict 5
|
531
531
|
|
532
|
-
skip "https://github.com/MagLev/maglev/issues/250" if maglev?
|
533
|
-
|
534
532
|
assert_equal(1, @sexp.shift)
|
535
533
|
assert_equal(2, @sexp.shift)
|
536
534
|
assert_equal(3, @sexp.shift)
|
@@ -589,14 +587,14 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
589
587
|
end
|
590
588
|
|
591
589
|
def test_sub_matcher
|
592
|
-
assert_sub s(:c), s(:b), s{
|
593
|
-
assert_sub s(:a, s(:c), s(:b)), s(:a, s(:b), s(:b)), s{
|
594
|
-
assert_sub s(:a, s(:c), s(:a)), s(:a, s(:b), s(:a)), s{
|
590
|
+
assert_sub s(:c), s(:b), s{ q(:b) }, s(:c)
|
591
|
+
assert_sub s(:a, s(:c), s(:b)), s(:a, s(:b), s(:b)), s{ q(:b) }, s(:c)
|
592
|
+
assert_sub s(:a, s(:c), s(:a)), s(:a, s(:b), s(:a)), s{ q(:b) }, s(:c)
|
595
593
|
|
596
|
-
assert_sub s(:a, :b, :c), s(:a, s(:b, 42), :c), s{
|
597
|
-
assert_sub s(:a, s(:b), :c), s(:a, s(:b), :c), s{
|
598
|
-
assert_sub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{
|
599
|
-
assert_sub s(:a, s(:q), :c), s(:a, s(:q), :c), s{
|
594
|
+
assert_sub s(:a, :b, :c), s(:a, s(:b, 42), :c), s{ q(:b, _) }, :b
|
595
|
+
assert_sub s(:a, s(:b), :c), s(:a, s(:b), :c), s{ q(:b, _) }, :b
|
596
|
+
assert_sub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{ q(:b, _) }, :b
|
597
|
+
assert_sub s(:a, s(:q), :c), s(:a, s(:q), :c), s{ q(:b, _) }, :b
|
600
598
|
end
|
601
599
|
|
602
600
|
def test_sub_structure
|
@@ -682,7 +680,7 @@ end # TestSexp
|
|
682
680
|
|
683
681
|
class TestSexpMatcher < SexpTestCase
|
684
682
|
def test_cls_s
|
685
|
-
assert_equal M.
|
683
|
+
assert_equal M.q(:x), s{ q(:x) }
|
686
684
|
end
|
687
685
|
|
688
686
|
def test_cls_underscore
|
@@ -702,19 +700,19 @@ class TestSexpMatcher < SexpTestCase
|
|
702
700
|
end
|
703
701
|
|
704
702
|
def test_cls_any
|
705
|
-
assert_equal M::Any.new(M.
|
703
|
+
assert_equal M::Any.new(M.q(:a), M.q(:b)), s{ any(q(:a), q(:b)) }
|
706
704
|
end
|
707
705
|
|
708
706
|
def test_cls_all
|
709
|
-
assert_equal M::All.new(M.
|
707
|
+
assert_equal M::All.new(M.q(:a), M.q(:b)), s{ all(q(:a), q(:b)) }
|
710
708
|
end
|
711
709
|
|
712
710
|
def test_cls_not_eh
|
713
|
-
assert_equal M::Not.new(M.
|
711
|
+
assert_equal M::Not.new(M.q(:a)), s{ not?(q(:a)) }
|
714
712
|
end
|
715
713
|
|
716
714
|
def test_cls_child
|
717
|
-
assert_equal M::Child.new(M.
|
715
|
+
assert_equal M::Child.new(M.q(:a)), s{ child(q(:a)) }
|
718
716
|
end
|
719
717
|
|
720
718
|
def test_cls_t
|
@@ -722,45 +720,51 @@ class TestSexpMatcher < SexpTestCase
|
|
722
720
|
end
|
723
721
|
|
724
722
|
def test_cls_m
|
725
|
-
assert_equal M::Pattern.new(/a/), s{ m(/a/) }
|
726
|
-
assert_equal M::Pattern.new(/\Aa\Z/), s{ m(:a) }
|
727
|
-
assert_equal M::Pattern.new(/test_\w/), s{ m(/test_\w/) }
|
728
723
|
re = Regexp.union [/\w/, /\d/]
|
729
|
-
|
724
|
+
|
725
|
+
assert_equal M::Pattern.new(/a/), s{ m(/a/) }
|
726
|
+
assert_equal M::Pattern.new(/\Aa\Z/), s{ m(:a) }
|
727
|
+
assert_equal M::Pattern.new(/test_\w/), s{ m(/test_\w/) }
|
728
|
+
assert_equal M::Pattern.new(re), s{ m(/\w/,/\d/) }
|
729
|
+
end
|
730
|
+
|
731
|
+
def test_cls_k
|
732
|
+
assert_equal M::Klass.new(Float), s{ k(Float) }
|
733
|
+
assert_operator M::Klass.new(Float), :===, 6.28
|
730
734
|
end
|
731
735
|
|
732
736
|
def test_amp
|
733
|
-
m = s{
|
734
|
-
e = M::All.new(M.
|
737
|
+
m = s{ q(:a) & q(:b) }
|
738
|
+
e = M::All.new(M.q(:a), M.q(:b))
|
735
739
|
|
736
740
|
assert_equal e, m
|
737
741
|
end
|
738
742
|
|
739
743
|
def test_pipe
|
740
|
-
m = s{
|
741
|
-
e = M::Any.new(M.
|
744
|
+
m = s{ q(:a) | q(:b) }
|
745
|
+
e = M::Any.new(M.q(:a), M.q(:b))
|
742
746
|
|
743
747
|
assert_equal e, m
|
744
748
|
end
|
745
749
|
|
746
750
|
def test_unary_minus
|
747
|
-
assert_equal M::Not.new(M.
|
751
|
+
assert_equal M::Not.new(M.q(:a)), s{ -q(:a) }
|
748
752
|
end
|
749
753
|
|
750
754
|
def test_rchevron
|
751
|
-
assert_equal M::Sibling.new(M.
|
755
|
+
assert_equal M::Sibling.new(M.q(:a), M.q(:b)), s{ q(:a) >> q(:b) }
|
752
756
|
end
|
753
757
|
|
754
758
|
def test_greedy_eh
|
755
|
-
refute_operator s{
|
759
|
+
refute_operator s{ q(:a) }, :greedy?
|
756
760
|
end
|
757
761
|
|
758
762
|
def test_inspect
|
759
|
-
assert_inspect "q(:a)", s{
|
763
|
+
assert_inspect "q(:a)", s{ q(:a) }
|
760
764
|
end
|
761
765
|
|
762
766
|
def test_pretty_print
|
763
|
-
assert_pretty_print "q(:a)", s{
|
767
|
+
assert_pretty_print "q(:a)", s{ q(:a) }
|
764
768
|
end
|
765
769
|
end # class TestSexpMatcher
|
766
770
|
|
@@ -790,11 +794,11 @@ class TestWild < MatcherTestCase
|
|
790
794
|
def test_wild_search # TODO: possibly remove
|
791
795
|
sexp = CLASS_SEXP.dup
|
792
796
|
|
793
|
-
assert_search 1, s(:add, :a, :b), s{
|
794
|
-
assert_search 1, sexp, s{
|
795
|
-
assert_search 2, sexp, s{
|
796
|
-
assert_search 1, s(:a, s()), s{
|
797
|
-
assert_search 1, s(:a, :b, :c), s{
|
797
|
+
assert_search 1, s(:add, :a, :b), s{ q(:add, _, :b) }
|
798
|
+
assert_search 1, sexp, s{ q(:defn, :bar, _, _) }
|
799
|
+
assert_search 2, sexp, s{ q(:defn, _, _, q(_, :a, :b) ) }
|
800
|
+
assert_search 1, s(:a, s()), s{ q(:a, _) }
|
801
|
+
assert_search 1, s(:a, :b, :c), s{ q(_, _, _) }
|
798
802
|
assert_search 7, sexp, s{ _ }
|
799
803
|
end
|
800
804
|
end
|
@@ -815,8 +819,8 @@ class TestRemaining < MatcherTestCase
|
|
815
819
|
def test_remaining_satisfy_eh # TODO: possibly remove
|
816
820
|
assert_satisfy s{ ___ }, s(:a)
|
817
821
|
assert_satisfy s{ ___ }, s(:a, :b, :c)
|
818
|
-
assert_satisfy s{
|
819
|
-
refute_satisfy s{
|
822
|
+
assert_satisfy s{ q(:x, ___ ) }, s(:x, :y)
|
823
|
+
refute_satisfy s{ q(:y, ___ ) }, s(:x, :y)
|
820
824
|
end
|
821
825
|
|
822
826
|
def test_greedy
|
@@ -826,7 +830,7 @@ end
|
|
826
830
|
|
827
831
|
class TestAny < MatcherTestCase
|
828
832
|
def matcher
|
829
|
-
s{
|
833
|
+
s{ q(:a) | q(:c) }
|
830
834
|
end
|
831
835
|
|
832
836
|
def inspect_str
|
@@ -838,26 +842,26 @@ class TestAny < MatcherTestCase
|
|
838
842
|
end
|
839
843
|
|
840
844
|
def test_any_search # TODO: possibly remove
|
841
|
-
assert_search 2, s(:foo, s(:a), s(:b)), s{
|
842
|
-
assert_search 1, s(:foo, s(:a), s(:b)), s{ any(
|
845
|
+
assert_search 2, s(:foo, s(:a), s(:b)), s{ q(any(:a, :b)) }
|
846
|
+
assert_search 1, s(:foo, s(:a), s(:b)), s{ any( q(:a), q(:c)) }
|
843
847
|
end
|
844
848
|
|
845
849
|
def test_or_satisfy_eh # TODO: possibly remove
|
846
|
-
assert_satisfy s{
|
847
|
-
refute_satisfy s{
|
850
|
+
assert_satisfy s{ q(:a) | q(:b) }, s(:a)
|
851
|
+
refute_satisfy s{ q(:a) | q(:b) }, s(:c)
|
848
852
|
end
|
849
853
|
|
850
854
|
def test_or_search # TODO: possibly remove
|
851
855
|
sexp = CLASS_SEXP.dup
|
852
856
|
|
853
|
-
assert_search 2, s(:a, s(:b, :c), s(:b, :d)), s{
|
854
|
-
assert_search 2, sexp, s{
|
857
|
+
assert_search 2, s(:a, s(:b, :c), s(:b, :d)), s{ q(:b, :c) | q(:b, :d) }
|
858
|
+
assert_search 2, sexp, s{ q(:add, :a, :b) | q(:defn, :bar, _, _) }
|
855
859
|
end
|
856
860
|
end
|
857
861
|
|
858
862
|
class TestAll < MatcherTestCase
|
859
863
|
def matcher
|
860
|
-
s{
|
864
|
+
s{ q(:a) & q(:a) }
|
861
865
|
end
|
862
866
|
|
863
867
|
def inspect_str
|
@@ -869,14 +873,14 @@ class TestAll < MatcherTestCase
|
|
869
873
|
end
|
870
874
|
|
871
875
|
def test_and_satisfy_eh # TODO: possibly remove
|
872
|
-
refute_satisfy s{
|
873
|
-
assert_satisfy s{
|
876
|
+
refute_satisfy s{ q(:a) & q(:b) }, s(:a)
|
877
|
+
assert_satisfy s{ q(:a) & q(atom) }, s(:a)
|
874
878
|
end
|
875
879
|
end
|
876
880
|
|
877
881
|
class TestNot < MatcherTestCase
|
878
882
|
def matcher
|
879
|
-
s{ not?
|
883
|
+
s{ not? q(:b) } # TODO: test unary minus
|
880
884
|
end
|
881
885
|
|
882
886
|
def inspect_str
|
@@ -889,20 +893,20 @@ class TestNot < MatcherTestCase
|
|
889
893
|
|
890
894
|
def test_not_satisfy_eh # TODO: possibly remove
|
891
895
|
refute_satisfy s{ -_ }, s(:a)
|
892
|
-
assert_satisfy s{ -
|
893
|
-
assert_satisfy s{ not?(
|
894
|
-
refute_satisfy s{ -
|
895
|
-
assert_satisfy s{
|
896
|
+
assert_satisfy s{ -q(:b) }, s(:a)
|
897
|
+
assert_satisfy s{ not?(q(:b)) }, s(:a)
|
898
|
+
refute_satisfy s{ -q(atom) }, s(:a)
|
899
|
+
assert_satisfy s{ q(not?(:b)) }, s(:a)
|
896
900
|
end
|
897
901
|
end
|
898
902
|
|
899
903
|
class TestChild < MatcherTestCase
|
900
904
|
def matcher
|
901
|
-
s{ child(
|
905
|
+
s{ child(q(:a)) }
|
902
906
|
end
|
903
907
|
|
904
908
|
def sexp
|
905
|
-
s(:x, s(:a))
|
909
|
+
s(:x, s(:b), s(:a))
|
906
910
|
end
|
907
911
|
|
908
912
|
def bad_sexp
|
@@ -916,12 +920,14 @@ class TestChild < MatcherTestCase
|
|
916
920
|
def test_child_search # TODO: possibly remove
|
917
921
|
sexp = CLASS_SEXP.dup
|
918
922
|
|
919
|
-
assert_search 1, sexp, s{
|
920
|
-
assert_search 1, sexp, s{
|
923
|
+
assert_search 1, sexp, s{ q(:class, :cake, _, _, child( q(:sub, :a, :b) ) ) }
|
924
|
+
assert_search 1, sexp, s{ q(:class, :cake, _, _, child(include(:a))) }
|
921
925
|
end
|
922
926
|
|
923
927
|
def test_satisfy_eh_by_child
|
924
928
|
assert_satisfy matcher, s(:a)
|
929
|
+
assert_satisfy matcher, sexp
|
930
|
+
refute_satisfy matcher, bad_sexp
|
925
931
|
end
|
926
932
|
end
|
927
933
|
|
@@ -954,15 +960,15 @@ class TestAtom < MatcherTestCase
|
|
954
960
|
def test_atom_search # TODO: possibly remove
|
955
961
|
sexp = CLASS_SEXP.dup
|
956
962
|
|
957
|
-
assert_search 1, s(:add, :a, :b), s{
|
958
|
-
assert_search 2, sexp, s{
|
959
|
-
assert_search 0, s(:a, s()), s{
|
963
|
+
assert_search 1, s(:add, :a, :b), s{ q(:add, atom, :b) }
|
964
|
+
assert_search 2, sexp, s{ q(:defn, atom, _, q(atom, :a, :b) ) }
|
965
|
+
assert_search 0, s(:a, s()), s{ q(:a, atom) }
|
960
966
|
end
|
961
967
|
end
|
962
968
|
|
963
969
|
class TestPattern < MatcherTestCase
|
964
970
|
def matcher
|
965
|
-
s{
|
971
|
+
s{ q(:a, m(/a/)) }
|
966
972
|
end
|
967
973
|
|
968
974
|
def sexp
|
@@ -984,15 +990,15 @@ class TestPattern < MatcherTestCase
|
|
984
990
|
def test_pattern_search # TODO: possibly remove
|
985
991
|
sexp = CLASS_SEXP.dup
|
986
992
|
|
987
|
-
assert_search 2, sexp, s{
|
993
|
+
assert_search 2, sexp, s{ q(m(/\w{3}/), :a, :b) }
|
988
994
|
|
989
995
|
assert_search 0, s(:a), s{ m(/\w/) }
|
990
|
-
assert_search 1, s(:a), s{
|
996
|
+
assert_search 1, s(:a), s{ q(m(/\w/)) }
|
991
997
|
assert_search 0, s(:a), s{ m(/\w/,/\d/) }
|
992
|
-
assert_search 1, s(:a), s{
|
998
|
+
assert_search 1, s(:a), s{ q(m(/\w/,/\d/)) }
|
993
999
|
|
994
1000
|
assert_search 0, s(:tests, s(s(:test_a), s(:test_b))), s{ m(/test_\w/) }
|
995
|
-
assert_search 2, s(:tests, s(s(:test_a), s(:test_b))), s{
|
1001
|
+
assert_search 2, s(:tests, s(s(:test_a), s(:test_b))), s{ q(m(/test_\w/)) }
|
996
1002
|
end
|
997
1003
|
end
|
998
1004
|
|
@@ -1021,7 +1027,7 @@ class TestInclude < MatcherTestCase
|
|
1021
1027
|
end
|
1022
1028
|
|
1023
1029
|
def matcher
|
1024
|
-
s{ include(
|
1030
|
+
s{ include(q(:a)) }
|
1025
1031
|
end
|
1026
1032
|
|
1027
1033
|
def inspect_str
|
@@ -1033,9 +1039,9 @@ class TestInclude < MatcherTestCase
|
|
1033
1039
|
|
1034
1040
|
assert_search 1, s(:add, :a, :b), s{ include(:a) }
|
1035
1041
|
assert_search 1, sexp, s{ include(:bar) }
|
1036
|
-
assert_search 2, sexp, s{
|
1042
|
+
assert_search 2, sexp, s{ q(:defn, atom, _, include(:a)) }
|
1037
1043
|
assert_search 2, sexp, s{ include(:a) }
|
1038
|
-
assert_search 0, s(:a, s(:b, s(:c))), s{
|
1044
|
+
assert_search 0, s(:a, s(:b, s(:c))), s{ q(:a, include(:c)) }
|
1039
1045
|
end
|
1040
1046
|
end
|
1041
1047
|
|
@@ -1045,7 +1051,7 @@ class TestSibling < MatcherTestCase
|
|
1045
1051
|
end
|
1046
1052
|
|
1047
1053
|
def matcher
|
1048
|
-
s{
|
1054
|
+
s{ q(:a) >> q(:b) }
|
1049
1055
|
end
|
1050
1056
|
|
1051
1057
|
def inspect_str
|
@@ -1053,15 +1059,15 @@ class TestSibling < MatcherTestCase
|
|
1053
1059
|
end
|
1054
1060
|
|
1055
1061
|
def test_pretty_print_distance
|
1056
|
-
m = s{ M::Sibling.new(
|
1062
|
+
m = s{ M::Sibling.new(q(:a), q(:b), 3) } # maybe q(:a) << q(:b) << 3 ?
|
1057
1063
|
assert_pretty_print "sibling(q(:a), q(:b), 3)", m
|
1058
1064
|
end
|
1059
1065
|
|
1060
1066
|
def test_sibling_satisfy_eh # TODO: possibly remove
|
1061
|
-
a_a = s{
|
1062
|
-
a_b = s{
|
1063
|
-
a_c = s{
|
1064
|
-
c_a = s{
|
1067
|
+
a_a = s{ q(:a) >> q(:a) }
|
1068
|
+
a_b = s{ q(:a) >> q(:b) }
|
1069
|
+
a_c = s{ q(:a) >> q(:c) }
|
1070
|
+
c_a = s{ q(:c) >> q(:a) }
|
1065
1071
|
|
1066
1072
|
assert_satisfy a_b, s(s(:a), s(:b))
|
1067
1073
|
assert_satisfy a_b, s(s(:a), s(:b), s(:c))
|
@@ -1093,8 +1099,8 @@ class TestMatchCollection < SexpTestCase
|
|
1093
1099
|
s(:defn, :foo, s(:args), s(:add, :a, :b)),
|
1094
1100
|
s(:defn, :bar, s(:args), s(:sub, :a, :b)))
|
1095
1101
|
|
1096
|
-
res = sexp / s{
|
1097
|
-
act = res / s{
|
1102
|
+
res = sexp / s{ q(:class, atom, _, ___) } # sexp / pat => MC
|
1103
|
+
act = res / s{ q(:defn, atom, ___) } # MC / pat => MC
|
1098
1104
|
|
1099
1105
|
_, _, _, defn1, defn2 = sexp
|
1100
1106
|
|
@@ -1150,8 +1156,43 @@ class TestSexpSearch < SexpTestCase
|
|
1150
1156
|
MR.new sexp.deep_clone, hash
|
1151
1157
|
end
|
1152
1158
|
|
1159
|
+
def test_sexp_hash
|
1160
|
+
s1 = s(:a)
|
1161
|
+
s2 = s(nil)
|
1162
|
+
refute_equal s1.hash, s2.hash
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
def test_matcher_inspect
|
1166
|
+
pat1 = M.parse "(a [m /b/] (c))"
|
1167
|
+
|
1168
|
+
assert_equal "q(:a, m(/b/), q(:c))", pat1.inspect
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
def test_matcher_hash
|
1172
|
+
a = M::Pattern.new(/x/) # M.parse "[m /x/]"
|
1173
|
+
b = M::Atom.new # M.parse "_"
|
1174
|
+
|
1175
|
+
refute_operator a, :eql?, b
|
1176
|
+
refute_equal a.hash, b.hash
|
1177
|
+
|
1178
|
+
h = {}
|
1179
|
+
h[a] = true
|
1180
|
+
refute_operator h, :key?, b
|
1181
|
+
|
1182
|
+
# original problem:
|
1183
|
+
a = M.parse "(call nil assert_equal (true) (call _ [m /include./] _))"
|
1184
|
+
b = M.parse "(call nil assert_equal (true) (call _ _ _))"
|
1185
|
+
|
1186
|
+
refute_operator a, :eql?, b
|
1187
|
+
refute_equal a.hash, b.hash
|
1188
|
+
|
1189
|
+
h = {}
|
1190
|
+
h[a] = true
|
1191
|
+
refute_operator h, :key?, b
|
1192
|
+
end
|
1193
|
+
|
1153
1194
|
def test_slash_simple
|
1154
|
-
act = sexp / s{
|
1195
|
+
act = sexp / s{ q(:class, atom, _, ___) }
|
1155
1196
|
|
1156
1197
|
exp = MC.new
|
1157
1198
|
exp << sexp.deep_clone
|
@@ -1160,7 +1201,7 @@ class TestSexpSearch < SexpTestCase
|
|
1160
1201
|
end
|
1161
1202
|
|
1162
1203
|
def test_slash_subsexp
|
1163
|
-
act = sexp / s{
|
1204
|
+
act = sexp / s{ q(:defn, atom, ___) }
|
1164
1205
|
|
1165
1206
|
exp = MC.new
|
1166
1207
|
exp << s(:defn, :foo, s(:args), s(:add, :a, :b))
|
@@ -1170,7 +1211,7 @@ class TestSexpSearch < SexpTestCase
|
|
1170
1211
|
end
|
1171
1212
|
|
1172
1213
|
def test_slash_data
|
1173
|
-
pat = s{
|
1214
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1174
1215
|
|
1175
1216
|
_, _, (_klass, _, _, _setup, t1, t2, t3) = TestUseCase.sexp.deep_clone
|
1176
1217
|
exp = [t1, t2, t3]
|
@@ -1199,27 +1240,27 @@ class TestSexpSearch < SexpTestCase
|
|
1199
1240
|
assert_search 0, sexp, :class # non-pattern should raise
|
1200
1241
|
end
|
1201
1242
|
|
1202
|
-
assert_search 0, sexp, s{
|
1203
|
-
assert_search 1, sexp, s{
|
1204
|
-
assert_search 1, s(:a, s(:b, s(:c))), s{
|
1205
|
-
assert_search 0, s(:a, s(:b, s(:c))), s{
|
1206
|
-
assert_search 1, sexp, s{
|
1243
|
+
assert_search 0, sexp, s{ q(:class) }
|
1244
|
+
assert_search 1, sexp, s{ q(:add, :a, :b) }
|
1245
|
+
assert_search 1, s(:a, s(:b, s(:c))), s{ q(:b, q(:c)) }
|
1246
|
+
assert_search 0, s(:a, s(:b, s(:c))), s{ q(:a, q(:c)) }
|
1247
|
+
assert_search 1, sexp, s{ q(:defn, :bar, _, q(:sub, :a, :b)) }
|
1207
1248
|
end
|
1208
1249
|
|
1209
1250
|
def test_satisfy_eh_any_capture # TODO: remove
|
1210
1251
|
sexp = s(:add, :a, :b)
|
1211
|
-
assert_satisfy s{ any(
|
1252
|
+
assert_satisfy s{ any(q(:add, :a, :b), q(:sub, :a, :b)) }, sexp
|
1212
1253
|
|
1213
|
-
assert_satisfy s{ any(
|
1254
|
+
assert_satisfy s{ any(q(atom, :a, :b), q(:sub, :a, :b)) }, sexp
|
1214
1255
|
end
|
1215
1256
|
|
1216
1257
|
def test_satisfy_eh_all_capture # TODO: remove
|
1217
1258
|
sexp = s(:add, :a, :b)
|
1218
|
-
assert_satisfy s{ all(
|
1259
|
+
assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
|
1219
1260
|
|
1220
|
-
assert_satisfy s{ all(
|
1261
|
+
assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
|
1221
1262
|
|
1222
|
-
assert_search 1, sexp, s{ all(
|
1263
|
+
assert_search 1, sexp, s{ all(q(_, :a, :b), q(atom, :a, :b)) }
|
1223
1264
|
end
|
1224
1265
|
end
|
1225
1266
|
|
@@ -1228,15 +1269,15 @@ class TestSexpPath < Minitest::Test
|
|
1228
1269
|
sexp = s(:a, :b, :c) # s called outside block
|
1229
1270
|
|
1230
1271
|
assert_instance_of Sexp, s{ sexp.deep_clone }
|
1231
|
-
assert_instance_of Sexp::Matcher, s{
|
1232
|
-
assert_instance_of Sexp::Matcher, s{
|
1272
|
+
assert_instance_of Sexp::Matcher, s{ q(:a, :b, :c) }
|
1273
|
+
assert_instance_of Sexp::Matcher, s{ q(:a, atom, :c) }
|
1233
1274
|
end
|
1234
1275
|
end
|
1235
1276
|
|
1236
1277
|
class TestSexpReplaceSexp < SexpTestCase
|
1237
1278
|
def test_replace_sexp
|
1238
1279
|
sexp = s(:a, s(:b), :c)
|
1239
|
-
actual = sexp.replace_sexp(s{
|
1280
|
+
actual = sexp.replace_sexp(s{ q(:b) }) { :b }
|
1240
1281
|
|
1241
1282
|
assert_equal s(:a, :b, :c), actual
|
1242
1283
|
end
|
@@ -1309,7 +1350,7 @@ class TestUseCase < SexpTestCase
|
|
1309
1350
|
end
|
1310
1351
|
|
1311
1352
|
def test_finding_classes_and_methods
|
1312
|
-
res = @sexp / s{
|
1353
|
+
res = @sexp / s{ q(:class, atom, ___ ) }
|
1313
1354
|
|
1314
1355
|
_klass, name, * = res.first
|
1315
1356
|
|
@@ -1321,7 +1362,7 @@ class TestUseCase < SexpTestCase
|
|
1321
1362
|
end
|
1322
1363
|
|
1323
1364
|
def test_finding_empty_test_methods
|
1324
|
-
empty_test = s{
|
1365
|
+
empty_test = s{ q(:defn, m(/^test_.+/), q(:args), q(:nil)) }
|
1325
1366
|
res = @sexp / empty_test
|
1326
1367
|
|
1327
1368
|
_, _, (_klass, _, _, _setup, _t1, t2, _t3) = TestUseCase.sexp.deep_clone
|
@@ -1330,7 +1371,7 @@ class TestUseCase < SexpTestCase
|
|
1330
1371
|
end
|
1331
1372
|
|
1332
1373
|
def test_search_each_finding_duplicate_test_names
|
1333
|
-
pat = s{
|
1374
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1334
1375
|
counts = Hash.new { |h, k| h[k] = 0 }
|
1335
1376
|
|
1336
1377
|
@sexp.search_each pat do |x|
|
@@ -1343,7 +1384,7 @@ class TestUseCase < SexpTestCase
|
|
1343
1384
|
end
|
1344
1385
|
|
1345
1386
|
def test_finding_duplicate_test_names_via_res
|
1346
|
-
pat = s{
|
1387
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1347
1388
|
res = @sexp / pat
|
1348
1389
|
counts = Hash.new { |h, k| h[k] = 0 }
|
1349
1390
|
|
@@ -1362,8 +1403,8 @@ class TestUseCase < SexpTestCase
|
|
1362
1403
|
end
|
1363
1404
|
|
1364
1405
|
def test_rewriting_colon2s
|
1365
|
-
colon2 = s{
|
1366
|
-
expected = s{
|
1406
|
+
colon2 = s{ q(:colon2, q(:const, atom), atom) }
|
1407
|
+
expected = s{ q(:const, "Minitest::Test") }
|
1367
1408
|
|
1368
1409
|
new_sexp = @sexp.replace_sexp(colon2) { |r|
|
1369
1410
|
(_, (_, a), b) = r
|
@@ -1388,46 +1429,46 @@ class TestSexpMatchers < SexpTestCase
|
|
1388
1429
|
SEXP = s(:class, :X, nil, s(:defn, :x, s(:args)))
|
1389
1430
|
|
1390
1431
|
def test_match_subset
|
1391
|
-
assert_match s{ child(
|
1392
|
-
assert_match s{ child(
|
1432
|
+
assert_match s{ child(q(:a)) }, s(:blah, s(:blah, s(:a)))
|
1433
|
+
assert_match s{ child(q(:a)) }, s(:a)
|
1393
1434
|
end
|
1394
1435
|
|
1395
1436
|
def test_match_simple
|
1396
|
-
assert_match s{
|
1437
|
+
assert_match s{ q(:lit, _) }, s(:lit, 42)
|
1397
1438
|
end
|
1398
1439
|
|
1399
1440
|
def test_match_mismatch_type
|
1400
|
-
refute_match s{
|
1441
|
+
refute_match s{ q(:xxx, 42) }, s(:lit, 42)
|
1401
1442
|
end
|
1402
1443
|
|
1403
1444
|
def test_match_mismatch_data
|
1404
|
-
refute_match s{
|
1445
|
+
refute_match s{ q(:lit, 24) }, s(:lit, 42)
|
1405
1446
|
end
|
1406
1447
|
|
1407
1448
|
def test_match_mismatch_length_shorter
|
1408
|
-
refute_match s{
|
1449
|
+
refute_match s{ q(:a, :b) }, s(:a, :b, :c)
|
1409
1450
|
end
|
1410
1451
|
|
1411
1452
|
def test_match_mismatch_length_longer
|
1412
|
-
refute_match s{
|
1453
|
+
refute_match s{ q(:a, :b, :c) }, s(:a, :b)
|
1413
1454
|
end
|
1414
1455
|
|
1415
1456
|
def test_match_wild
|
1416
|
-
assert_match s{
|
1457
|
+
assert_match s{ q(:class, _, _, _) }, SEXP
|
1417
1458
|
end
|
1418
1459
|
|
1419
1460
|
def test_match_rest_same_length
|
1420
|
-
assert_match s{
|
1461
|
+
assert_match s{ q(:class, _, _, ___) }, SEXP
|
1421
1462
|
end
|
1422
1463
|
|
1423
1464
|
def test_match_rest_diff_length
|
1424
1465
|
skip_if_strict
|
1425
1466
|
|
1426
|
-
assert_match s{
|
1467
|
+
assert_match s{ q(:class, ___) }, SEXP
|
1427
1468
|
end
|
1428
1469
|
|
1429
1470
|
def test_match_reversed
|
1430
|
-
assert_match SEXP, s{
|
1471
|
+
assert_match SEXP, s{ q(:class, _, _, ___) }
|
1431
1472
|
end
|
1432
1473
|
|
1433
1474
|
def assert_match_case pat, data
|
@@ -1440,7 +1481,7 @@ class TestSexpMatchers < SexpTestCase
|
|
1440
1481
|
end
|
1441
1482
|
|
1442
1483
|
def test_match_case
|
1443
|
-
assert_match_case s{
|
1484
|
+
assert_match_case s{ q(:class, _, _, ___) }, SEXP
|
1444
1485
|
end
|
1445
1486
|
|
1446
1487
|
# NOTE: eqt is =~ (equal-tilde)
|
@@ -1498,12 +1539,12 @@ class TestSexpMatchers < SexpTestCase
|
|
1498
1539
|
l_cls = s(:class, :X, nil,
|
1499
1540
|
s(:something_in_between),
|
1500
1541
|
s(:cdecl, :Y, s(:hash, s(:lit, :a), s(:lit, 1))))
|
1501
|
-
p_cls1 = s{
|
1502
|
-
p_cls2 = s{
|
1542
|
+
p_cls1 = s{ q(:class, ___) & include(q(:cdecl, _, q(:hash, ___))) }
|
1543
|
+
p_cls2 = s{ q(:class, _, _, q(:cdecl, _, q(:hash, ___))) }
|
1503
1544
|
|
1504
1545
|
x, o = true, false
|
1505
|
-
TestMatcherDirectMatch = cmt x, x, o, x, l_a, s{
|
1506
|
-
TestMatcherSubtree = cmt x, x, o, x, l_abc, s{
|
1546
|
+
TestMatcherDirectMatch = cmt x, x, o, x, l_a, s{ q(:a) }
|
1547
|
+
TestMatcherSubtree = cmt x, x, o, x, l_abc, s{ q(:c) }
|
1507
1548
|
TestMatcherSubtreeType = cmt x, x, o, x, l_abc, s{ t(:c) }
|
1508
1549
|
TestMatcherDisparateSubtree = cmt x, x, o, x, l_cls, p_cls1
|
1509
1550
|
TestMatcherDisparateSubtree2 = cmt o, o, o, o, l_cls, p_cls2 # TODO: make pass
|
@@ -1539,18 +1580,34 @@ class TestSexpMatcherParser < Minitest::Test
|
|
1539
1580
|
lambda { s(&b) }
|
1540
1581
|
end
|
1541
1582
|
|
1583
|
+
re = /(?-mix:\Aa\Z)|(?-mix:\Ab\Z)|(?-mix:\Ac\Z)/ # [m a b c]
|
1584
|
+
|
1542
1585
|
test_parse "nothing", nil, ""
|
1543
1586
|
test_parse "nil", delay{ nil }, "nil"
|
1544
|
-
test_parse "empty", delay{
|
1545
|
-
test_parse "simple", delay{
|
1546
|
-
test_parse "number", delay{
|
1547
|
-
test_parse "string", delay{
|
1548
|
-
test_parse "compound", delay{
|
1549
|
-
test_parse "complex", delay{
|
1550
|
-
test_parse "type", delay{
|
1551
|
-
test_parse "match", delay{
|
1552
|
-
test_parse "not_atom", delay{
|
1587
|
+
test_parse "empty", delay{ q() }, "()"
|
1588
|
+
test_parse "simple", delay{ q(:a) }, "(a)"
|
1589
|
+
test_parse "number", delay{ q(:a, 42) }, "(a 42)"
|
1590
|
+
test_parse "string", delay{ q(:a, "s") }, "(a \"s\")"
|
1591
|
+
test_parse "compound", delay{ q(:b) }, "(a) (b)"
|
1592
|
+
test_parse "complex", delay{ q(:a, _, q(:b, :cde), ___) }, "(a _ (b cde) ___)"
|
1593
|
+
test_parse "type", delay{ q(:a, t(:b)) }, "(a [t b])"
|
1594
|
+
test_parse "match", delay{ q(:a, m(/b/)) }, "(a [m /b/])"
|
1595
|
+
test_parse "not_atom", delay{ q(:atom) }, "(atom)"
|
1553
1596
|
test_parse "atom", delay{ atom }, "[atom]"
|
1597
|
+
test_parse "match_n", delay{ m(re) }, "[m a b c]"
|
1598
|
+
test_parse "ne", delay{ q(:call, _, :!=, _) }, "(call _ != _)"
|
1599
|
+
test_parse "eq", delay{ q(:call, _, :==, _) }, "(call _ == _)"
|
1600
|
+
test_parse "not_call", delay{ q(:call, _, :"!") }, "(call _ !)"
|
1601
|
+
test_parse "eh", delay{ q(:call, _, :include?, _) }, "(call _ include? _)"
|
1602
|
+
test_parse "under", delay{ q(:call, nil, :_, _) }, "(call nil :_ _)"
|
1603
|
+
test_parse "sym_nil", delay{ q(:call, nil, :nil, _) }, "(call nil :nil _)"
|
1604
|
+
test_parse "not?", delay{ not?(m(/^_$/)) }, "[not? [m /^_$/]]"
|
1605
|
+
test_parse "not2", delay{ -_ }, "[- _]"
|
1606
|
+
test_parse "any", delay{ q(:a) | q(:b) }, "[any (a) (b)]"
|
1607
|
+
test_parse "child", delay{ child(q(:str, m(/woot/))) }, "[child (str [m /woot/])]"
|
1608
|
+
|
1609
|
+
test_parse "klass", delay{ q(:lit, k(Float)) }, "(lit [k Float])"
|
1610
|
+
test_parse "const", delay{ q(:const, :Float) }, "(const :Float)"
|
1554
1611
|
|
1555
1612
|
test_bad_parse "open_sexp", "(a"
|
1556
1613
|
test_bad_parse "closed_sexp", "a)"
|