Commit b8804d2

mo khan <mo.khan@gmail.com>
2020-01-21 16:44:14
Add AST abstraction to traverse tree
1 parent d772749
Changed files (2)
lib
scim
spec
scim
lib/scim/kit/v2/filter.rb
@@ -125,6 +125,56 @@ module Scim
         rule(:underscore) { str('_') }
         rule(:version) { digit >> dot >> digit }
         rule(:assign) { str('=') }
+
+        class Node
+          def initialize(hash)
+            @hash = hash
+          end
+
+          def operator
+            self[:operator].to_sym
+          end
+
+          def attribute
+            self[:attribute].to_s
+          end
+
+          def value
+            self[:value].to_s[1..-2]
+          end
+
+          def not?
+            @hash.key?(:not)
+          end
+
+          def accept(visitor)
+            visitor.visit(self)
+          end
+
+          def left
+            self.class.new(self[:left])
+          end
+
+          def right
+            self.class.new(self[:right])
+          end
+
+          def inspect
+            @hash.inspect
+          end
+
+          private
+
+          def [](key)
+            @hash[key]
+          end
+        end
+
+        class << self
+          def parse(filter)
+            Node.new(new.parse(filter))
+          end
+        end
       end
     end
   end
spec/scim/kit/v2/filter_spec.rb
@@ -171,4 +171,35 @@ RSpec.describe Scim::Kit::V2::Filter do
   specify { expect(subject.colon).to parse(':') }
   specify { expect(subject.version).to parse('2.0') }
   specify { expect(subject.version).to parse('1.0') }
+
+  describe ".parse" do
+    subject { described_class }
+
+    [
+      %(meta.lastModified ge "2011-05-13T04:42:34Z"),
+      %(meta.lastModified gt "2011-05-13T04:42:34Z"),
+      %(meta.lastModified le "2011-05-13T04:42:34Z"),
+      %(meta.lastModified lt "2011-05-13T04:42:34Z"),
+      %(name.familyName co "O'Malley"),
+      %(schemas eq "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"),
+      %(title pr and userType eq "Employee"),
+      %(title pr or userType eq "Intern"),
+      %(title pr),
+      %(urn:ietf:params:scim:schemas:core:2.0:User:userName sw "J"),
+      %(userName eq "bjensen"),
+      %(userName sw "J"),
+      %(userType eq "Employee" and (emails co "example.com" or emails.value co "example.org")),
+      %(userType eq "Employee" and (emails.type eq "work")),
+      %(userType ne "Employee" and not (emails co "example.com" or emails.value co "example.org")),
+      '(emails[(type eq "work") and (value co "@example.com")]) or (ims[(type eq "xmpp") and (value co "@foo.com")])',
+      '(title pr) and (userType eq "Employee")',
+      '(title pr) or (userType eq "Intern")',
+      '(userType eq "Employee") and (emails.type eq "work")',
+      '(userType eq "Employee") and (emails[(type eq "work") and (value co "@example.com")])',
+      'title pr',
+      'userName pr and not (userName eq "hello@example.com")'
+    ].each do |filter|
+      specify { expect(subject.parse(filter)).to be_instance_of(Scim::Kit::V2::Filter::Node) }
+    end
+  end
 end