Class: TestRunner::Cli::FilterExpression
- Inherits:
-
Object
- Object
- TestRunner::Cli::FilterExpression
- Defined in:
- lib/test-runner/cli/filter_expression.rb
Instance Attribute Summary collapse
-
#source ⇒ Object
readonly
protected
Returns the value of attribute source.
Instance Method Summary collapse
- #accept(type) ⇒ Object protected
- #and_expr(left, right) ⇒ Object protected
- #error(message) ⇒ Object protected
- #expect(type) ⇒ Object protected
-
#initialize(str_filter) ⇒ FilterExpression
constructor
A new instance of FilterExpression.
- #or_expr(left, right) ⇒ Object protected
- #parse_and ⇒ Object protected
- #parse_comparison ⇒ Object protected
- #parse_factor ⇒ Object protected
- #parse_or ⇒ Object protected
- #pass?(test_script) ⇒ Boolean
- #peek ⇒ Object protected
- #tokenize(str) ⇒ Object protected
Constructor Details
#initialize(str_filter) ⇒ FilterExpression
Returns a new instance of FilterExpression.
5 6 7 8 9 10 11 12 13 14 |
# File 'lib/test-runner/cli/filter_expression.rb', line 5 def initialize(str_filter) @source = str_filter.to_s @tokens = tokenize(@source) @pos = 0 error('empty expression') if @tokens.empty? @expr = parse_or error("unexpected token #{peek[1].inspect}") if peek end |
Instance Attribute Details
#source ⇒ Object (readonly, protected)
Returns the value of attribute source.
23 24 25 |
# File 'lib/test-runner/cli/filter_expression.rb', line 23 def source @source end |
Instance Method Details
#accept(type) ⇒ Object (protected)
124 125 126 127 128 129 130 |
# File 'lib/test-runner/cli/filter_expression.rb', line 124 def accept(type) token = peek return unless token && token[0] == type @pos += 1 token end |
#and_expr(left, right) ⇒ Object (protected)
120 121 122 |
# File 'lib/test-runner/cli/filter_expression.rb', line 120 def and_expr(left, right) proc { |test_script| left.call(test_script) && right.call(test_script) } end |
#error(message) ⇒ Object (protected)
148 149 150 |
# File 'lib/test-runner/cli/filter_expression.rb', line 148 def error() raise GLI::BadCommandLine, "Invalid filter expression #{source.inspect}: #{}" end |
#expect(type) ⇒ Object (protected)
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/test-runner/cli/filter_expression.rb', line 132 def expect(type) token = accept(type) return token if token expected = { word: 'identifier', rparen: ')' }.fetch(type, type.to_s) error("expected #{expected}") end |
#or_expr(left, right) ⇒ Object (protected)
116 117 118 |
# File 'lib/test-runner/cli/filter_expression.rb', line 116 def or_expr(left, right) proc { |test_script| left.call(test_script) || right.call(test_script) } end |
#parse_and ⇒ Object (protected)
77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/test-runner/cli/filter_expression.rb', line 77 def parse_and expr = parse_factor while accept(:and) left = expr right = parse_factor expr = and_expr(left, right) end expr end |
#parse_comparison ⇒ Object (protected)
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/test-runner/cli/filter_expression.rb', line 99 def parse_comparison key = expect(:word)[1] op = accept(:eq) || accept(:neq) error('expected = or !=') unless op value = expect(:word)[1] proc do |test_script| if key == 'tag' test_script..include?(value) == (op[0] == :eq) elsif op[0] == :eq test_script.labels[key].to_s == value else test_script.labels[key].to_s != value end end end |
#parse_factor ⇒ Object (protected)
89 90 91 92 93 94 95 96 97 |
# File 'lib/test-runner/cli/filter_expression.rb', line 89 def parse_factor if accept(:lparen) expr = parse_or expect(:rparen) expr else parse_comparison end end |
#parse_or ⇒ Object (protected)
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/test-runner/cli/filter_expression.rb', line 65 def parse_or expr = parse_and while accept(:or) left = expr right = parse_and expr = or_expr(left, right) end expr end |
#pass?(test_script) ⇒ Boolean
17 18 19 |
# File 'lib/test-runner/cli/filter_expression.rb', line 17 def pass?(test_script) @expr.call(test_script) end |
#peek ⇒ Object (protected)
144 145 146 |
# File 'lib/test-runner/cli/filter_expression.rb', line 144 def peek @tokens[@pos] end |
#tokenize(str) ⇒ Object (protected)
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 |
# File 'lib/test-runner/cli/filter_expression.rb', line 25 def tokenize(str) tokens = [] i = 0 while i < str.length c = str[i] if c.match?(/\s/) i += 1 elsif str[i, 2] == '&&' tokens << [:and, '&&'] i += 2 elsif str[i, 2] == '||' tokens << [:or, '||'] i += 2 elsif str[i, 2] == '!=' tokens << [:neq, '!='] i += 2 elsif c == '=' tokens << [:eq, '='] i += 1 elsif c == '(' tokens << [:lparen, '('] i += 1 elsif c == ')' tokens << [:rparen, ')'] i += 1 elsif ['&', '|', '!'].include?(c) error("unexpected token #{c.inspect}") else j = i j += 1 while j < str.length && str[j] !~ /[\s()&|!=]/ tokens << [:word, str[i...j]] i = j end end tokens end |