@@ -91,3 +91,119 @@ func TestErrorDNParsing(t *testing.T) {
9191 }
9292 }
9393}
94+
95+ func TestDNEqual (t * testing.T ) {
96+ testcases := []struct {
97+ A string
98+ B string
99+ Equal bool
100+ }{
101+ // Exact match
102+ {"" , "" , true },
103+ {"o=A" , "o=A" , true },
104+ {"o=A" , "o=B" , false },
105+
106+ {"o=A,o=B" , "o=A,o=B" , true },
107+ {"o=A,o=B" , "o=A,o=C" , false },
108+
109+ {"o=A+o=B" , "o=A+o=B" , true },
110+ {"o=A+o=B" , "o=A+o=C" , false },
111+
112+ // Case mismatch in type is ignored
113+ {"o=A" , "O=A" , true },
114+ {"o=A,o=B" , "o=A,O=B" , true },
115+ {"o=A+o=B" , "o=A+O=B" , true },
116+
117+ // Case mismatch in value is significant
118+ {"o=a" , "O=A" , false },
119+ {"o=a,o=B" , "o=A,O=B" , false },
120+ {"o=a+o=B" , "o=A+O=B" , false },
121+
122+ // Multi-valued RDN order mismatch is ignored
123+ {"o=A+o=B" , "O=B+o=A" , true },
124+ // Number of RDN attributes is significant
125+ {"o=A+o=B" , "O=B+o=A+O=B" , false },
126+
127+ // Missing values are significant
128+ {"o=A+o=B" , "O=B+o=A+O=C" , false }, // missing values matter
129+ {"o=A+o=B+o=C" , "O=B+o=A" , false }, // missing values matter
130+
131+ // Whitespace tests
132+ // Matching
133+ {
134+ "cn=John Doe, ou=People, dc=sun.com" ,
135+ "cn=John Doe, ou=People, dc=sun.com" ,
136+ true ,
137+ },
138+ // Difference in leading/trailing chars is ignored
139+ {
140+ "cn=John Doe, ou=People, dc=sun.com" ,
141+ "cn=John Doe,ou=People,dc=sun.com" ,
142+ true ,
143+ },
144+ // Difference in values is significant
145+ {
146+ "cn=John Doe, ou=People, dc=sun.com" ,
147+ "cn=John Doe, ou=People, dc=sun.com" ,
148+ false ,
149+ },
150+ }
151+
152+ for i , tc := range testcases {
153+ a , err := ldap .ParseDN (tc .A )
154+ if err != nil {
155+ t .Errorf ("%d: %v" , i , err )
156+ continue
157+ }
158+ b , err := ldap .ParseDN (tc .B )
159+ if err != nil {
160+ t .Errorf ("%d: %v" , i , err )
161+ continue
162+ }
163+ if expected , actual := tc .Equal , a .Equal (b ); expected != actual {
164+ t .Errorf ("%d: when comparing '%s' and '%s' expected %v, got %v" , i , tc .A , tc .B , expected , actual )
165+ continue
166+ }
167+ if expected , actual := tc .Equal , b .Equal (a ); expected != actual {
168+ t .Errorf ("%d: when comparing '%s' and '%s' expected %v, got %v" , i , tc .A , tc .B , expected , actual )
169+ continue
170+ }
171+ }
172+ }
173+
174+ func TestDNAncestor (t * testing.T ) {
175+ testcases := []struct {
176+ A string
177+ B string
178+ Ancestor bool
179+ }{
180+ // Exact match returns false
181+ {"" , "" , false },
182+ {"o=A" , "o=A" , false },
183+ {"o=A,o=B" , "o=A,o=B" , false },
184+ {"o=A+o=B" , "o=A+o=B" , false },
185+
186+ // Mismatch
187+ {"ou=C,ou=B,o=A" , "ou=E,ou=D,ou=B,o=A" , false },
188+
189+ // Descendant
190+ {"ou=C,ou=B,o=A" , "ou=E,ou=C,ou=B,o=A" , true },
191+ }
192+
193+ for i , tc := range testcases {
194+ a , err := ldap .ParseDN (tc .A )
195+ if err != nil {
196+ t .Errorf ("%d: %v" , i , err )
197+ continue
198+ }
199+ b , err := ldap .ParseDN (tc .B )
200+ if err != nil {
201+ t .Errorf ("%d: %v" , i , err )
202+ continue
203+ }
204+ if expected , actual := tc .Ancestor , a .AncestorOf (b ); expected != actual {
205+ t .Errorf ("%d: when comparing '%s' and '%s' expected %v, got %v" , i , tc .A , tc .B , expected , actual )
206+ continue
207+ }
208+ }
209+ }
0 commit comments