Commit 310c6d4
Changed files (2)
lib
scim
kit
v2
spec
scim
kit
lib/scim/kit/v2/filter.rb
@@ -11,27 +11,31 @@ module Scim
# FILTER = attrExp / logExp / valuePath / assignVariable / *1"not" "(" FILTER ")"
rule(:filter) do
- attribute_expression | logical_expression | value_path | assign_variable | not_op >> lparen >> filter >> rparen
+ logical_expression | filter_atom
+ end
+
+ rule(:filter_atom) do
+ (not_op? >> lparen >> filter >> rparen) | attribute_expression | value_path
end
# valuePath = attrPath "[" valFilter "]" ; FILTER uses sub-attributes of a parent attrPath
rule(:value_path) do
- attribute_path.as(:attribute) >> lbracket >> value_filter >> rbracket
+ attribute_path >> lbracket >> value_filter >> rbracket
end
# valFilter = attrExp / logExp / *1"not" "(" valFilter ")"
rule(:value_filter) do
- attribute_expression | logical_expression | not_op >> lparen >> value_filter >> rparen
+ attribute_expression | logical_expression | not_op? >> lparen >> value_filter >> rparen
end
# attrExp = (attrPath SP "pr") / (attrPath SP compareOp SP compValue)
rule(:attribute_expression) do
- (attribute_path.as(:attribute) >> space >> presence) | attribute_path.as(:attribute) >> space >> comparison_operator.as(:comparison_operator) >> space >> comparison_value.as(:comparison_value)
+ (attribute_path >> space >> presence) | (attribute_path >> space >> comparison_operator.as(:comparison_operator) >> space >> comparison_value.as(:comparison_value))
end
# logExp = FILTER SP ("and" / "or") SP FILTER
rule(:logical_expression) do
- lparen >> filter >> rparen >> space >> (and_op | or_op) >> space >> lparen >> filter >> rparen
+ filter_atom >> space >> (and_op | or_op).as(:logical_operator) >> space >> filter
end
# compValue = false / null / true / number / string ; rules from JSON (RFC 7159)
@@ -47,7 +51,7 @@ module Scim
# attrPath = [URI ":"] ATTRNAME *1subAttr ; SCIM attribute name ; URI is SCIM "schema" URI
rule(:attribute_path) do
- (uri >> colon).repeat(0, 1) >> attribute_name >> sub_attribute.repeat(0, 1)
+ ((uri >> colon).repeat(0, 1) >> attribute_name >> sub_attribute.repeat(0, 1)).as(:attribute)
end
# ATTRNAME = ALPHA *(nameChar)
@@ -78,18 +82,13 @@ module Scim
)
end
- # assignVariable = ATTRNAME '=' *(NAMECHAR) | STRING
- rule(:assign_variable) do
- attribute_name >> space >> assign >> space >> (name_character.repeat(1, nil) | string)
- end
-
rule(:presence) { str('pr').as(:presence) }
- rule(:and_op) { str('and').as(:and) }
- rule(:or_op) { str('or').as(:or) }
- rule(:not_op) { str('not').repeat(0, 1).as(:not) }
- rule(:falsey) { str('false').as(:falsey) }
- rule(:truthy) { str('true').as(:truthy) }
- rule(:null) { str('null').as(:null) }
+ rule(:and_op) { str('and') }
+ rule(:or_op) { str('or') }
+ rule(:not_op?) { str('not').repeat(0, 1).as(:not) }
+ rule(:falsey) { str('false') }
+ rule(:truthy) { str('true') }
+ rule(:null) { str('null') }
rule(:number) do
str('-').maybe >> (
str('0') | (match('[1-9]') >> digit.repeat)
spec/scim/kit/v2/filter_spec.rb
@@ -107,9 +107,9 @@ RSpec.describe Scim::Kit::V2::Filter do
specify { expect(subject.presence).to parse('pr') }
specify { expect(subject.and_op).to parse('and') }
specify { expect(subject.or_op).to parse('or') }
- specify { expect(subject.not_op).to parse('not') }
- specify { expect(subject.not_op).to parse('') }
- specify { expect(subject.not_op).not_to parse('not not') }
+ specify { expect(subject.not_op?).to parse('not') }
+ specify { expect(subject.not_op?).to parse('') }
+ specify { expect(subject.not_op?).not_to parse('not not') }
specify { expect(subject.falsey).to parse('false') }
specify { expect(subject.truthy).to parse('true') }
specify { expect(subject.null).to parse('null') }
@@ -125,15 +125,30 @@ RSpec.describe Scim::Kit::V2::Filter do
[
# '',
- '(userType eq "Employee") and ((emails co "example.com") or (emails.value co "example.org"))',
+ # %Q(userType ne "Employee" and not (emails co "example.com" or emails.value co "example.org")),
+ # %Q(userType eq "Employee" and emails[type eq "work" and value co "@example.com"]),
+ # %Q(emails[type eq "work" and value co "@example.com"] or ims[type eq "xmpp" and value co "@foo.com"]),
'(userType ne "Employee") and (not((emails co "example.com") or (emails.value co "example.org")))',
'(userType eq "Employee") and (emails.type eq "work")',
'(userType eq "Employee") and (emails[(type eq "work") and (value co "@example.com")])',
'(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")',
- '((email eq "hello@example.org") or (name.givenName eq "Tsuyoshi")) or (id = "4CE7E760-F222-4096-90B1-4AC491D12F2E")',
- 'title pr'
+ 'title pr',
+ %(userName eq "bjensen"),
+ %(name.familyName co "O'Malley"),
+ %(userName sw "J"),
+ %(urn:ietf:params:scim:schemas:core:2.0:User:userName sw "J"),
+ %(title pr),
+ %(meta.lastModified gt "2011-05-13T04:42:34Z"),
+ %(meta.lastModified ge "2011-05-13T04:42:34Z"),
+ %(meta.lastModified lt "2011-05-13T04:42:34Z"),
+ %(meta.lastModified le "2011-05-13T04:42:34Z"),
+ %(title pr and userType eq "Employee"),
+ %(title pr or userType eq "Intern"),
+ %(schemas eq "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"),
+ %(userType eq "Employee" and (emails co "example.com" or emails.value co "example.org")),
+ %(userType eq "Employee" and (emails.type eq "work"))
].each do |x|
specify { expect(subject).to parse(x) }
end