sexp_processor 4.11.0 → 4.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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{s(:a)}, s(s(:a), s(:b)) # left - =~
237
- assert_equal3 s{s(:a)}, s(s(:a), s(:b)) # left - ===
238
- assert_equal3 s{s(:a)}, s(:blah, s(:a ), s(:b)) # mid 1
239
- assert_equal3 s{s(:a, 1)}, s(:blah, s(:a, 1), s(:b)) # mid 2
240
- assert_equal3 s{s(:a)}, s(:blah, s(:blah, s(:a))) # left deeper
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{ s(:b) }, s(:a, s(:b), :c)
245
- assert_match s(:a, s(:b), :c), s{ s(:b) }
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{ s(:re) } =~ s(:data) # pattern on LHS
260
- s(:data) =~ s{ s(:re) } # pattern on RHS
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{ s(:b, _) }, :b
301
- assert_gsub s(:a, s(:b), :c), s(:a, s(:b), :c), s{ s(:b, _) }, :b
302
- assert_gsub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{ s(:b, _) }, :b
303
- assert_gsub s(:a, s(:q), :c), s(:a, s(:q), :c), s{ s(:b, _) }, :b
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 [2, 3], @sexp.sexp_body
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{ s(:b) }, s(:c)
589
- assert_sub s(:a, s(:c), s(:b)), s(:a, s(:b), s(:b)), s{ s(:b) }, s(:c)
590
- assert_sub s(:a, s(:c), s(:a)), s(:a, s(:b), s(:a)), s{ s(:b) }, s(:c)
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{ s(:b, _) }, :b
593
- assert_sub s(:a, s(:b), :c), s(:a, s(:b), :c), s{ s(:b, _) }, :b
594
- assert_sub s(:a, s(:c, :b), :d), s(:a, s(:c, s(:b, 42)), :d), s{ s(:b, _) }, :b
595
- assert_sub s(:a, s(:q), :c), s(:a, s(:q), :c), s{ s(:b, _) }, :b
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(&:first)
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.s(:x), s{ s(:x) }
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.s(:a), M.s(:b)), s{ any(s(:a), s(:b)) }
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.s(:a), M.s(:b)), s{ all(s(:a), s(:b)) }
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.s(:a)), s{ not?(s(:a)) }
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.s(:a)), s{ child(s(:a)) }
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
- assert_equal M::Pattern.new(re), s{ m(/\w/,/\d/) }
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{ s(:a) & s(:b) }
730
- e = M::All.new(M.s(:a), M.s(:b))
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{ s(:a) | s(:b) }
737
- e = M::Any.new(M.s(:a), M.s(:b))
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.s(:a)), s{ -s(:a) }
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.s(:a), M.s(:b)), s{ s(:a) >> s(:b) }
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{ s(:a) }, :greedy?
777
+ refute_operator s{ q(:a) }, :greedy?
752
778
  end
753
779
 
754
780
  def test_inspect
755
- assert_inspect "q(:a)", s{ s(:a) }
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{ s(:a) }
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{ s(:add, _, :b) }
790
- assert_search 1, sexp, s{ s(:defn, :bar, _, _) }
791
- assert_search 2, sexp, s{ s(:defn, _, _, s(_, :a, :b) ) }
792
- assert_search 1, s(:a, s()), s{ s(:a, _) }
793
- assert_search 1, s(:a, :b, :c), s{ 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{ s(:x, ___ ) }, s(:x, :y)
815
- refute_satisfy s{ s(:y, ___ ) }, s(:x, :y)
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{ s(:a) | s(:c) }
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{ s(any(:a, :b)) }
838
- assert_search 1, s(:foo, s(:a), s(:b)), s{ any( s(:a), s(:c)) }
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{ s(:a) | s(:b) }, s(:a)
843
- refute_satisfy s{ s(:a) | s(:b) }, s(:c)
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{ s(:b, :c) | s(:b, :d) }
850
- assert_search 2, sexp, s{ s(:add, :a, :b) | s(:defn, :bar, _, _) }
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{ s(:a) & s(:a) }
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{ s(:a) & s(:b) }, s(:a)
869
- assert_satisfy s{ s(:a) & s(atom) }, s(:a)
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? s(:b) } # TODO: test unary minus
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{ -s(:b) }, s(:a)
889
- assert_satisfy s{ not?(s(:b)) }, s(:a)
890
- refute_satisfy s{ -s(atom) }, s(:a)
891
- assert_satisfy s{ s(not?(:b)) }, s(:a)
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(s(:a)) }
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{ s(:class, :cake, _, _, child( s(:sub, :a, :b) ) ) }
916
- assert_search 1, sexp, s{ s(:class, :cake, _, _, child(include(:a))) }
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{ s(:add, atom, :b) }
954
- assert_search 2, sexp, s{ s(:defn, atom, _, s(atom, :a, :b) ) }
955
- assert_search 0, s(:a, s()), s{ s(:a, atom) }
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{ s(:a, m(/a/)) }
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{ s(m(/\w{3}/), :a, :b) }
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{ s(m(/\w/)) }
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{ s(m(/\w/,/\d/)) }
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{ s(m(/test_\w/)) }
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(s(:a)) }
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{ s(:defn, atom, _, include(:a)) }
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{ s(:a, include(:c)) }
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{ s(:a) >> s(:b) }
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(s(:a), s(:b), 3) } # maybe s(:a) << s(:b) << 3 ?
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{ s(:a) >> s(:a) }
1058
- a_b = s{ s(:a) >> s(:b) }
1059
- a_c = s{ s(:a) >> s(:c) }
1060
- c_a = s{ s(:c) >> s(:a) }
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{ s(:class, atom, _, ___) } # sexp / pat => MC
1093
- act = res / s{ s(:defn, atom, ___) } # MC / pat => MC
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{ s(:class, atom, _, ___) }
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{ s(:defn, atom, ___) }
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{ s(:defn, m(/^test_.+/), ___ ) }
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{ s(:class) }
1199
- assert_search 1, sexp, s{ s(:add, :a, :b) }
1200
- assert_search 1, s(:a, s(:b, s(:c))), s{ s(:b, s(:c)) }
1201
- assert_search 0, s(:a, s(:b, s(:c))), s{ s(:a, s(:c)) }
1202
- assert_search 1, sexp, s{ s(:defn, :bar, _, s(:sub, :a, :b)) }
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(s(:add, :a, :b), s(:sub, :a, :b)) }, sexp
1270
+ assert_satisfy s{ any(q(:add, :a, :b), q(:sub, :a, :b)) }, sexp
1208
1271
 
