sexp_processor 4.11.0 → 4.16.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 +1 -3
- data/History.rdoc +88 -0
- data/Manifest.txt +1 -0
- data/Rakefile +2 -0
- data/lib/pt_testcase.rb +22 -19
- data/lib/sexp.rb +32 -1061
- data/lib/sexp_matcher.rb +1100 -0
- data/lib/sexp_processor.rb +2 -2
- data/lib/strict_sexp.rb +26 -4
- data/test/test_sexp.rb +213 -134
- data/test/test_sexp_processor.rb +2 -2
- data.tar.gz.sig +1 -2
- metadata +32 -22
- 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
|
@@ -519,14 +525,16 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
519
525
|
end
|
520
526
|
|
521
527
|
def test_sexp_body
|
522
|
-
assert_equal
|
528
|
+
assert_equal s(2, 3), @sexp.sexp_body
|
529
|
+
assert_equal s(), s(:x).sexp_body
|
530
|
+
assert_equal s(), s().sexp_body
|
531
|
+
|
532
|
+
assert_instance_of Sexp, s().sexp_body
|
523
533
|
end
|
524
534
|
|
525
535
|
def test_shift
|
526
536
|
skip_if_strict 5
|
527
537
|
|
528
|
-
skip "https://github.com/MagLev/maglev/issues/250" if maglev?
|
529
|
-
|
530
538
|
assert_equal(1, @sexp.shift)
|
531
539
|
assert_equal(2, @sexp.shift)
|
532
540
|
assert_equal(3, @sexp.shift)
|
@@ -585,14 +593,14 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
585
593
|
end
|
586
594
|
|
587
595
|
def test_sub_matcher
|
588
|
-
assert_sub s(:c), s(:b), s{
|
589
|
-
assert_sub s(:a, s(:c), s(:b)), s(:a, s(:b), s(:b)), s{
|
590
|
-
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)
|
591
599
|
|
592
|
-
assert_sub s(:a, :b, :c), s(:a, s(:b, 42), :c), s{
|
593
|
-
assert_sub s(:a, s(:b), :c), s(:a, s(:b), :c), s{
|
594
|
-
assert_sub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{
|
595
|
-
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
|
596
604
|
end
|
597
605
|
|
598
606
|
def test_sub_structure
|
@@ -652,6 +660,18 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
652
660
|
assert_equal DEEP_EXP, act.map { |k, _| k }
|
653
661
|
end
|
654
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
|
+
|
655
675
|
def test_deep_each_skip
|
656
676
|
exp = DEEP_EXP.first(3) + DEEP_EXP.last(4)
|
657
677
|
act = []
|
@@ -662,7 +682,7 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
662
682
|
|
663
683
|
def test_deep_each_without_block
|
664
684
|
assert_kind_of Enumerator, @complex_sexp.deep_each
|
665
|
-
assert_equal DEEP_EXP, @complex_sexp.deep_each.map(&:
|
685
|
+
assert_equal DEEP_EXP, @complex_sexp.deep_each.map(&:sexp_type)
|
666
686
|
end
|
667
687
|
|
668
688
|
def test_unary_not
|
@@ -678,7 +698,7 @@ end # TestSexp
|
|
678
698
|
|
679
699
|
class TestSexpMatcher < SexpTestCase
|
680
700
|
def test_cls_s
|
681
|
-
assert_equal M.
|
701
|
+
assert_equal M.q(:x), s{ q(:x) }
|
682
702
|
end
|
683
703
|
|
684
704
|
def test_cls_underscore
|
@@ -698,19 +718,19 @@ class TestSexpMatcher < SexpTestCase
|
|
698
718
|
end
|
699
719
|
|
700
720
|
def test_cls_any
|
701
|
-
assert_equal M::Any.new(M.
|
721
|
+
assert_equal M::Any.new(M.q(:a), M.q(:b)), s{ any(q(:a), q(:b)) }
|
702
722
|
end
|
703
723
|
|
704
724
|
def test_cls_all
|
705
|
-
assert_equal M::All.new(M.
|
725
|
+
assert_equal M::All.new(M.q(:a), M.q(:b)), s{ all(q(:a), q(:b)) }
|
706
726
|
end
|
707
727
|
|
708
728
|
def test_cls_not_eh
|
709
|
-
assert_equal M::Not.new(M.
|
729
|
+
assert_equal M::Not.new(M.q(:a)), s{ not?(q(:a)) }
|
710
730
|
end
|
711
731
|
|
712
732
|
def test_cls_child
|
713
|
-
assert_equal M::Child.new(M.
|
733
|
+
assert_equal M::Child.new(M.q(:a)), s{ child(q(:a)) }
|
714
734
|
end
|
715
735
|
|
716
736
|
def test_cls_t
|
@@ -718,45 +738,51 @@ class TestSexpMatcher < SexpTestCase
|
|
718
738
|
end
|
719
739
|
|
720
740
|
def test_cls_m
|
721
|
-
assert_equal M::Pattern.new(/a/), s{ m(/a/) }
|
722
|
-
assert_equal M::Pattern.new(/\Aa\Z/), s{ m(:a) }
|
723
|
-
assert_equal M::Pattern.new(/test_\w/), s{ m(/test_\w/) }
|
724
741
|
re = Regexp.union [/\w/, /\d/]
|
725
|
-
|
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
|
726
752
|
end
|
727
753
|
|
728
754
|
def test_amp
|
729
|
-
m = s{
|
730
|
-
e = M::All.new(M.
|
755
|
+
m = s{ q(:a) & q(:b) }
|
756
|
+
e = M::All.new(M.q(:a), M.q(:b))
|
731
757
|
|
732
758
|
assert_equal e, m
|
733
759
|
end
|
734
760
|
|
735
761
|
def test_pipe
|
736
|
-
m = s{
|
737
|
-
e = M::Any.new(M.
|
762
|
+
m = s{ q(:a) | q(:b) }
|
763
|
+
e = M::Any.new(M.q(:a), M.q(:b))
|
738
764
|
|
739
765
|
assert_equal e, m
|
740
766
|
end
|
741
767
|
|
742
768
|
def test_unary_minus
|
743
|
-
assert_equal M::Not.new(M.
|
769
|
+
assert_equal M::Not.new(M.q(:a)), s{ -q(:a) }
|
744
770
|
end
|
745
771
|
|
746
772
|
def test_rchevron
|
747
|
-
assert_equal M::Sibling.new(M.
|
773
|
+
assert_equal M::Sibling.new(M.q(:a), M.q(:b)), s{ q(:a) >> q(:b) }
|
748
774
|
end
|
749
775
|
|
750
776
|
def test_greedy_eh
|
751
|
-
refute_operator s{
|
777
|
+
refute_operator s{ q(:a) }, :greedy?
|
752
778
|
end
|
753
779
|
|
754
780
|
def test_inspect
|
755
|
-
assert_inspect "q(:a)", s{
|
781
|
+
assert_inspect "q(:a)", s{ q(:a) }
|
756
782
|
end
|
757
783
|
|
758
784
|
def test_pretty_print
|
759
|
-
assert_pretty_print "q(:a)", s{
|
785
|
+
assert_pretty_print "q(:a)", s{ q(:a) }
|
760
786
|
end
|
761
787
|
end # class TestSexpMatcher
|
762
788
|
|
@@ -786,11 +812,11 @@ class TestWild < MatcherTestCase
|
|
786
812
|
def test_wild_search # TODO: possibly remove
|
787
813
|
sexp = CLASS_SEXP.dup
|
788
814
|
|
789
|
-
assert_search 1, s(:add, :a, :b), s{
|
790
|
-
assert_search 1, sexp, s{
|
791
|
-
assert_search 2, sexp, s{
|
792
|
-
assert_search 1, s(:a, s()), s{
|
793
|
-
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(_, _, _) }
|
794
820
|
assert_search 7, sexp, s{ _ }
|
795
821
|
end
|
796
822
|
end
|
@@ -811,8 +837,8 @@ class TestRemaining < MatcherTestCase
|
|
811
837
|
def test_remaining_satisfy_eh # TODO: possibly remove
|
812
838
|
assert_satisfy s{ ___ }, s(:a)
|
813
839
|
assert_satisfy s{ ___ }, s(:a, :b, :c)
|
814
|
-
assert_satisfy s{
|
815
|
-
refute_satisfy s{
|
840
|
+
assert_satisfy s{ q(:x, ___ ) }, s(:x, :y)
|
841
|
+
refute_satisfy s{ q(:y, ___ ) }, s(:x, :y)
|
816
842
|
end
|
817
843
|
|
818
844
|
def test_greedy
|
@@ -822,7 +848,7 @@ end
|
|
822
848
|
|
823
849
|
class TestAny < MatcherTestCase
|
824
850
|
def matcher
|
825
|
-
s{
|
851
|
+
s{ q(:a) | q(:c) }
|
826
852
|
end
|
827
853
|
|
828
854
|
def inspect_str
|
@@ -834,26 +860,26 @@ class TestAny < MatcherTestCase
|
|
834
860
|
end
|
835
861
|
|
836
862
|
def test_any_search # TODO: possibly remove
|
837
|
-
assert_search 2, s(:foo, s(:a), s(:b)), s{
|
838
|
-
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)) }
|
839
865
|
end
|
840
866
|
|
841
867
|
def test_or_satisfy_eh # TODO: possibly remove
|
842
|
-
assert_satisfy s{
|
843
|
-
refute_satisfy s{
|
868
|
+
assert_satisfy s{ q(:a) | q(:b) }, s(:a)
|
869
|
+
refute_satisfy s{ q(:a) | q(:b) }, s(:c)
|
844
870
|
end
|
845
871
|
|
846
872
|
def test_or_search # TODO: possibly remove
|
847
873
|
sexp = CLASS_SEXP.dup
|
848
874
|
|
849
|
-
assert_search 2, s(:a, s(:b, :c), s(:b, :d)), s{
|
850
|
-
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, _, _) }
|
851
877
|
end
|
852
878
|
end
|
853
879
|
|
854
880
|
class TestAll < MatcherTestCase
|
855
881
|
def matcher
|
856
|
-
s{
|
882
|
+
s{ q(:a) & q(:a) }
|
857
883
|
end
|
858
884
|
|
859
885
|
def inspect_str
|
@@ -865,14 +891,14 @@ class TestAll < MatcherTestCase
|
|
865
891
|
end
|
866
892
|
|
867
893
|
def test_and_satisfy_eh # TODO: possibly remove
|
868
|
-
refute_satisfy s{
|
869
|
-
assert_satisfy s{
|
894
|
+
refute_satisfy s{ q(:a) & q(:b) }, s(:a)
|
895
|
+
assert_satisfy s{ q(:a) & q(atom) }, s(:a)
|
870
896
|
end
|
871
897
|
end
|
872
898
|
|
873
899
|
class TestNot < MatcherTestCase
|
874
900
|
def matcher
|
875
|
-
s{ not?
|
901
|
+
s{ not? q(:b) } # TODO: test unary minus
|
876
902
|
end
|
877
903
|
|
878
904
|
def inspect_str
|
@@ -885,20 +911,20 @@ class TestNot < MatcherTestCase
|
|
885
911
|
|
886
912
|
def test_not_satisfy_eh # TODO: possibly remove
|
887
913
|
refute_satisfy s{ -_ }, s(:a)
|
888
|
-
assert_satisfy s{ -
|
889
|
-
assert_satisfy s{ not?(
|
890
|
-
refute_satisfy s{ -
|
891
|
-
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)
|
892
918
|
end
|
893
919
|
end
|
894
920
|
|
895
921
|
class TestChild < MatcherTestCase
|
896
922
|
def matcher
|
897
|
-
s{ child(
|
923
|
+
s{ child(q(:a)) }
|
898
924
|
end
|
899
925
|
|
900
926
|
def sexp
|
901
|
-
s(:x, s(:a))
|
927
|
+
s(:x, s(:b), s(:a))
|
902
928
|
end
|
903
929
|
|
904
930
|
def bad_sexp
|
@@ -912,12 +938,14 @@ class TestChild < MatcherTestCase
|
|
912
938
|
def test_child_search # TODO: possibly remove
|
913
939
|
sexp = CLASS_SEXP.dup
|
914
940
|
|
915
|
-
assert_search 1, sexp, s{
|
916
|
-
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))) }
|
917
943
|
end
|
918
944
|
|
919
945
|
def test_satisfy_eh_by_child
|
920
946
|
assert_satisfy matcher, s(:a)
|
947
|
+
assert_satisfy matcher, sexp
|
948
|
+
refute_satisfy matcher, bad_sexp
|
921
949
|
end
|
922
950
|
end
|
923
951
|
|
@@ -950,15 +978,15 @@ class TestAtom < MatcherTestCase
|
|
950
978
|
def test_atom_search # TODO: possibly remove
|
951
979
|
sexp = CLASS_SEXP.dup
|
952
980
|
|
953
|
-
assert_search 1, s(:add, :a, :b), s{
|
954
|
-
assert_search 2, sexp, s{
|
955
|
-
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) }
|
956
984
|
end
|
957
985
|
end
|
958
986
|
|
959
987
|
class TestPattern < MatcherTestCase
|
960
988
|
def matcher
|
961
|
-
s{
|
989
|
+
s{ q(:a, m(/a/)) }
|
962
990
|
end
|
963
991
|
|
964
992
|
def sexp
|
@@ -980,15 +1008,15 @@ class TestPattern < MatcherTestCase
|
|
980
1008
|
def test_pattern_search # TODO: possibly remove
|
981
1009
|
sexp = CLASS_SEXP.dup
|
982
1010
|
|
983
|
-
assert_search 2, sexp, s{
|
1011
|
+
assert_search 2, sexp, s{ q(m(/\w{3}/), :a, :b) }
|
984
1012
|
|
985
1013
|
assert_search 0, s(:a), s{ m(/\w/) }
|
986
|
-
assert_search 1, s(:a), s{
|
1014
|
+
assert_search 1, s(:a), s{ q(m(/\w/)) }
|
987
1015
|
assert_search 0, s(:a), s{ m(/\w/,/\d/) }
|
988
|
-
assert_search 1, s(:a), s{
|
1016
|
+
assert_search 1, s(:a), s{ q(m(/\w/,/\d/)) }
|
989
1017
|
|
990
1018
|
assert_search 0, s(:tests, s(s(:test_a), s(:test_b))), s{ m(/test_\w/) }
|
991
|
-
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/)) }
|
992
1020
|
end
|
993
1021
|
end
|
994
1022
|
|
@@ -1017,7 +1045,7 @@ class TestInclude < MatcherTestCase
|
|
1017
1045
|
end
|
1018
1046
|
|
1019
1047
|
def matcher
|
1020
|
-
s{ include(
|
1048
|
+
s{ include(q(:a)) }
|
1021
1049
|
end
|
1022
1050
|
|
1023
1051
|
def inspect_str
|
@@ -1029,9 +1057,9 @@ class TestInclude < MatcherTestCase
|
|
1029
1057
|
|
1030
1058
|
assert_search 1, s(:add, :a, :b), s{ include(:a) }
|
1031
1059
|
assert_search 1, sexp, s{ include(:bar) }
|
1032
|
-
assert_search 2, sexp, s{
|
1060
|
+
assert_search 2, sexp, s{ q(:defn, atom, _, include(:a)) }
|
1033
1061
|
assert_search 2, sexp, s{ include(:a) }
|
1034
|
-
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)) }
|
1035
1063
|
end
|
1036
1064
|
end
|
1037
1065
|
|
@@ -1041,7 +1069,7 @@ class TestSibling < MatcherTestCase
|
|
1041
1069
|
end
|
1042
1070
|
|
1043
1071
|
def matcher
|
1044
|
-
s{
|
1072
|
+
s{ q(:a) >> q(:b) }
|
1045
1073
|
end
|
1046
1074
|
|
1047
1075
|
def inspect_str
|
@@ -1049,15 +1077,15 @@ class TestSibling < MatcherTestCase
|
|
1049
1077
|
end
|
1050
1078
|
|
1051
1079
|
def test_pretty_print_distance
|
1052
|
-
m = s{ M::Sibling.new(
|
1080
|
+
m = s{ M::Sibling.new(q(:a), q(:b), 3) } # maybe q(:a) << q(:b) << 3 ?
|
1053
1081
|
assert_pretty_print "sibling(q(:a), q(:b), 3)", m
|
1054
1082
|
end
|
1055
1083
|
|
1056
1084
|
def test_sibling_satisfy_eh # TODO: possibly remove
|
1057
|
-
a_a = s{
|
1058
|
-
a_b = s{
|
1059
|
-
a_c = s{
|
1060
|
-
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) }
|
1061
1089
|
|
1062
1090
|
assert_satisfy a_b, s(s(:a), s(:b))
|
1063
1091
|
assert_satisfy a_b, s(s(:a), s(:b), s(:c))
|
@@ -1089,8 +1117,8 @@ class TestMatchCollection < SexpTestCase
|
|
1089
1117
|
s(:defn, :foo, s(:args), s(:add, :a, :b)),
|
1090
1118
|
s(:defn, :bar, s(:args), s(:sub, :a, :b)))
|
1091
1119
|
|
1092
|
-
res = sexp / s{
|
1093
|
-
act = res / s{
|
1120
|
+
res = sexp / s{ q(:class, atom, _, ___) } # sexp / pat => MC
|
1121
|
+
act = res / s{ q(:defn, atom, ___) } # MC / pat => MC
|
1094
1122
|
|
1095
1123
|
_, _, _, defn1, defn2 = sexp
|
1096
1124
|
|
@@ -1146,8 +1174,43 @@ class TestSexpSearch < SexpTestCase
|
|
1146
1174
|
MR.new sexp.deep_clone, hash
|
1147
1175
|
end
|
1148
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
|
+
|
1149
1212
|
def test_slash_simple
|
1150
|
-
act = sexp / s{
|
1213
|
+
act = sexp / s{ q(:class, atom, _, ___) }
|
1151
1214
|
|
1152
1215
|
exp = MC.new
|
1153
1216
|
exp << sexp.deep_clone
|
@@ -1156,7 +1219,7 @@ class TestSexpSearch < SexpTestCase
|
|
1156
1219
|
end
|
1157
1220
|
|
1158
1221
|
def test_slash_subsexp
|
1159
|
-
act = sexp / s{
|
1222
|
+
act = sexp / s{ q(:defn, atom, ___) }
|
1160
1223
|
|
1161
1224
|
exp = MC.new
|
1162
1225
|
exp << s(:defn, :foo, s(:args), s(:add, :a, :b))
|
@@ -1166,7 +1229,7 @@ class TestSexpSearch < SexpTestCase
|
|
1166
1229
|
end
|
1167
1230
|
|
1168
1231
|
def test_slash_data
|
1169
|
-
pat = s{
|
1232
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1170
1233
|
|
1171
1234
|
_, _, (_klass, _, _, _setup, t1, t2, t3) = TestUseCase.sexp.deep_clone
|
1172
1235
|
exp = [t1, t2, t3]
|
@@ -1195,27 +1258,27 @@ class TestSexpSearch < SexpTestCase
|
|
1195
1258
|
assert_search 0, sexp, :class # non-pattern should raise
|
1196
1259
|
end
|
1197
1260
|
|
1198
|
-
assert_search 0, sexp, s{
|
1199
|
-
assert_search 1, sexp, s{
|
1200
|
-
assert_search 1, s(:a, s(:b, s(:c))), s{
|
1201
|
-
assert_search 0, s(:a, s(:b, s(:c))), s{
|
1202
|
-
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)) }
|
1203
1266
|
end
|
1204
1267
|
|
1205
1268
|
def test_satisfy_eh_any_capture # TODO: remove
|
1206
1269
|
sexp = s(:add, :a, :b)
|
1207
|
-
assert_satisfy s{ any(
|
1270
|
+
assert_satisfy s{ any(q(:add, :a, :b), q(:sub, :a, :b)) }, sexp
|
1208
1271
|
|
1209
|
-
assert_satisfy s{ any(
|
1272
|
+
assert_satisfy s{ any(q(atom, :a, :b), q(:sub, :a, :b)) }, sexp
|
1210
1273
|
end
|
1211
1274
|
|
1212
1275
|
def test_satisfy_eh_all_capture # TODO: remove
|
1213
1276
|
sexp = s(:add, :a, :b)
|
1214
|
-
assert_satisfy s{ all(
|
1277
|
+
assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
|
1215
1278
|
|
1216
|
-
assert_satisfy s{ all(
|
1279
|
+
assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
|
1217
1280
|
|
1218
|
-
assert_search 1, sexp, s{ all(
|
1281
|
+
assert_search 1, sexp, s{ all(q(_, :a, :b), q(atom, :a, :b)) }
|
1219
1282
|
end
|
1220
1283
|
end
|
1221
1284
|
|
@@ -1224,15 +1287,15 @@ class TestSexpPath < Minitest::Test
|
|
1224
1287
|
sexp = s(:a, :b, :c) # s called outside block
|
1225
1288
|
|
1226
1289
|
assert_instance_of Sexp, s{ sexp.deep_clone }
|
1227
|
-
assert_instance_of Sexp::Matcher, s{
|
1228
|
-
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) }
|
1229
1292
|
end
|
1230
1293
|
end
|
1231
1294
|
|
1232
1295
|
class TestSexpReplaceSexp < SexpTestCase
|
1233
1296
|
def test_replace_sexp
|
1234
1297
|
sexp = s(:a, s(:b), :c)
|
1235
|
-
actual = sexp.replace_sexp(s{
|
1298
|
+
actual = sexp.replace_sexp(s{ q(:b) }) { :b }
|
1236
1299
|
|
1237
1300
|
assert_equal s(:a, :b, :c), actual
|
1238
1301
|
end
|
@@ -1305,7 +1368,7 @@ class TestUseCase < SexpTestCase
|
|
1305
1368
|
end
|
1306
1369
|
|
1307
1370
|
def test_finding_classes_and_methods
|
1308
|
-
res = @sexp / s{
|
1371
|
+
res = @sexp / s{ q(:class, atom, ___ ) }
|
1309
1372
|
|
1310
1373
|
_klass, name, * = res.first
|
1311
1374
|
|
@@ -1317,7 +1380,7 @@ class TestUseCase < SexpTestCase
|
|
1317
1380
|
end
|
1318
1381
|
|
1319
1382
|
def test_finding_empty_test_methods
|
1320
|
-
empty_test = s{
|
1383
|
+
empty_test = s{ q(:defn, m(/^test_.+/), q(:args), q(:nil)) }
|
1321
1384
|
res = @sexp / empty_test
|
1322
1385
|
|
1323
1386
|
_, _, (_klass, _, _, _setup, _t1, t2, _t3) = TestUseCase.sexp.deep_clone
|
@@ -1326,7 +1389,7 @@ class TestUseCase < SexpTestCase
|
|
1326
1389
|
end
|
1327
1390
|
|
1328
1391
|
def test_search_each_finding_duplicate_test_names
|
1329
|
-
pat = s{
|
1392
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1330
1393
|
counts = Hash.new { |h, k| h[k] = 0 }
|
1331
1394
|
|
1332
1395
|
@sexp.search_each pat do |x|
|
@@ -1339,7 +1402,7 @@ class TestUseCase < SexpTestCase
|
|
1339
1402
|
end
|
1340
1403
|
|
1341
1404
|
def test_finding_duplicate_test_names_via_res
|
1342
|
-
pat = s{
|
1405
|
+
pat = s{ q(:defn, m(/^test_.+/), ___ ) }
|
1343
1406
|
res = @sexp / pat
|
1344
1407
|
counts = Hash.new { |h, k| h[k] = 0 }
|
1345
1408
|
|
@@ -1358,8 +1421,8 @@ class TestUseCase < SexpTestCase
|
|
1358
1421
|
end
|
1359
1422
|
|
1360
1423
|
def test_rewriting_colon2s
|
1361
|
-
colon2 = s{
|
1362
|
-
expected = s{
|
1424
|
+
colon2 = s{ q(:colon2, q(:const, atom), atom) }
|
1425
|
+
expected = s{ q(:const, "Minitest::Test") }
|
1363
1426
|
|
1364
1427
|
new_sexp = @sexp.replace_sexp(colon2) { |r|
|
1365
1428
|
(_, (_, a), b) = r
|
@@ -1384,46 +1447,46 @@ class TestSexpMatchers < SexpTestCase
|
|
1384
1447
|
SEXP = s(:class, :X, nil, s(:defn, :x, s(:args)))
|
1385
1448
|
|
1386
1449
|
def test_match_subset
|
1387
|
-
assert_match s{ child(
|
1388
|
-
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)
|
1389
1452
|
end
|
1390
1453
|
|
1391
1454
|
def test_match_simple
|
1392
|
-
assert_match s{
|
1455
|
+
assert_match s{ q(:lit, _) }, s(:lit, 42)
|
1393
1456
|
end
|
1394
1457
|
|
1395
1458
|
def test_match_mismatch_type
|
1396
|
-
refute_match s{
|
1459
|
+
refute_match s{ q(:xxx, 42) }, s(:lit, 42)
|
1397
1460
|
end
|
1398
1461
|
|
1399
1462
|
def test_match_mismatch_data
|
1400
|
-
refute_match s{
|
1463
|
+
refute_match s{ q(:lit, 24) }, s(:lit, 42)
|
1401
1464
|
end
|
1402
1465
|
|
1403
1466
|
def test_match_mismatch_length_shorter
|
1404
|
-
refute_match s{
|
1467
|
+
refute_match s{ q(:a, :b) }, s(:a, :b, :c)
|
1405
1468
|
end
|
1406
1469
|
|
1407
1470
|
def test_match_mismatch_length_longer
|
1408
|
-
refute_match s{
|
1471
|
+
refute_match s{ q(:a, :b, :c) }, s(:a, :b)
|
1409
1472
|
end
|
1410
1473
|
|
1411
1474
|
def test_match_wild
|
1412
|
-
assert_match s{
|
1475
|
+
assert_match s{ q(:class, _, _, _) }, SEXP
|
1413
1476
|
end
|
1414
1477
|
|
1415
1478
|
def test_match_rest_same_length
|
1416
|
-
assert_match s{
|
1479
|
+
assert_match s{ q(:class, _, _, ___) }, SEXP
|
1417
1480
|
end
|
1418
1481
|
|
1419
1482
|
def test_match_rest_diff_length
|
1420
1483
|
skip_if_strict
|
1421
1484
|
|
1422
|
-
assert_match s{
|
1485
|
+
assert_match s{ q(:class, ___) }, SEXP
|
1423
1486
|
end
|
1424
1487
|
|
1425
1488
|
def test_match_reversed
|
1426
|
-
assert_match SEXP, s{
|
1489
|
+
assert_match SEXP, s{ q(:class, _, _, ___) }
|
1427
1490
|
end
|
1428
1491
|
|
1429
1492
|
def assert_match_case pat, data
|
@@ -1436,7 +1499,7 @@ class TestSexpMatchers < SexpTestCase
|
|
1436
1499
|
end
|
1437
1500
|
|
1438
1501
|
def test_match_case
|
1439
|
-
assert_match_case s{
|
1502
|
+
assert_match_case s{ q(:class, _, _, ___) }, SEXP
|
1440
1503
|
end
|
1441
1504
|
|
1442
1505
|
# NOTE: eqt is =~ (equal-tilde)
|
@@ -1494,12 +1557,12 @@ class TestSexpMatchers < SexpTestCase
|
|
1494
1557
|
l_cls = s(:class, :X, nil,
|
1495
1558
|
s(:something_in_between),
|
1496
1559
|
s(:cdecl, :Y, s(:hash, s(:lit, :a), s(:lit, 1))))
|
1497
|
-
p_cls1 = s{
|
1498
|
-
p_cls2 = s{
|
1560
|
+
p_cls1 = s{ q(:class, ___) & include(q(:cdecl, _, q(:hash, ___))) }
|
1561
|
+
p_cls2 = s{ q(:class, _, _, q(:cdecl, _, q(:hash, ___))) }
|
1499
1562
|
|
1500
1563
|
x, o = true, false
|
1501
|
-
TestMatcherDirectMatch = cmt x, x, o, x, l_a, s{
|
1502
|
-
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) }
|
1503
1566
|
TestMatcherSubtreeType = cmt x, x, o, x, l_abc, s{ t(:c) }
|
1504
1567
|
TestMatcherDisparateSubtree = cmt x, x, o, x, l_cls, p_cls1
|
1505
1568
|
TestMatcherDisparateSubtree2 = cmt o, o, o, o, l_cls, p_cls2 # TODO: make pass
|
@@ -1535,18 +1598,34 @@ class TestSexpMatcherParser < Minitest::Test
|
|
1535
1598
|
lambda { s(&b) }
|
1536
1599
|
end
|
1537
1600
|
|
1601
|
+
re = /(?-mix:\Aa\Z)|(?-mix:\Ab\Z)|(?-mix:\Ac\Z)/ # [m a b c]
|
1602
|
+
|
1538
1603
|
test_parse "nothing", nil, ""
|
1539
1604
|
test_parse "nil", delay{ nil }, "nil"
|
1540
|
-
test_parse "empty", delay{
|
1541
|
-
test_parse "simple", delay{
|
1542
|
-
test_parse "number", delay{
|
1543
|
-
test_parse "string", delay{
|
1544
|
-
test_parse "compound", delay{
|
1545
|
-
test_parse "complex", delay{
|
1546
|
-
test_parse "type", delay{
|
1547
|
-
test_parse "match", delay{
|
1548
|
-
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)"
|
1549
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)"
|
1550
1629
|
|
1551
1630
|
test_bad_parse "open_sexp", "(a"
|
1552
1631
|
test_bad_parse "closed_sexp", "a)"
|