File: tests.rb

package info (click to toggle)
ruby-regexp-parser 2.11.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,092 kB
  • sloc: ruby: 6,891; makefile: 6; sh: 3
file content (145 lines) | stat: -rw-r--r-- 5,052 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# frozen_string_literal: true

module Regexp::Expression
  module Shared

    # Test if this expression has the given test_type, which can be either
    # a symbol or an array of symbols to check against the expression's type.
    #
    #   # is it a :group expression
    #   exp.type? :group
    #
    #   # is it a :set, or :meta
    #   exp.type? [:set, :meta]
    #
    def type?(test_type)
      test_types = Array(test_type).map(&:to_sym)
      test_types.include?(:*) || test_types.include?(type)
    end

    # Test if this expression has the given test_token, and optionally a given
    # test_type.
    #
    #   # Any expressions
    #   exp.is? :*  # always returns true
    #
    #   # is it a :capture
    #   exp.is? :capture
    #
    #   # is it a :character and a :set
    #   exp.is? :character, :set
    #
    #   # is it a :meta :dot
    #   exp.is? :dot, :meta
    #
    #   # is it a :meta or :escape :dot
    #   exp.is? :dot, [:meta, :escape]
    #
    def is?(test_token, test_type = nil)
      return true if test_token === :*
      token == test_token and (test_type ? type?(test_type) : true)
    end

    # Test if this expression matches an entry in the given scope spec.
    #
    # A scope spec can be one of:
    #
    #   . An array: Interpreted as a set of tokens, tested for inclusion
    #               of the expression's token.
    #
    #   . A hash:   Where the key is interpreted as the expression type
    #               and the value is either a symbol or an array. In this
    #               case, when the scope is a hash, one_of? calls itself to
    #               evaluate the key's value.
    #
    #   . A symbol: matches the expression's token or type, depending on
    #               the level of the call. If one_of? is called directly with
    #               a symbol then it will always be checked against the
    #               type of the expression. If it's being called for a value
    #               from a hash, it will be checked against the token of the
    #               expression.
    #
    #   # any expression
    #   exp.one_of?(:*) # always true
    #
    #   # like exp.type?(:group)
    #   exp.one_of?(:group)
    #
    #   # any expression of type meta
    #   exp.one_of?(:meta => :*)
    #
    #   # meta dots and alternations
    #   exp.one_of?(:meta => [:dot, :alternation])
    #
    #   # meta dots and any set tokens
    #   exp.one_of?({meta: [:dot], set: :*})
    #
    def one_of?(scope, top = true)
      case scope
      when Array
        scope.include?(:*) || scope.include?(token)

      when Hash
        if scope.has_key?(:*)
          test_type = scope.has_key?(type) ? type : :*
          one_of?(scope[test_type], false)
        else
          scope.has_key?(type) && one_of?(scope[type], false)
        end

      when Symbol
        scope.equal?(:*) || (top ? type?(scope) : is?(scope))

      else
        raise ArgumentError,
              "Array, Hash, or Symbol expected, #{scope.class.name} given"
      end
    end

    # Deep-compare two expressions for equality.
    #
    # When changing the conditions, please make sure to update
    # #pretty_print_instance_variables so that it includes all relevant values.
    def ==(other)
      self.class   == other.class &&
        text       == other.text &&
        quantifier == other.quantifier &&
        options    == other.options &&
        (terminal? || expressions == other.expressions)
    end
    alias :=== :==
    alias :eql? :==

    def optional?
      quantified? && quantifier.min == 0
    end

    def quantified?
      !quantifier.nil?
    end
  end

  Shared.class_eval                     { def terminal?; self.class.terminal? end }
  Shared::ClassMethods.class_eval       { def terminal?; true  end }
  Subexpression.instance_eval           { def terminal?; false end }

  Shared.class_eval                     { def capturing?; self.class.capturing? end }
  Shared::ClassMethods.class_eval       { def capturing?; false end }
  Group::Capture.instance_eval          { def capturing?; true  end }

  Shared.class_eval                     { def comment?; self.class.comment? end }
  Shared::ClassMethods.class_eval       { def comment?; false end }
  Comment.instance_eval                 { def comment?; true  end }
  Group::Comment.instance_eval          { def comment?; true  end }

  Shared.class_eval                     { def decorative?; self.class.decorative? end }
  Shared::ClassMethods.class_eval       { def decorative?; false end }
  FreeSpace.instance_eval               { def decorative?; true  end }
  Group::Comment.instance_eval          { def decorative?; true  end }

  Shared.class_eval                     { def referential?; self.class.referential? end }
  Shared::ClassMethods.class_eval       { def referential?; false end }
  Backreference::Base.instance_eval     { def referential?; true  end }
  Conditional::Condition.instance_eval  { def referential?; true  end }
  Conditional::Expression.instance_eval { def referential?; true  end }
end