1209
- assert_satisfy s{ any(s(atom, :a, :b), s(:sub, :a, :b)) }, sexp
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(s(_, :a, :b), s(atom, :a, :b)) }, sexp
1277
+ assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
1215
1278
 
1216
- assert_satisfy s{ all(s(_, :a, :b), s(atom, :a, :b)) }, sexp
1279
+ assert_satisfy s{ all(q(_, :a, :b), q(atom, :a, :b)) }, sexp
1217
1280
 
1218
- assert_search 1, sexp, s{ all(s(_, :a, :b), s(atom, :a, :b)) }
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{ s(:a, :b, :c) }
1228
- assert_instance_of Sexp::Matcher, s{ s(:a, atom, :c) }
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{ s(:b) }) { :b }
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{ s(:class, atom, ___ ) }
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{ s(:defn, m(/^test_.+/), s(:args), s(:nil)) }
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{ s(:defn, m(/^test_.+/), ___ ) }
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{ s(:defn, m(/^test_.+/), ___ ) }
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{ s(:colon2, s(:const, atom), atom) }
1362
- expected = s{ s(:const, "Minitest::Test") }
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(s(:a)) }, s(:blah, s(:blah, s(:a)))
1388
- assert_match s{ child(s(:a)) }, s(:a)
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{ s(:lit, _) }, s(:lit, 42)
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{ s(:xxx, 42) }, s(:lit, 42)
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{ s(:lit, 24) }, s(:lit, 42)
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{ s(:a, :b) }, s(:a, :b, :c)
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{ s(:a, :b, :c) }, s(:a, :b)
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{ s(:class, _, _, _) }, SEXP
1475
+ assert_match s{ q(:class, _, _, _) }, SEXP
1413
1476
  end
1414
1477
 
1415
1478
  def test_match_rest_same_length
1416
- assert_match s{ s(:class, _, _, ___) }, SEXP
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{ s(:class, ___) }, SEXP
1485
+ assert_match s{ q(:class, ___) }, SEXP
1423
1486
  end
1424
1487
 
1425
1488
  def test_match_reversed
1426
- assert_match SEXP, s{ s(:class, _, _, ___) }
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{ s(:class, _, _, ___) }, SEXP
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{ s(:class, ___) & include(s(:cdecl, _, s(:hash, ___))) }
1498
- p_cls2 = s{ s(:class, _, _, s(:cdecl, _, s(:hash, ___))) }
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{ s(:a) }
1502
- TestMatcherSubtree = cmt x, x, o, x, l_abc, s{ s(:c) }
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{ s() }, "()"
1541
- test_parse "simple", delay{ s(:a) }, "(a)"
1542
- test_parse "number", delay{ s(:a, 42) }, "(a 42)"
1543
- test_parse "string", delay{ s(:a, "s") }, "(a \"s\")"
1544
- test_parse "compound", delay{ s(:b) }, "(a) (b)"
1545
- test_parse "complex", delay{ s(:a, _, s(:b, :cde), ___) }, "(a _ (b cde) ___)"
1546
- test_parse "type", delay{ s(:a, t(:b)) }, "(a [t b])"
1547
- test_parse "match", delay{ s(:a, m(/b/)) }, "(a [m /b/])"
1548
- test_parse "not_atom", delay{ s(:atom) }, "(atom)"
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)"