sexp_processor 4.12.1 → 4.17.1
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/History.rdoc +93 -0
- data/Manifest.txt +1 -0
- data/Rakefile +2 -0
- data/lib/pt_testcase.rb +16 -7
- data/lib/sexp.rb +35 -1061
- data/lib/sexp_matcher.rb +1100 -0
- data/lib/sexp_processor.rb +1 -1
- data/lib/strict_sexp.rb +28 -5
- data/test/test_sexp.rb +207 -132
- data.tar.gz.sig +0 -0
- metadata +23 -18
- metadata.gz.sig +0 -0
data/test/test_sexp.rb
CHANGED
@@ -193,6 +193,12 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
193
193
|
assert_equal(3, count, "must find 3 a's in #{@sexp.inspect}")
|
194
194
|
end
|
195
195
|
|
196
|
+
def test_each_of_type_no_block
|
197
|
+
@sexp = s(:a, s(:b), s(:c), :d)
|
198
|
+
|
199
|
+
assert_equal [s(:b)], @sexp.each_of_type(:b).to_a
|
200
|
+
end
|
201
|
+
|
196
202
|
def test_equals2_array
|
197
203
|
refute_equal @sexp, [1, 2, 3] # Sexp == Array
|
198
204
|
assert_raises Minitest::Assertion do # Array == Sexp.
|
@@ -233,16 +239,16 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
233
239
|
end
|
234
240
|
|
235
241
|
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{
|
242
|
+
assert_match s{q(:a)}, s(s(:a), s(:b)) # left - =~
|
243
|
+
assert_equal3 s{q(:a)}, s(s(:a), s(:b)) # left - ===
|
244
|
+
assert_equal3 s{q(:a)}, s(:blah, s(:a ), s(:b)) # mid 1
|
245
|
+
assert_equal3 s{q(:a, 1)}, s(:blah, s(:a, 1), s(:b)) # mid 2
|
246
|
+
assert_equal3 s{q(:a)}, s(:blah, s(:blah, s(:a))) # left deeper
|
241
247
|
end
|
242
248
|
|
243
249
|
def test_equalstilde_fancy
|
244
|
-
assert_match s{
|
245
|
-
assert_match s(:a, s(:b), :c), s{
|
250
|
+
assert_match s{ q(:b) }, s(:a, s(:b), :c)
|
251
|
+
assert_match s(:a, s(:b), :c), s{ q(:b) }
|
246
252
|
|
247
253
|
e = assert_raises ArgumentError do
|
248
254
|
s(:b) =~ s(:a, s(:b), :c)
|
@@ -256,8 +262,8 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
256
262
|
end
|
257
263
|
|
258
264
|
def test_equalstilde_plain
|
259
|
-
s{
|
260
|
-
s(:data) =~ s{
|
265
|
+
s{ q(:re) } =~ s(:data) # pattern on LHS
|
266
|
+
s(:data) =~ s{ q(:re) } # pattern on RHS
|
261
267
|
|
262
268
|
e = assert_raises ArgumentError do
|
263
269
|
s(:re) =~ s(:data) # no pattern
|
@@ -297,10 +303,10 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
297
303
|
end
|
298
304
|
|
299
305
|
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{
|
306
|
+
assert_gsub s(:a, :b, :c), s(:a, s(:b, 42), :c), s{ q(:b, _) }, :b
|
307
|
+
assert_gsub s(:a, s(:b), :c), s(:a, s(:b), :c), s{ q(:b, _) }, :b
|
308
|
+
assert_gsub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{ q(:b, _) }, :b
|
309
|
+
assert_gsub s(:a, s(:q), :c), s(:a, s(:q), :c), s{ q(:b, _) }, :b
|
304
310
|
end
|
305
311
|
|
306
312
|
def with_env key
|
@@ -529,8 +535,6 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
529
535
|
def test_shift
|
530
536
|
skip_if_strict 5
|
531
537
|
|
532
|
-
skip "https://github.com/MagLev/maglev/issues/250" if maglev?
|
533
|
-
|
534
538
|
assert_equal(1, @sexp.shift)
|
535
539
|
assert_equal(2, @sexp.shift)
|
536
540
|
assert_equal(3, @sexp.shift)
|
@@ -589,14 +593,14 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
589
593
|
end
|
590
594
|
|
591
595
|
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{
|
596
|
+
assert_sub s(:c), s(:b), s{ q(:b) }, s(:c)
|
597
|
+
assert_sub s(:a, s(:c), s(:b)), s(:a, s(:b), s(:b)), s{ q(:b) }, s(:c)
|
598
|
+
assert_sub s(:a, s(:c), s(:a)), s(:a, s(:b), s(:a)), s{ q(:b) }, s(:c)
|
595
599
|
|
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{
|
600
|
+
assert_sub s(:a, :b, :c), s(:a, s(:b, 42), :c), s{ q(:b, _) }, :b
|
601
|
+
assert_sub s(:a, s(:b), :c), s(:a, s(:b), :c), s{ q(:b, _) }, :b
|
602
|
+
assert_sub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{ q(:b, _) }, :b
|
603
|
+
assert_sub s(:a, s(:q), :c), s(:a, s(:q), :c), s{ q(:b, _) }, :b
|
600
604
|
end
|
601
605
|
|
602
606
|
def test_sub_structure
|
@@ -656,6 +660,18 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
656
660
|
assert_equal DEEP_EXP, act.map { |k, _| k }
|
657
661
|
end
|
658
662
|
|
663
|
+
def test_deep_each_sexp_recursive
|
664
|
+
sexp = s(:array, s(:lit, 1), nil, 42, s(:array, s(:lit, 2)))
|
665
|
+
|
666
|
+
result = []
|
667
|
+
sexp.deep_each { |x| result << x.last if x.sexp_type == :lit }
|
668
|
+
assert_equal [1, 2], result
|
669
|
+
|
670
|
+
result = []
|
671
|
+
sexp.each_of_type(:lit) { |x| result << x.last }
|
672
|
+
assert_equal [1, 2], result
|
673
|
+
end
|
674
|
+
|
659
675
|
def test_deep_each_skip
|
660
676
|
exp = DEEP_EXP.first(3) + DEEP_EXP.last(4)
|
661
677
|
act = []
|
@@ -682,7 +698,7 @@ end # TestSexp
|
|
682
698
|
|
683
699
|
class TestSexpMatcher < SexpTestCase
|
684
700
|
def test_cls_s
|
685
|
-
assert_equal M.
|
701
|
+
assert_equal M.q(:x), s{ q(:x) }
|
686
702
|
end
|
687
703
|
|
688
704
|
def test_cls_underscore
|
@@ -702,19 +718,19 @@ class TestSexpMatcher < SexpTestCase
|
|
702
718
|
end
|
703
719
|
|
704
720
|
def test_cls_any
|
705
|
-
assert_equal M::Any.new(M.
|
721
|
+
assert_equal M::Any.new(M.q(:a), M.q(:b)), s{ any(q(:a), q(:b)) }
|
706
722
|
end
|
707
723
|
|
708
724
|
def test_cls_all
|
709
|
-
assert_equal M::All.new(M.
|
725
|
+
assert_equal M::All.new(M.q(:a), M.q(:b)), s{ all(q(:a), q(:b)) }
|
710
726
|
end
|
711
727
|
|
712
728
|
def test_cls_not_eh
|
713
|
-
assert_equal M::Not.new(M.
|
729
|
+
assert_equal M::Not.new(M.q(:a)), s{ not?(q(:a)) }
|
714
730
|
end
|
715
731
|
|
716
732
|
def test_cls_child
|
717
|
-
assert_equal M::Child.new(M.
|
733
|
+
assert_equal M::Child.new(M.q(:a)), s{ child(q(:a)) }
|
718
734
|
end
|
719
735
|
|
720
736
|
def test_cls_t
|
@@ -722,45 +738,51 @@ class TestSexpMatcher < SexpTestCase
|
|
722
738
|
end
|
723
739
|
|
724
740
|
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
741
|
re = Regexp.union [/\w/, /\d/]
|
729
|
-
|
742
|
+
|
743
|
+
assert_equal M::Pattern.new(/a/), s{ m(/a/) }
|
744
|
+
assert_equal M::Pattern.new(/\Aa\Z/), s{ m(:a) }
|
745
|
+
assert_equal M::Pattern.new(/test_\w/), s{ m(/test_\w/) }
|
746
|
+
assert_equal M::Pattern.new(re), s{ m(/\w/,/\d/) }
|
747
|
+
end
|
748
|
+
|
749
|
+
def test_cls_k
|
750
|
+
assert_equal M::Klass.new(Float), s{ k(Float) }
|
751
|
+
assert_operator M::Klass.new(Float), :===, 6.28
|
730
752
|
end
|
731
753
|
|
732
754
|
def test_amp
|
733
|
-
m = s{
|
734
|
-
e = M::All.new(M.
|
755
|
+
m = s{ q(:a) & q(:b) }
|
756
|
+
e = M::All.new(M.q(:a), M.q(:b))
|
735
757
|
|
736
758
|
assert_equal e, m
|
737
759
|
end
|
738
760
|
|
739
761
|
def test_pipe
|
740
|
-
m = s{
|
741
|
-
e = M::Any.new(M.
|
762
|
+
m = s{ q(:a) | q(:b) }
|
763
|
+
e = M::Any.new(M.q(:a), M.q(:b))
|
742
764
|
|
743
765
|
assert_equal e, m
|
744
766
|
end
|
745
767
|
|
746
768
|
def test_unary_minus
|
747
|
-
assert_equal M::Not.new(M.
|
769
|
+
assert_equal M::Not.new(M.q(:a)), s{ -q(:a) }
|
748
770
|
end
|
749
771
|
|
750
772
|
def test_rchevron
|
751
|
-
assert_equal M::Sibling.new(M.
|
773
|
+
assert_equal M::Sibling.new(M.q(:a), M.q(:b)), s{ q(:a) >> q(:b) }
|
752
774
|
end
|
753
775
|
|
754
776
|
def test_greedy_eh
|
755
|
-
refute_operator s{
|
777
|
+
refute_operator s{ q(:a) }, :greedy?
|
756
778
|
end
|
757
779
|
|
758
780
|
def test_inspect
|
759
|
-
assert_inspect "q(:a)", s{
|
781
|
+
assert_inspect "q(:a)", s{ q(:a) }
|
760
782
|
end
|
761
783
|
|
762
784
|
def test_pretty_print
|
763
|
-
assert_pretty_print "q(:a)", s{
|
785
|
+
assert_pretty_print "q(:a)", s{ q(:a) }
|
764
786
|
end
|
765
787
|
end # class TestSexpMatcher
|
766
788
|
|
@@ -790,11 +812,11 @@ class TestWild < MatcherTestCase
|
|
790
812
|
def test_wild_search # TODO: possibly remove
|
791
813
|
sexp = CLASS_SEXP.dup
|
792
814
|
|
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{
|
815
|
+
assert_search 1, s(:add, :a, :b), s{ q(:add, _, :b) }
|
816
|
+
assert_search 1, sexp, s{ q(:defn, :bar, _, _) }
|
817
|
+
assert_search 2, sexp, s{ q(:defn, _, _, q(_, :a, :b) ) }
|
818
|
+
assert_search 1, s(:a, s()), s{ q(:a, _) }
|
819
|
+
assert_search 1, s(:a, :b, :c), s{ q(_, _, _) }
|
798
820
|
assert_search 7, sexp, s{ _ }
|
799
821
|
end
|
800
822
|
end
|
@@ -815,8 +837,8 @@ class TestRemaining < MatcherTestCase
|
|
815
837
|
def test_remaining_satisfy_eh # TODO: possibly remove
|
816
838
|
assert_satisfy s{ ___ }, s(:a)
|
817
839
|
assert_satisfy s{ ___ }, s(:a, :b, :c)
|
818
|
-
assert_satisfy s{
|
819
|
-
refute_satisfy s{
|
840
|
+
assert_satisfy s{ q(:x, ___ ) }, s(:x, :y)
|
841
|
+
refute_satisfy s{ q(:y, ___ ) }, s(:x, :y)
|
820
842
|
end
|
821
843
|
|
822
844
|
def test_greedy
|
@@ -826,7 +848,7 @@ end
|
|
826
848
|
|
827
849
|
class TestAny < MatcherTestCase
|
828
850
|
def matcher
|
829
|
-
s{
|
851
|
+
s{ q(:a) | q(:c) }
|
830
852
|
end
|
831
853
|
|
832
854
|
def inspect_str
|
@@ -838,26 +860,26 @@ class TestAny < MatcherTestCase
|
|
838
860
|
end
|
839
861
|
|
840
862
|
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(
|
863
|
+
assert_search 2, s(:foo, s(:a), s(:b)), s{ q(any(:a, :b)) }
|
864
|
+
assert_search 1, s(:foo, s(:a), s(:b)), s{ any( q(:a), q(:c)) }
|
843
865
|
end
|
844
866
|
|
845
867
|
def test_or_satisfy_eh # TODO: possibly remove
|
846
|
-
assert_satisfy s{
|
847
|
-
refute_satisfy s{
|
868
|
+
assert_satisfy s{ q(:a) | q(:b) }, s(:a)
|
869
|
+
refute_satisfy s{ q(:a) | q(:b) }, s(:c)
|
848
870
|
end
|
849
871
|
|
850
872
|
def test_or_search # TODO: possibly remove
|
851
873
|
sexp = CLASS_SEXP.dup
|
852
874
|
|
853
|
-
assert_search 2, s(:a, s(:b, :c), s(:b, :d)), s{
|
854
|
-
assert_search 2, sexp, s{
|
875
|
+
assert_search 2, s(:a, s(:b, :c), s(:b, :d)), s{ q(:b, :c) | q(:b, :d) }
|
876
|
+
assert_search 2, sexp, s{ q(:add, :a, :b) | q(:defn, :bar, _, _) }
|
855
877
|
end
|
856
878
|
end
|
857
879
|
|
858
880
|
class TestAll < MatcherTestCase
|
859
881
|
def matcher
|
860
|
-
s{
|
882
|
+
s{ q(:a) & q(:a) }
|
861
883
|
end
|
862
884
|
|
863
885
|
def inspect_str
|
@@ -869,14 +891,14 @@ class TestAll < MatcherTestCase
|
|
869
891
|
end
|
870
892
|
|
871
893
|
def test_and_satisfy_eh # TODO: possibly remove
|
872
|
-
refute_satisfy s{
|
873
|
-
assert_satisfy s{
|
894
|
+
refute_satisfy s{ q(:a) & q(:b) }, s(:a)
|
895
|
+
assert_satisfy s{ q(:a) & q(atom) }, s(:a)
|
874
896
|
end
|
875
897
|
end
|
876
898
|
|
877
899
|
class TestNot < MatcherTestCase
|
878
900
|
def matcher
|
879
|
-
s{ not?
|
901
|
+
s{ not? q(:b) } # TODO: test unary minus
|
880
902
|
end
|
881
903
|
|
882
904
|
def inspect_str
|
@@ -889,20 +911,20 @@ class TestNot < MatcherTestCase
|
|
889
911
|
|
890
912
|
def test_not_satisfy_eh # TODO: possibly remove
|
891
913
|
refute_satisfy s{ -_ }, s(:a)
|
892
|
-
assert_satisfy s{ -
|
893
|
-
assert_satisfy s{ not?(
|
894
|
-
refute_satisfy s{ -
|
895
|
-
assert_satisfy s{
|
914
|
+
assert_satisfy s{ -q(:b) }, s(:a)
|
915
|
+
assert_satisfy s{ not?(q(:b)) }, s(:a)
|
916
|
+
refute_satisfy s{ -q(atom) }, s(:a)
|
917
|
+
assert_satisfy s{ q(not?(:b)) }, s(:a)
|
896
918
|
end
|
897
919
|
end
|
898
920
|
|
899
921
|
class TestChild < MatcherTestCase
|
900
922
|
def matcher
|
901
|
-
s{ child(
|
923
|
+
s{ child(q(:a)) }
|
902
924
|
end
|
903
925
|
|
904
926
|
def sexp
|
905
|
-
s(:x, s(:a))
|
927
|
+
s(:x, s(:b), s(:a))
|
906
928
|
end
|
907
929
|
|
908
930
|
def bad_sexp
|
@@ -916,12 +938,14 @@ class TestChild < MatcherTestCase
|
|
916
938
|
def test_child_search # TODO: possibly remove
|
917
939
|
sexp = CLASS_SEXP.dup
|
918
940
|
|
919
|
-
assert_search 1, sexp, s{
|
920
|
-
assert_search 1, sexp, s{
|
941
|
+
assert_search 1, sexp, s{ q(:class, :cake, _, _, child( q(:sub, :a, :b) ) ) }
|
942
|
+
assert_search 1, sexp, s{ q(:class, :cake, _, _, child(include(:a))) }
|
921
943
|
end
|
922
944
|
|
923
945
|
def test_satisfy_eh_by_child
|
924
946
|
assert_satisfy matcher, s(:a)
|
947
|
+
assert_satisfy matcher, sexp
|
948
|
+
refute_satisfy matcher, bad_sexp
|
925
949
|
end
|
926
950
|
end
|
927
951
|
|
@@ -954,15 +978,15 @@ class TestAtom < MatcherTestCase
|
|
954
978
|
def test_atom_search # TODO: possibly remove
|
955
979
|
sexp = CLASS_SEXP.dup
|
956
980
|
|
957
|
-
assert_search 1, s(:add, :a, :b), s{
|
958
|
-
assert_search 2, sexp, s{
|
959
|
-
assert_search 0, s(:a, s()), s{
|
981
|
+
assert_search 1, s(:add, :a, :b), s{ q(:add, atom, :b) }
|
982
|
+
assert_search 2, sexp, s{ q(:defn, atom, _, q(atom, :a, :b) ) }
|
983
|
+
assert_search 0, s(:a, s()), s{ q(:a, atom) }
|
960
984
|
end
|
961
985
|
end
|
962
986
|
|
963
987
|
class TestPattern < MatcherTestCase
|
964
988
|
def matcher
|
965
|
-
s{
|
989
|
+
s{ q(:a, m(/a/)) }
|
966
990
|
end
|
967
991
|
|
968
992
|
def sexp
|
@@ -984,15 +1008,15 @@ class TestPattern < MatcherTestCase
|
|
984
1008
|
def test_pattern_search # TODO: possibly remove
|
985
1009
|
sexp = CLASS_SEXP.dup
|
986
1010
|
|
987
|
-
assert_search 2, sexp, s{
|
1011
|
+
assert_search 2, sexp, s{ q(m(/\w{3}/), :a, :b) }
|
988
1012
|
|
989
1013
|
assert_search 0, s(:a), s{ m(/\w/) }
|
990
|
-
assert_search 1, s(:a), s{
|
1014
|
+
assert_search 1, s(:a), s{ q(m(/\w/)) }
|
991
1015
|
assert_search 0, s(:a), s{ m(/\w/,/\d/) }
|
992
|
-
assert_search 1, s(:a), s{
|
1016
|
+
assert_search 1, s(:a), s{ q(m(/\w/,/\d/)) }
|
993
1017
|
|
994
1018
|
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{
|
1019
|
+
assert_search 2, s(:tests, s(s(:test_a), s(:test_b))), s{ q(m(/test_\w/)) }
|
996
1020
|
end
|
997
1021
|
end
|
998
1022
|
|
@@ -1021,7 +1045,7 @@ class TestInclude < MatcherTestCase
|
|
1021
1045
|
end
|
1022
1046
|
|
1023
1047
|
def matcher
|
1024
|
-
s{ include(
|
1048
|
+
s{ include(q(:a)) }
|
1025
1049
|
end
|
1026
1050
|
|
1027
1051
|
def inspect_str
|
@@ -1033,9 +1057,9 @@ class TestInclude < MatcherTestCase
|
|
1033
1057
|
|
1034
1058
|
assert_search 1, s(:add, :a, :b), s{ include(:a) }
|
1035
1059
|
assert_search 1, sexp, s{ include(:bar) }
|
1036
|
-
assert_search 2, sexp, s{
|
1060
|
+
assert_search 2, sexp, s{ q(:defn, atom, _, include(:a)) }
|
1037
1061
|
assert_search 2, sexp, s{ include(:a) }
|
1038
|
-
assert_search 0, s(:a, s(:b, s(:c))), s{
|
1062
|
+
assert_search 0, s(:a, s(:b, s(:c))), s{ q(:a, include(:c)) }
|
1039
1063
|
end
|
1040
1064
|
end
|
1041
1065
|
|
@@ -1045,7 +1069,7 @@ class TestSibling < MatcherTestCase
|
|
1045
1069
|
end
|
1046
1070
|
|
1047
1071
|
def matcher
|
1048
|
-
s{
|
1072
|
+
s{ q(:a) >> q(:b) }
|
1049
1073
|
end
|
1050
1074
|
|
1051
1075
|
def inspect_str
|
@@ -1053,15 +1077,15 @@ class TestSibling < MatcherTestCase
|
|
1053
1077
|
end
|
1054
1078
|
|
1055
1079
|
def test_pretty_print_distance
|
1056
|
-
m = s{ M::Sibling.new(
|
1080
|
+
m = s{ M::Sibling.new(q(:a), q(:b), 3) } # maybe q(:a) << q(:b) << 3 ?
|
1057
1081
|
assert_pretty_print "sibling(q(:a), q(:b), 3)", m
|
1058
1082
|
end
|
1059
1083
|
|
1060
1084
|
def test_sibling_satisfy_eh # TODO: possibly remove
|
1061
|
-
a_a = s{
|
1062
|
-
a_b = s{
|
1063
|
-
a_c = s{
|
1064
|
-
c_a = s{
|
1085
|
+
a_a = s{ q(:a) >> q(:a) }
|
1086
|
+
a_b = s{ q(:a) >> q(:b) }
|
1087
|
+
a_c = s{ q(:a) >> q(:c) }
|
1088
|
+
c_a = s{ q(:c) >> q(:a) }
|
1065
1089
|
|
1066
1090
|
assert_satisfy a_b, s(s(:a), s(:b))
|
1067
1091
|
assert_satisfy a_b, s(s(:a), s(:b), s(:c))
|
@@ -1093,8 +1117,8 @@ class TestMatchCollection < SexpTestCase
|
|
1093
1117
|
s(:defn, :foo, s(:args), s(:add, :a, :b)),
|
1094
1118
|
s(:defn, :bar, s(:args), s(:sub, :a, :b)))
|
1095
1119
|
|
1096
|
-
res = sexp / s{
|
1097
|
-
act = res / s{
|
1120
|
+
res = sexp / s{ q(:class, atom, _, ___) } # sexp / pat => MC
|
1121
|
+
act = res / s{ q(:defn, atom, ___) } # MC / pat => MC
|
1098
1122
|
|
1099
1123
|
_, _, _, defn1, defn2 = sexp
|
1100
1124
|
|
@@ -1150,8 +1174,43 @@ class TestSexpSearch < SexpTestCase
|
|
1150
1174
|
MR.new sexp.deep_clone, hash
|
1151
1175
|
end
|
1152
1176
|
|
1177
|
+
def test_sexp_hash
|
1178
|
+
s1 = s(:a)
|
1179
|
+
s2 = s(nil)
|
1180
|
+
refute_equal s1.hash, s2.hash
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def test_matcher_inspect
|
1184
|
+
pat1 = M.parse "(a [m /b/] (c))"
|
1185
|
+
|
1186
|
+
assert_equal "q(:a, m(/b/), q(:c))", pat1.inspect
|
1187
|
+
end
|
1188
|
+
|
1189
|
+
def test_matcher_hash
|
1190
|
+
a = M::Pattern.new(/x/) # M.parse "[m /x/]"
|
1191
|
+
b = M::Atom.new # M.parse "_"
|
1192
|
+
|
1193
|
+
refute_operator a, :eql?, b
|
1194
|
+
refute_equal a.hash, b.hash
|
1195
|
+
|
1196
|
+
h = {}
|
1197
|
+
h[a] = true
|
1198
|
+
refute_operator h, :key?, b
|
1199
|
+
|
1200
|
+
# original problem:
|
1201
|
+
a = M.parse "(call nil assert_equal (true) (call _ [m /include./] _))"
|
1202
|
+
b = M.parse "(call nil assert_equal (true) (call _ _ _))"
|
1203
|
+
|
1204
|
+
refute_operator a, :eql?, b
|
1205
|
+
refute_equal a.hash, b.hash
|
1206
|
+
|
1207
|
+
h = {}
|
1208
|
+
h[a] = true
|
1209
|
+
refute_operator h, :key?, b
|
1210
|
+
end
|
1211
|
+
|
1153
1212
|
def test_slash_simple
|
1154
|
-
act = sexp / s{
|
1213
|
+
act = sexp / s{ q(:class, atom, _, ___) }
|
1155
1214
|
|
1156
1215
|
exp = MC.new
|
1157
1216
|
exp << sexp.deep_clone
|
@@ -1160,7 +1219,7 @@ class TestSexpSearch < SexpTestCase
|
|
1160
1219
|
end
|
1161
1220
|
|
1162
1221
|
def test_slash_subsexp
|
1163
|
-
act = sexp / s{
|
1222
|
+
act = sexp / s{ q(:defn, atom, ___) }
|
1164
1223
|
|
1165
1224
|
exp = MC.new
|
1166
1225
|
exp << s(:defn, :foo, s(:args), s(:add, :a, :b))
|
@@ -1170,7 +1229,7 @@ class TestSexpSearch < SexpTestCase
|
|
1170
1229
|
end
|
1171
1230
|
|
1172
1231
|
def test_slash_data
|
1173
|
-
pat = s{
|
1232
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1174
1233
|
|
1175
1234
|
_, _, (_klass, _, _, _setup, t1, t2, t3) = TestUseCase.sexp.deep_clone
|
1176
1235
|
exp = [t1, t2, t3]
|
@@ -1199,27 +1258,27 @@ class TestSexpSearch < SexpTestCase
|
|
1199
1258
|
assert_search 0, sexp, :class # non-pattern should raise
|
1200
1259
|
end
|
1201
1260
|
|
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{
|
1261
|
+
assert_search 0, sexp, s{ q(:class) }
|
1262
|
+
assert_search 1, sexp, s{ q(:add, :a, :b) }
|
1263
|
+
assert_search 1, s(:a, s(:b, s(:c))), s{ q(:b, q(:c)) }
|
1264
|
+
assert_search 0, s(:a, s(:b, s(:c))), s{ q(:a, q(:c)) }
|
1265
|
+
assert_search 1, sexp, s{ q(:defn, :bar, _, q(:sub, :a, :b)) }
|
1207
1266
|
end
|
1208
1267
|
|
1209
1268
|
def test_satisfy_eh_any_capture # TODO: remove
|
1210
1269
|
sexp = s(:add, :a, :b)
|
1211
|
-
assert_satisfy s{ any(
|
1270
|
+
assert_satisfy s{ any(q(:add, :a, :b), q(:sub, :a, :b)) }, sexp
|
1212
1271
|
|
1213
|
-
assert_satisfy s{ any(
|
1272
|
+
assert_satisfy s{ any(q(atom, :a, :b), q(:sub, :a, :b)) }, sexp
|
1214
1273
|
end
|
1215
1274
|
|
1216
1275
|
def test_satisfy_eh_all_capture # TODO: remove
|
1217
1276
|
sexp = s(:add, :a, :b)
|
1218
|
-
assert_satisfy s{ all(
|
1277
|
+
assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
|
1219
1278
|
|
1220
|
-
assert_satisfy s{ all(
|
1279
|
+
assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
|
1221
1280
|
|
1222
|
-
assert_search 1, sexp, s{ all(
|
1281
|
+
assert_search 1, sexp, s{ all(q(_, :a, :b), q(atom, :a, :b)) }
|
1223
1282
|
end
|
1224
1283
|
end
|
1225
1284
|
|
@@ -1228,15 +1287,15 @@ class TestSexpPath < Minitest::Test
|
|
1228
1287
|
sexp = s(:a, :b, :c) # s called outside block
|
1229
1288
|
|
1230
1289
|
assert_instance_of Sexp, s{ sexp.deep_clone }
|
1231
|
-
assert_instance_of Sexp::Matcher, s{
|
1232
|
-
assert_instance_of Sexp::Matcher, s{
|
1290
|
+
assert_instance_of Sexp::Matcher, s{ q(:a, :b, :c) }
|
1291
|
+
assert_instance_of Sexp::Matcher, s{ q(:a, atom, :c) }
|
1233
1292
|
end
|
1234
1293
|
end
|
1235
1294
|
|
1236
1295
|
class TestSexpReplaceSexp < SexpTestCase
|
1237
1296
|
def test_replace_sexp
|
1238
1297
|
sexp = s(:a, s(:b), :c)
|
1239
|
-
actual = sexp.replace_sexp(s{
|
1298
|
+
actual = sexp.replace_sexp(s{ q(:b) }) { :b }
|
1240
1299
|
|
1241
1300
|
assert_equal s(:a, :b, :c), actual
|
1242
1301
|
end
|
@@ -1309,7 +1368,7 @@ class TestUseCase < SexpTestCase
|
|
1309
1368
|
end
|
1310
1369
|
|
1311
1370
|
def test_finding_classes_and_methods
|
1312
|
-
res = @sexp / s{
|
1371
|
+
res = @sexp / s{ q(:class, atom, ___ ) }
|
1313
1372
|
|
1314
1373
|
_klass, name, * = res.first
|
1315
1374
|
|
@@ -1321,7 +1380,7 @@ class TestUseCase < SexpTestCase
|
|
1321
1380
|
end
|
1322
1381
|
|
1323
1382
|
def test_finding_empty_test_methods
|
1324
|
-
empty_test = s{
|
1383
|
+
empty_test = s{ q(:defn, m(/^test_.+/), q(:args), q(:nil)) }
|
1325
1384
|
res = @sexp / empty_test
|
1326
1385
|
|
1327
1386
|
_, _, (_klass, _, _, _setup, _t1, t2, _t3) = TestUseCase.sexp.deep_clone
|
@@ -1330,7 +1389,7 @@ class TestUseCase < SexpTestCase
|
|
1330
1389
|
end
|
1331
1390
|
|
1332
1391
|
def test_search_each_finding_duplicate_test_names
|
1333
|
-
pat = s{
|
1392
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1334
1393
|
counts = Hash.new { |h, k| h[k] = 0 }
|
1335
1394
|
|
1336
1395
|
@sexp.search_each pat do |x|
|
@@ -1343,7 +1402,7 @@ class TestUseCase < SexpTestCase
|
|
1343
1402
|
end
|
1344
1403
|
|
1345
1404
|
def test_finding_duplicate_test_names_via_res
|
1346
|
-
pat = s{
|
1405
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1347
1406
|
res = @sexp / pat
|
1348
1407
|
counts = Hash.new { |h, k| h[k] = 0 }
|
1349
1408
|
|
@@ -1362,8 +1421,8 @@ class TestUseCase < SexpTestCase
|
|
1362
1421
|
end
|
1363
1422
|
|
1364
1423
|
def test_rewriting_colon2s
|
1365
|
-
colon2 = s{
|
1366
|
-
expected = s{
|
1424
|
+
colon2 = s{ q(:colon2, q(:const, atom), atom) }
|
1425
|
+
expected = s{ q(:const, "Minitest::Test") }
|
1367
1426
|
|
1368
1427
|
new_sexp = @sexp.replace_sexp(colon2) { |r|
|
1369
1428
|
(_, (_, a), b) = r
|
@@ -1388,46 +1447,46 @@ class TestSexpMatchers < SexpTestCase
|
|
1388
1447
|
SEXP = s(:class, :X, nil, s(:defn, :x, s(:args)))
|
1389
1448
|
|
1390
1449
|
def test_match_subset
|
1391
|
-
assert_match s{ child(
|
1392
|
-
assert_match s{ child(
|
1450
|
+
assert_match s{ child(q(:a)) }, s(:blah, s(:blah, s(:a)))
|
1451
|
+
assert_match s{ child(q(:a)) }, s(:a)
|
1393
1452
|
end
|
1394
1453
|
|
1395
1454
|
def test_match_simple
|
1396
|
-
assert_match s{
|
1455
|
+
assert_match s{ q(:lit, _) }, s(:lit, 42)
|
1397
1456
|
end
|
1398
1457
|
|
1399
1458
|
def test_match_mismatch_type
|
1400
|
-
refute_match s{
|
1459
|
+
refute_match s{ q(:xxx, 42) }, s(:lit, 42)
|
1401
1460
|
end
|
1402
1461
|
|
1403
1462
|
def test_match_mismatch_data
|
1404
|
-
refute_match s{
|
1463
|
+
refute_match s{ q(:lit, 24) }, s(:lit, 42)
|
1405
1464
|
end
|
1406
1465
|
|
1407
1466
|
def test_match_mismatch_length_shorter
|
1408
|
-
refute_match s{
|
1467
|
+
refute_match s{ q(:a, :b) }, s(:a, :b, :c)
|
1409
1468
|
end
|
1410
1469
|
|
1411
1470
|
def test_match_mismatch_length_longer
|
1412
|
-
refute_match s{
|
1471
|
+
refute_match s{ q(:a, :b, :c) }, s(:a, :b)
|
1413
1472
|
end
|
1414
1473
|
|
1415
1474
|
def test_match_wild
|
1416
|
-
assert_match s{
|
1475
|
+
assert_match s{ q(:class, _, _, _) }, SEXP
|
1417
1476
|
end
|
1418
1477
|
|
1419
1478
|
def test_match_rest_same_length
|
1420
|
-
assert_match s{
|
1479
|
+
assert_match s{ q(:class, _, _, ___) }, SEXP
|
1421
1480
|
end
|
1422
1481
|
|
1423
1482
|
def test_match_rest_diff_length
|
1424
1483
|
skip_if_strict
|
1425
1484
|
|
1426
|
-
assert_match s{
|
1485
|
+
assert_match s{ q(:class, ___) }, SEXP
|
1427
1486
|
end
|
1428
1487
|
|
1429
1488
|
def test_match_reversed
|
1430
|
-
assert_match SEXP, s{
|
1489
|
+
assert_match SEXP, s{ q(:class, _, _, ___) }
|
1431
1490
|
end
|
1432
1491
|
|
1433
1492
|
def assert_match_case pat, data
|
@@ -1440,7 +1499,7 @@ class TestSexpMatchers < SexpTestCase
|
|
1440
1499
|
end
|
1441
1500
|
|
1442
1501
|
def test_match_case
|
1443
|
-
assert_match_case s{
|
1502
|
+
assert_match_case s{ q(:class, _, _, ___) }, SEXP
|
1444
1503
|
end
|
1445
1504
|
|
1446
1505
|
# NOTE: eqt is =~ (equal-tilde)
|
@@ -1498,12 +1557,12 @@ class TestSexpMatchers < SexpTestCase
|
|
1498
1557
|
l_cls = s(:class, :X, nil,
|
1499
1558
|
s(:something_in_between),
|
1500
1559
|
s(:cdecl, :Y, s(:hash, s(:lit, :a), s(:lit, 1))))
|
1501
|
-
p_cls1 = s{
|
1502
|
-
p_cls2 = s{
|
1560
|
+
p_cls1 = s{ q(:class, ___) & include(q(:cdecl, _, q(:hash, ___))) }
|
1561
|
+
p_cls2 = s{ q(:class, _, _, q(:cdecl, _, q(:hash, ___))) }
|
1503
1562
|
|
1504
1563
|
x, o = true, false
|
1505
|
-
TestMatcherDirectMatch = cmt x, x, o, x, l_a, s{
|
1506
|
-
TestMatcherSubtree = cmt x, x, o, x, l_abc, s{
|
1564
|
+
TestMatcherDirectMatch = cmt x, x, o, x, l_a, s{ q(:a) }
|
1565
|
+
TestMatcherSubtree = cmt x, x, o, x, l_abc, s{ q(:c) }
|
1507
1566
|
TestMatcherSubtreeType = cmt x, x, o, x, l_abc, s{ t(:c) }
|
1508
1567
|
TestMatcherDisparateSubtree = cmt x, x, o, x, l_cls, p_cls1
|
1509
1568
|
TestMatcherDisparateSubtree2 = cmt o, o, o, o, l_cls, p_cls2 # TODO: make pass
|
@@ -1539,18 +1598,34 @@ class TestSexpMatcherParser < Minitest::Test
|
|
1539
1598
|
lambda { s(&b) }
|
1540
1599
|
end
|
1541
1600
|
|
1601
|
+
re = /(?-mix:\Aa\Z)|(?-mix:\Ab\Z)|(?-mix:\Ac\Z)/ # [m a b c]
|
1602
|
+
|
1542
1603
|
test_parse "nothing", nil, ""
|
1543
1604
|
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{
|
1605
|
+
test_parse "empty", delay{ q() }, "()"
|
1606
|
+
test_parse "simple", delay{ q(:a) }, "(a)"
|
1607
|
+
test_parse "number", delay{ q(:a, 42) }, "(a 42)"
|
1608
|
+
test_parse "string", delay{ q(:a, "s") }, "(a \"s\")"
|
1609
|
+
test_parse "compound", delay{ q(:b) }, "(a) (b)"
|
1610
|
+
test_parse "complex", delay{ q(:a, _, q(:b, :cde), ___) }, "(a _ (b cde) ___)"
|
1611
|
+
test_parse "type", delay{ q(:a, t(:b)) }, "(a [t b])"
|
1612
|
+
test_parse "match", delay{ q(:a, m(/b/)) }, "(a [m /b/])"
|
1613
|
+
test_parse "not_atom", delay{ q(:atom) }, "(atom)"
|
1553
1614
|
test_parse "atom", delay{ atom }, "[atom]"
|
1615
|
+
test_parse "match_n", delay{ m(re) }, "[m a b c]"
|
1616
|
+
test_parse "ne", delay{ q(:call, _, :!=, _) }, "(call _ != _)"
|
1617
|
+
test_parse "eq", delay{ q(:call, _, :==, _) }, "(call _ == _)"
|
1618
|
+
test_parse "not_call", delay{ q(:call, _, :"!") }, "(call _ !)"
|
1619
|
+
test_parse "eh", delay{ q(:call, _, :include?, _) }, "(call _ include? _)"
|
1620
|
+
test_parse "under", delay{ q(:call, nil, :_, _) }, "(call nil :_ _)"
|
1621
|
+
test_parse "sym_nil", delay{ q(:call, nil, :nil, _) }, "(call nil :nil _)"
|
1622
|
+
test_parse "not?", delay{ not?(m(/^_$/)) }, "[not? [m /^_$/]]"
|
1623
|
+
test_parse "not2", delay{ -_ }, "[- _]"
|
1624
|
+
test_parse "any", delay{ q(:a) | q(:b) }, "[any (a) (b)]"
|
1625
|
+
test_parse "child", delay{ child(q(:str, m(/woot/))) }, "[child (str [m /woot/])]"
|
1626
|
+
|
1627
|
+
test_parse "klass", delay{ q(:lit, k(Float)) }, "(lit [k Float])"
|
1628
|
+
test_parse "const", delay{ q(:const, :Float) }, "(const :Float)"
|
1554
1629
|
|
1555
1630
|
test_bad_parse "open_sexp", "(a"
|
1556
1631
|
test_bad_parse "closed_sexp", "a)"
|