[Ruby-activeldap-commit] [ruby-activeldap commit] r177 - in trunk: lib/active_ldap/adapter test

codesite-noreply at google.com codesite-noreply at google.com
Wed May 9 04:04:10 EDT 2007


Author: koutou
Date: Wed May  9 01:03:52 2007
New Revision: 177

Added:
   trunk/test/test_adapter.rb
Modified:
   trunk/lib/active_ldap/adapter/base.rb

Log:
* cleanup ActiveLdap::Adapter::Base#parse_filter.


Modified: trunk/lib/active_ldap/adapter/base.rb
==============================================================================
--- trunk/lib/active_ldap/adapter/base.rb	(original)
+++ trunk/lib/active_ldap/adapter/base.rb	Wed May  9 01:03:52 2007
@@ -61,43 +61,89 @@
         end
       end
 
-      # FIXME: should cleanup!!!
       def parse_filter(filter)
         return nil if filter.nil?
         if !filter.is_a?(String) and !filter.respond_to?(:collect)
           filter = filter.to_s
         end
 
-        if filter.is_a?(String)
-          if filter.empty?
-            nil
-          else
-            filter
+        case filter
+        when String
+          parse_filter_string(filter)
+        when Hash
+          components = filter.sort_by {|k, v| k.to_s}.collect do |key, value|
+            construct_component(key, value)
           end
+          construct_filter(components)
         else
-          type, *components = filter
-          unless [:and, :or, :&, :|].include?(type)
-            components.unshift(type)
-            type = :and
+          operator, *components = filter
+          unless operator.is_a?(Symbol)
+            components.unshift(operator)
+            operator = nil
           end
-          if type == :&
-            type = :and
-          elsif type == :|
-            type = :or
+
+          components = components.collect do |key, value, *others|
+            if value.nil?
+              parse_filter(key)
+            elsif !others.empty?
+              parse_filter([key, value, *others])
+            else
+              construct_component(key, value)
+            end
           end
+          construct_filter(components, operator)
+        end
+      end
 
-          components = components.collect do |component|
-            parse_filter(component)
-          end.compact
-
-          case components.size
-          when 0
-            nil
-          when 1
-            components.join
+      def parse_filter_string(filter)
+        if /\A\s*\z/.match(filter)
+          nil
+        else
+          if filter[0, 1] == "("
+            filter
           else
-            "(#{type == :and ? '&' : '|'}#{components.join})"
+            "(#{filter})"
+          end
+        end
+      end
+
+      def construct_component(key, value)
+        if !value.is_a?(String) and value.respond_to?(:collect)
+          values = value.collect {|v| [key, v]}
+          if values[0][1].is_a?(Symbol)
+            _, operator = values.shift
+            values.unshift(operator)
           end
+          parse_filter(values)
+        else
+          "(#{key}=#{value})"
+        end
+      end
+
+      def construct_filter(components, operator=nil)
+        operator = normalize_filter_logical_operator(operator)
+        components = components.compact
+        case components.size
+        when 0
+          nil
+        when 1
+          components.join
+        else
+          "(#{operator == :and ? '&' : '|'}#{components.join})"
+        end
+      end
+
+      def normalize_filter_logical_operator(type)
+        case (type || :and)
+        when :and, :&
+          :and
+        when :or, :|
+          :or
+        else
+          operators = [:and, :or, :&, :|]
+          raise ArgumentError,
+                "invalid logical operator: #{type.inspect}: " +
+                "available operators: #{operators.inspect}"
         end
       end
     end

Added: trunk/test/test_adapter.rb
==============================================================================
--- (empty file)
+++ trunk/test/test_adapter.rb	Wed May  9 01:03:52 2007
@@ -0,0 +1,76 @@
+require 'al-test-utils'
+
+class TestAdapter < Test::Unit::TestCase
+  include AlTestUtils
+
+  def setup
+  end
+
+  def teardown
+  end
+
+  priority :must
+
+  priority :normal
+  def test_empty_filter
+    assert_parse_filter(nil, nil)
+    assert_parse_filter(nil, "")
+    assert_parse_filter(nil, "   ")
+  end
+
+  def test_simple_filter
+    assert_parse_filter("(objectClass=*)", "objectClass=*")
+    assert_parse_filter("(objectClass=*)", "(objectClass=*)")
+    assert_parse_filter("(&(uid=bob)(objectClass=*))",
+                        "(&(uid=bob)(objectClass=*))")
+
+    assert_parse_filter("(objectClass=*)", {:objectClass => "*"})
+    assert_parse_filter("(&(objectClass=*)(uid=bob))",
+                        {:uid => "bob", :objectClass => "*"})
+
+    assert_parse_filter("(&(uid=bob)(objectClass=*))",
+                        [:and, "uid=bob", "objectClass=*"])
+    assert_parse_filter("(&(uid=bob)(objectClass=*))",
+                        [:&, "uid=bob", "objectClass=*"])
+    assert_parse_filter("(|(uid=bob)(objectClass=*))",
+                        [:or, "uid=bob", "objectClass=*"])
+    assert_parse_filter("(|(uid=bob)(objectClass=*))",
+                        [:|, "uid=bob", "objectClass=*"])
+  end
+
+  def test_multi_value_filter
+    assert_parse_filter("(&(objectClass=top)(objectClass=posixAccount))",
+                        {:objectClass => ["top", "posixAccount"]})
+
+    assert_parse_filter("(&(objectClass=top)(objectClass=posixAccount))",
+                        [[:objectClass, "top"],
+                         [:objectClass, "posixAccount"]])
+    assert_parse_filter("(&(objectClass=top)(objectClass=posixAccount))",
+                        [[:objectClass, ["top", "posixAccount"]]])
+  end
+
+  def test_nested_filter
+    assert_parse_filter("(&(objectClass=*)(uid=bob))",
+                        [:and, {:uid => "bob", :objectClass => "*"}])
+    assert_parse_filter("(&(objectClass=*)(|(uid=bob)(uid=alice)))",
+                        [:and, {:objectClass => "*"},
+                         [:or, [:uid, "bob"], [:uid, "alice"]]])
+    assert_parse_filter("(&(objectClass=*)(|(uid=bob)(uid=alice)))",
+                        [:and,
+                         {:objectClass => "*",
+                          :uid => [:or, "bob", "alice"]}])
+  end
+
+  def test_invalid_operator
+    assert_raises(ArgumentError) do
+      assert_parse_filter("(&(objectClass=*)(uid=bob))",
+                          [:xxx, {:uid => "bob", :objectClass => "*"}])
+    end
+  end
+
+  private
+  def assert_parse_filter(expected, filter)
+    adapter = ActiveLdap::Adapter::Base.new
+    assert_equal(expected, adapter.send(:parse_filter, filter))
+  end
+end


More information about the Ruby-activeldap-commit mailing list