treequel 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ ---
2
+ attributeTypes:
3
+ - ( 1.3.6.1.4.1.1466.101.120.15 NAME 'supportedLDAPVersion' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
4
+ - ( 1.3.6.1.4.1.1466.101.120.6 NAME 'altServer' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
5
+ - ( 1.3.6.1.1.4 NAME 'vendorName' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dsaOperation X-ORIGIN 'RFC 3045' )
6
+ - ( 1.3.6.1.4.1.42.2.27.9.1.800 NAME 'supportedSSLCiphers' DESC 'List of ciphers supported by SSL lib' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'Sun Directory Server' )
7
+ - ( 1.3.6.1.1.5 NAME 'vendorVersion' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dsaOperation X-ORIGIN 'RFC 3045' )
8
+ - ( 1.3.6.1.4.1.1466.101.120.14 NAME 'supportedSASLMechanisms' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
9
+ - ( 1.3.6.1.4.1.1466.101.120.7 NAME 'supportedExtension' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
10
+ - ( 1.3.6.1.4.1.1466.101.120.13 NAME 'supportedControl' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
11
+ - ( 1.3.6.1.4.1.1466.101.120.5 NAME 'namingContexts' DESC 'Standard LDAP attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 USAGE dsaOperation X-ORIGIN 'RFC 2252' )
12
+
13
+ matchingRules:
14
+ - ( 1.3.6.1.4.1.42.2.27.9.4.0.3 NAME 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.0.3' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
15
+ - ( 1.3.6.1.4.1.42.2.27.9.4.0.3.6 NAME 'caseExactSubstringMatch-2.16.840.1.113730.3.3.2.0.3' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
16
+ - ( 1.3.6.1.4.1.42.2.27.9.4.34.3 NAME 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.11.3' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
17
+ - ( 1.3.6.1.4.1.42.2.27.9.4.34.3.6 NAME 'caseExactSubstringMatch-2.16.840.1.113730.3.3.2.11.3' DESC 'en' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
data/spec/lib/helpers.rb CHANGED
@@ -10,6 +10,17 @@ BEGIN {
10
10
  $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
11
11
  }
12
12
 
13
+ # SimpleCov test coverage reporting; enable this using the :coverage rake task
14
+ if ENV['COVERAGE']
15
+ require 'simplecov'
16
+ SimpleCov.start do
17
+ add_filter 'spec'
18
+ add_group "Needing tests" do |file|
19
+ file.covered_percent < 90
20
+ end
21
+ end
22
+ end
23
+
13
24
  require 'rspec'
14
25
 
15
26
  require 'treequel'
@@ -161,8 +172,10 @@ module Treequel::SpecHelpers
161
172
  end
162
173
 
163
174
 
164
- ### Mock with Rspec
165
- Rspec.configure do |c|
175
+ abort "You need a version of RSpec >= 2.6.0" unless defined?( RSpec )
176
+
177
+ ### Mock with RSpec
178
+ RSpec.configure do |c|
166
179
  include Treequel::TestConstants
167
180
 
168
181
  c.mock_with :rspec
@@ -175,6 +188,8 @@ Rspec.configure do |c|
175
188
 
176
189
  c.filter_run_excluding( :ruby_1_8_only => true ) if
177
190
  Treequel::SpecHelpers.vvec( RUBY_VERSION ) >= Treequel::SpecHelpers.vvec('1.9.1')
191
+ c.filter_run_excluding( :mri_only => true ) if
192
+ defined?( RUBY_ENGINE ) && RUBY_ENGINE != 'ruby'
178
193
  end
179
194
 
180
195
  # vim: set nosta noet ts=4 sw=4:
@@ -636,7 +636,14 @@ describe Treequel::Branch do
636
636
  end
637
637
 
638
638
 
639
- it "knows how to represent its DN as an RFC1781-style UFN" do
639
+ it "knows how to represent its DN as an RFC1781-style UFN", :if => LDAP.respond_to?(:dn2ufn) do
640
+ @branch.to_ufn.should =~ /Hosts, acme\.com/i
641
+ end
642
+
643
+
644
+ it "knows how to represent its DN as a UFN even if the LDAP library doesn't " +
645
+ "define #dn2ufn" do
646
+ LDAP.stub( :respond_to? ).with( :dn2ufn ).and_return( false )
640
647
  @branch.to_ufn.should =~ /Hosts, acme\.com/i
641
648
  end
642
649
 
@@ -418,6 +418,15 @@ describe Treequel::Branchset do
418
418
  newset.base_dn.should == TEST_SUBHOSTS_DN
419
419
  end
420
420
 
421
+
422
+ #
423
+ # with_operational_attributes
424
+ #
425
+ it "can create a new branchset cloned from itself with operational attributes selected" do
426
+ newset = @branchset.with_operational_attributes
427
+ newset.options[:select].should include( :+ )
428
+ end
429
+
421
430
  end
422
431
 
423
432
 
@@ -191,7 +191,6 @@ describe Treequel::Directory do
191
191
  @dir.should be_bound()
192
192
  end
193
193
 
194
-
195
194
  it "can be unbound, which replaces the bound connection with a duplicate that is unbound" do
196
195
  dupconn = mock( "duplicate connection" )
197
196
  @conn.should_receive( :bound? ).and_return( true )
@@ -203,7 +202,6 @@ describe Treequel::Directory do
203
202
  @dir.conn.should == dupconn
204
203
  end
205
204
 
206
-
207
205
  it "doesn't do anything if told to unbind but the current connection is not bound" do
208
206
  @conn.should_receive( :bound? ).and_return( false )
209
207
  @conn.should_not_receive( :dup )
@@ -385,6 +383,10 @@ describe Treequel::Directory do
385
383
  end
386
384
 
387
385
 
386
+ it "doesn't retain its connection when duplicated" do
387
+ @dir.dup.conn.should_not equal( @dir.conn )
388
+ end
389
+
388
390
  describe "and a custom search results class" do
389
391
 
390
392
  before( :each ) do
@@ -75,7 +75,7 @@ describe Treequel::TimeExtensions do
75
75
  before( :all ) do
76
76
  # Make the local timezone PDT so offsets show up correctly
77
77
  @real_tz = ENV['TZ']
78
- ENV['TZ'] = ':PST8PDT'
78
+ ENV['TZ'] = 'US/Pacific'
79
79
  end
80
80
 
81
81
  before( :each ) do
@@ -52,7 +52,7 @@ describe Treequel::Schema::AttributeType do
52
52
  %{EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )}
53
53
 
54
54
  before( :each ) do
55
- @attrtype = Treequel::Schema::AttributeType.parse( @schema, OBJECTCLASS_ATTRTYPE )
55
+ @attrtype = described_class.parse( @schema, OBJECTCLASS_ATTRTYPE )
56
56
  end
57
57
 
58
58
  it "knows what OID corresponds to the type" do
@@ -138,7 +138,7 @@ describe Treequel::Schema::AttributeType do
138
138
  %{SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )}
139
139
 
140
140
  before( :each ) do
141
- @attrtype = Treequel::Schema::AttributeType.parse( @schema, DERIVED_ATTRTYPE )
141
+ @attrtype = described_class.parse( @schema, DERIVED_ATTRTYPE )
142
142
  end
143
143
 
144
144
  it "can fetch its superior type from its schema" do
@@ -184,7 +184,7 @@ describe Treequel::Schema::AttributeType do
184
184
  DERIVED_NOSYN_ATTRTYPE = %{( 1.11.2.11.1 SUP aSuperType )}
185
185
 
186
186
  before( :each ) do
187
- @attrtype = Treequel::Schema::AttributeType.parse( @schema, DERIVED_NOSYN_ATTRTYPE )
187
+ @attrtype = described_class.parse( @schema, DERIVED_NOSYN_ATTRTYPE )
188
188
  end
189
189
 
190
190
  it "fetches its SYNTAX from its supertype" do
@@ -203,7 +203,7 @@ describe Treequel::Schema::AttributeType do
203
203
  MULTINAME_ATTRIBUTETYPE = %{( 1.1.1.1 NAME ('firstName' 'secondName') )}
204
204
 
205
205
  before( :each ) do
206
- @attrtype = Treequel::Schema::AttributeType.parse( @schema, MULTINAME_ATTRIBUTETYPE )
206
+ @attrtype = described_class.parse( @schema, MULTINAME_ATTRIBUTETYPE )
207
207
  end
208
208
 
209
209
  it "knows what both names are" do
@@ -234,7 +234,7 @@ describe Treequel::Schema::AttributeType do
234
234
  %{'This spec\\27s example, which includes a \\5c character.' )}
235
235
 
236
236
  before( :each ) do
237
- @attrtype = Treequel::Schema::AttributeType.parse( @schema, ESCAPED_DESC_ATTRIBUTETYPE )
237
+ @attrtype = described_class.parse( @schema, ESCAPED_DESC_ATTRIBUTETYPE )
238
238
  end
239
239
 
240
240
  it "unscapes the escaped characters" do
@@ -248,7 +248,7 @@ describe Treequel::Schema::AttributeType do
248
248
  OBSOLETE_ATTRIBUTETYPE = %{( 1.1.1.1 OBSOLETE )}
249
249
 
250
250
  before( :each ) do
251
- @attrtype = Treequel::Schema::AttributeType.parse( @schema, OBSOLETE_ATTRIBUTETYPE )
251
+ @attrtype = described_class.parse( @schema, OBSOLETE_ATTRIBUTETYPE )
252
252
  end
253
253
 
254
254
  it "knows that it's obsolete" do
@@ -262,8 +262,7 @@ describe Treequel::Schema::AttributeType do
262
262
  DIRECTORY_OPERATIONAL_ATTRIBUTETYPE = %{( 1.1.1.1 USAGE directoryOperation )}
263
263
 
264
264
  before( :each ) do
265
- @attrtype = Treequel::Schema::AttributeType.
266
- parse( @schema, DIRECTORY_OPERATIONAL_ATTRIBUTETYPE )
265
+ @attrtype = described_class.parse( @schema, DIRECTORY_OPERATIONAL_ATTRIBUTETYPE )
267
266
  end
268
267
 
269
268
  it "knows that it's not a user-application attribute type" do
@@ -293,7 +292,7 @@ describe Treequel::Schema::AttributeType do
293
292
  DISTRIBUTED_OPERATIONAL_ATTRIBUTETYPE = %{( 1.1.1.1 USAGE distributedOperation )}
294
293
 
295
294
  before( :each ) do
296
- @attrtype = Treequel::Schema::AttributeType.
295
+ @attrtype = described_class.
297
296
  parse( @schema, DISTRIBUTED_OPERATIONAL_ATTRIBUTETYPE )
298
297
  end
299
298
 
@@ -324,8 +323,7 @@ describe Treequel::Schema::AttributeType do
324
323
  DSASPECIFIC_OPERATIONAL_ATTRIBUTETYPE = %{( 1.1.1.1 USAGE dSAOperation )}
325
324
 
326
325
  before( :each ) do
327
- @attrtype = Treequel::Schema::AttributeType.
328
- parse( @schema, DSASPECIFIC_OPERATIONAL_ATTRIBUTETYPE )
326
+ @attrtype = described_class.parse( @schema, DSASPECIFIC_OPERATIONAL_ATTRIBUTETYPE )
329
327
  end
330
328
 
331
329
  it "knows that it's not a user-application attribute type" do
@@ -350,6 +348,85 @@ describe Treequel::Schema::AttributeType do
350
348
 
351
349
  end
352
350
 
351
+ describe "parsed from the 'supportedLDAPVersion' attribute type" do
352
+
353
+ SUPPORTED_LDAP_VERSION_ATTRIBUTETYPE = %{( 1.3.6.1.4.1.1466.101.120.15 NAME } +
354
+ %{'supportedLDAPVersion' DESC 'Standard LDAP attribute type' SYNTAX } +
355
+ %{1.3.6.1.4.1.1466.115.121.1.27 USAGE dsaOperation X-ORIGIN 'RFC 2252' )}
356
+
357
+ before( :each ) do
358
+ @attrtype = described_class.parse( @schema, SUPPORTED_LDAP_VERSION_ATTRIBUTETYPE )
359
+ end
360
+
361
+ it "knows what OID corresponds to the type" do
362
+ @attrtype.oid.should == '1.3.6.1.4.1.1466.101.120.15'
363
+ end
364
+
365
+ it "knows what its NAME attribute is" do
366
+ @attrtype.name.should == :supportedLDAPVersion
367
+ end
368
+
369
+ it "knows what its DESC attribute is" do
370
+ @attrtype.desc.should == 'Standard LDAP attribute type'
371
+ end
372
+
373
+ it "knows it doesn't have a superior type" do
374
+ @attrtype.sup.should be_nil()
375
+ end
376
+
377
+ it "knows what the name of its equality matching rule is" do
378
+ @attrtype.eqmatch_oid.should be_nil()
379
+ end
380
+
381
+ end
382
+
383
+ describe "compatibility with malformed declarations: " do
384
+
385
+ LDAP_CHANGELOG_ATTRIBUTETYPE = %{
386
+ ( 2.16.840.1.113730.3.1.35
387
+ NAME 'changelog'
388
+ DESC 'the distinguished name of the entry which contains
389
+ the set of entries comprising this server's changelog'
390
+ EQUALITY distinguishedNameMatch
391
+ SYNTAX 'DN'
392
+ )
393
+ }
394
+
395
+ it "parses the 'changelog' attribute type from draft-good-ldap-changelog" do
396
+ attrtype = described_class.parse( @schema, LDAP_CHANGELOG_ATTRIBUTETYPE )
397
+
398
+ attrtype.should be_a( described_class )
399
+ attrtype.name.should == :changelog
400
+ attrtype.oid.should == '2.16.840.1.113730.3.1.35'
401
+ attrtype.desc.should == %{the distinguished name of the entry which contains } +
402
+ %{the set of entries comprising this server's changelog}
403
+ end
404
+
405
+ LDAP_CHANGELOG_CHANGENUMBER_ATTRIBUTETYPE = %{
406
+ ( 2.16.840.1.113730.3.1.5
407
+ NAME 'changeNumber'
408
+ DESC 'a number which uniquely identifies a change made to a
409
+ directory entry'
410
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
411
+ EQUALITY integerMatch
412
+ ORDERING integerOrderingMatch
413
+ SINGLE-VALUE
414
+ )
415
+ }
416
+
417
+ it "parses the 'changeNumber' attribute from draft-good-ldap-changelog" do
418
+ attrtype = described_class.parse( @schema, LDAP_CHANGELOG_CHANGENUMBER_ATTRIBUTETYPE )
419
+
420
+ attrtype.should be_a( described_class )
421
+ attrtype.name.should == :changeNumber
422
+ attrtype.oid.should == '2.16.840.1.113730.3.1.5'
423
+ attrtype.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.27'
424
+ attrtype.desc.should == %{a number which uniquely identifies a change made to a } +
425
+ %{directory entry}
426
+ end
427
+
428
+ end
429
+
353
430
  end
354
431
 
355
432
 
@@ -158,6 +158,43 @@ describe Treequel::Schema::MatchingRule do
158
158
 
159
159
  end
160
160
 
161
+
162
+ describe "parsed from one of the matching rules from the OpenDS schema" do
163
+
164
+ TIME_BASED_MATCHINGRULE = %{( 1.3.6.1.4.1.26027.1.4.5 NAME } +
165
+ %{( 'relativeTimeGTOrderingMatch' 'relativeTimeOrderingMatch.gt' ) } +
166
+ %{SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )}
167
+
168
+ before( :each ) do
169
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, TIME_BASED_MATCHINGRULE )
170
+ end
171
+
172
+ it "knows that it's obsolete" do
173
+ @rule.name.should == :relativeTimeGTOrderingMatch
174
+ @rule.names.should include( :relativeTimeGTOrderingMatch, :'relativeTimeOrderingMatch.gt' )
175
+ @rule.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.24'
176
+ end
177
+
178
+ end
179
+
180
+
181
+ describe "parsed from one of the matching rules from issue 11" do
182
+
183
+ NAME_AND_OID_MATCHINGRULE = %{( 1.3.6.1.4.1.42.2.27.9.4.0.3 } +
184
+ %{NAME 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.0.3' } +
185
+ %{SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )}
186
+
187
+ before( :each ) do
188
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, NAME_AND_OID_MATCHINGRULE )
189
+ end
190
+
191
+ it "knows what its rule is" do
192
+ @rule.name.should == 'caseExactOrderingMatch-2.16.840.1.113730.3.3.2.0.3'.to_sym
193
+ @rule.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.15'
194
+ end
195
+
196
+ end
197
+
161
198
  end
162
199
 
163
200
 
@@ -53,7 +53,6 @@ describe Treequel::Schema::ObjectClass do
53
53
  %{ facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $} +
54
54
  %{ postalAddress $ physicalDeliveryOfficeName $ ou $ st $ l ) )}
55
55
 
56
-
57
56
  before( :all ) do
58
57
  setup_logging( :fatal )
59
58
  @datadir = Pathname( __FILE__ ).dirname.parent.parent + 'data'
@@ -316,6 +315,91 @@ describe Treequel::Schema::ObjectClass do
316
315
  end
317
316
  end
318
317
 
318
+
319
+ # Sun/Oracle OpenDS (as of 2.2, at least) "allows a non-numeric OID [as the
320
+ # 'numericoid' part of an objectClass definition] for the purpose of convenience"
321
+ describe "Sun OpenDS compatibility workarounds (ticket #11)" do
322
+
323
+ SUN_ODS_DESCR_OID_OBJECTCLASS =
324
+ %{( interwovengroup-oid NAME 'interwovengroup' SUP posixgroup } +
325
+ %{ STRUCTURAL MAY path X-ORIGIN 'user defined' )}
326
+
327
+ before( :each ) do
328
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, SUN_ODS_DESCR_OID_OBJECTCLASS )
329
+ end
330
+
331
+
332
+ it "sets the oid to the non-numeric OID value" do
333
+ @oc.oid.should == 'interwovengroup-oid'
334
+ @oc.name.should == :interwovengroup
335
+ @oc.extensions.should == %{X-ORIGIN 'user defined'}
336
+ end
337
+
338
+ end
339
+
340
+
341
+ describe "compatibility with malformed declarations: " do
342
+
343
+ SLP_SERVICE_OBJECTCLASS = %{
344
+ ( 1.3.6.1.4.1.6252.2.27.6.2.1
345
+ NAME 'slpService'
346
+ DESC 'parent superclass for SLP services'
347
+ ABSTRACT
348
+ SUP top
349
+ MUST ( template-major-version-number $
350
+ template-minor-version-number $
351
+ description $
352
+ template-url-syntax $
353
+ service-advert-service-type $
354
+ service-advert-scopes )
355
+ MAY ( service-advert-url-authenticator $
356
+ service-advert-attribute-authenticator ) )
357
+ }
358
+
359
+ it "parses the malformed objectClass from RFC 2926" do
360
+ oc = Treequel::Schema::ObjectClass.parse( @schema, SLP_SERVICE_OBJECTCLASS )
361
+
362
+ oc.should be_a( Treequel::Schema::ObjectClass )
363
+ oc.name.should == :slpService
364
+ oc.oid.should == '1.3.6.1.4.1.6252.2.27.6.2.1'
365
+ end
366
+
367
+
368
+ AUTH_PASSWORD_OBJECT_OBJECTCLASS = %{
369
+ ( 1.3.6.1.4.1.4203.1.4.7 NAME 'authPasswordObject'
370
+ DESC 'authentication password mix in class'
371
+ MAY 'authPassword'
372
+ AUXILIARY )
373
+ }
374
+
375
+ it "parses the malformed authPasswordObject objectClass from RFC2696" do
376
+ oc = Treequel::Schema::ObjectClass.parse( @schema, AUTH_PASSWORD_OBJECT_OBJECTCLASS )
377
+
378
+ oc.should be_a( Treequel::Schema::ObjectClass )
379
+ oc.name.should == :authPasswordObject
380
+ oc.oid.should == '1.3.6.1.4.1.4203.1.4.7'
381
+ end
382
+
383
+ DRAFT_HOWARD_RFC2307BIS_OBJECTCLASS = %{
384
+ ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
385
+ SUP top
386
+ AUXILIARY
387
+ DESC 'Abstraction of an account with POSIX attributes'
388
+ MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
389
+ MAY ( authPassword $ userPassword $ loginShell $ gecos $ description )
390
+ X-ORIGIN 'draft-howard-rfc2307bis' )
391
+ }
392
+
393
+ it "parses the malformed objectClasses from draft-howard-rfc2307bis" do
394
+ oc = Treequel::Schema::ObjectClass.parse( @schema, DRAFT_HOWARD_RFC2307BIS_OBJECTCLASS )
395
+
396
+ oc.should be_a( Treequel::Schema::ObjectClass )
397
+ oc.name.should == :posixAccount
398
+ oc.oid.should == '1.3.6.1.1.1.2.0'
399
+ end
400
+
401
+ end
402
+
319
403
  end
320
404
 
321
405
 
@@ -12,7 +12,6 @@ BEGIN {
12
12
 
13
13
  require 'rspec'
14
14
 
15
- require 'spec/lib/constants'
16
15
  require 'spec/lib/helpers'
17
16
 
18
17
  require 'yaml'
@@ -21,29 +20,108 @@ require 'ldap/schema'
21
20
  require 'treequel/schema'
22
21
 
23
22
 
24
- include Treequel::TestConstants
25
- include Treequel::Constants
26
-
27
- #####################################################################
28
- ### C O N T E X T S
29
- #####################################################################
30
-
31
23
  describe Treequel::Schema do
32
24
  include Treequel::SpecHelpers
33
25
 
34
26
  before( :all ) do
35
- setup_logging( :fatal )
27
+ setup_logging( :warn )
36
28
  @datadir = Pathname( __FILE__ ).dirname.parent + 'data'
37
29
  end
38
30
 
31
+ before( :each ) do
32
+ @strict_flag = Treequel::Schema.strict_parse_mode?
33
+ end
34
+
35
+ after( :each ) do
36
+ Treequel::Schema.strict_parse_mode = @strict_flag
37
+ end
38
+
39
39
  after( :all ) do
40
40
  reset_logging()
41
41
  end
42
42
 
43
+ ### Constants
44
+
45
+ # Some simple parser-testing values
43
46
  TEST_NUMERICOID = '1.12.3.8.16.1.1.5'
44
47
  TEST_DESCR = 'objectClass'
45
48
  TEST_OIDLIST = %:( #{TEST_DESCR} $ objectCaste $ #{TEST_NUMERICOID} ) :
46
49
 
50
+ # The malformed objectClass from RFC2926, for testing schema-parsing lenience
51
+ BAD_OBJECTCLASS = "( 1.3.6.1.4.1.6252.2.27.6.2.1 NAME 'slpService' " +
52
+ "DESC 'parent superclass for SLP services' ABSTRACT SUP top MUST " +
53
+ " ( template-major-version-number $ template-minor-version-number " +
54
+ "$ description $ template-url-syntax $ service-advert-service-type " +
55
+ "$ service-advert-scopes ) MAY ( service-advert-url-authenticator " +
56
+ "$ service-advert-attribute-authenticator ) X-ORIGIN 'RFC 2926' )"
57
+
58
+ ### Matchers
59
+
60
+ RSpec::Matchers.define( :be_lenient ) do
61
+ match do |actual|
62
+ !actual.strict_parse_mode?
63
+ end
64
+ end
65
+
66
+
67
+ ### Examples
68
+
69
+ it "defaults to lenient schema-parsing" do
70
+ Treequel::Schema.should be_lenient()
71
+ end
72
+
73
+ it "can be told to propagate schema-parsing failures for easier problem-detection" do
74
+ Treequel::Schema.strict_parse_mode = true
75
+ Treequel::Schema.should_not be_lenient()
76
+ end
77
+
78
+
79
+ it "doesn't propagate parse errors while in lenient schema-parsing mode" do
80
+ schema = Treequel::Schema.new( 'objectClasses' => [BAD_OBJECTCLASS],
81
+ 'attributeTypes' => [],
82
+ 'ldapSyntaxes' => [],
83
+ 'matchingRules' => [],
84
+ 'matchingRuleUse' => [] )
85
+ schema.should be_a( Treequel::Schema )
86
+ schema.object_classes.keys.should_not include( 'slpService' )
87
+ end
88
+
89
+ it "propagates parse errors while in strict schema-parsing mode" do
90
+ Treequel::Schema.strict_parse_mode = true
91
+ expect {
92
+ Treequel::Schema.new( 'objectClasses' => [BAD_OBJECTCLASS] )
93
+ }.to raise_exception( Treequel::ParseError, /malformed objectClass/i )
94
+ end
95
+
96
+ it "can parse a valid oidlist" do
97
+ oids = Treequel::Schema.parse_oids( TEST_OIDLIST )
98
+ oids.should have(3).members
99
+ oids.should == [ :objectClass, :objectCaste, TEST_NUMERICOID ]
100
+ end
101
+
102
+ it "returns an empty Array if oidlist it's asked to parse is nil" do
103
+ Treequel::Schema.parse_oids( nil ).should == []
104
+ end
105
+
106
+ it "raises an exception if it's asked to parse an invalid oidlist" do
107
+ expect do
108
+ Treequel::Schema.parse_oids( %Q{my name is Jorma, I'm the sensitive one} )
109
+ end.to raise_error( Treequel::ParseError, /oidlist/i )
110
+ end
111
+
112
+
113
+ it "keeps a numeric OID as a String when parsing it" do
114
+ Treequel::Schema.parse_oid( TEST_NUMERICOID ).should be_a( String )
115
+ Treequel::Schema.parse_oid( TEST_NUMERICOID ).should == TEST_NUMERICOID
116
+ end
117
+
118
+ it "transforms a named OID as a Symbol when parsing it" do
119
+ Treequel::Schema.parse_oid( TEST_DESCR ).should be_a( Symbol )
120
+ Treequel::Schema.parse_oid( TEST_DESCR ).should == TEST_DESCR.to_sym
121
+ end
122
+
123
+
124
+
47
125
  context "OpenLDAP schema" do
48
126
  before( :all ) do
49
127
  @schema_dumpfile = @datadir + 'schema.yml'
@@ -72,7 +150,8 @@ describe Treequel::Schema do
72
150
  end
73
151
 
74
152
 
75
- it "can parse the schema structure returned from LDAP::Conn#schema even under $SAFE >= 1" do
153
+ it "can parse the schema structure returned from LDAP::Conn#schema even under $SAFE >= 1",
154
+ :mri_only => true do
76
155
  schema = nil
77
156
  Thread.new do
78
157
  Thread.current.abort_on_exception = true
@@ -105,37 +184,73 @@ describe Treequel::Schema do
105
184
  @schema.operational_attribute_types.should be_empty()
106
185
  end
107
186
 
108
-
109
187
  end
110
188
 
111
189
 
112
- it "can parse a valid oidlist" do
113
- oids = Treequel::Schema.parse_oids( TEST_OIDLIST )
114
- oids.should have(3).members
115
- oids.should == [ :objectClass, :objectCaste, TEST_NUMERICOID ]
116
- end
190
+ # Dumped from an OpenDS 2.2 server with the included 'test data' -- dunno if that's
191
+ # representative of schemas one would find in the wild, but it doesn't parse as-is
192
+ # currently because of (at least) the objectClasses from RFCs 2696, 3112, 3712, and
193
+ # draft-howard-rfc2307bi
194
+ context "OpenDS schema" do
117
195
 
118
- it "returns an empty Array if oidlist it's asked to parse is nil" do
119
- Treequel::Schema.parse_oids( nil ).should == []
120
- end
196
+ before( :all ) do
197
+ @schema_dumpfile = @datadir + 'opends.yml'
198
+ @hash = YAML.load_file( @schema_dumpfile )
199
+ @schemahash = LDAP::Schema.new( @hash )
200
+ end
121
201
 
122
- it "raises an exception if it's asked to parse an invalid oidlist" do
123
- expect do
124
- Treequel::Schema.parse_oids( %Q{my name is Jorma, I'm the sensitive one} )
125
- end.to raise_error( Treequel::ParseError, /oidlist/i )
126
- end
202
+ it "can parse an OpenDS schema structure, too" do
203
+ @schema = Treequel::Schema.new( @schemahash )
127
204
 
205
+ @schema.object_classes.values.uniq.should have( @hash['objectClasses'].length ).members
206
+ @schema.attribute_types.values.uniq.should have( @hash['attributeTypes'].length ).members
207
+ @schema.matching_rules.values.uniq.should have( @hash['matchingRules'].length ).members
208
+ @schema.ldap_syntaxes.values.uniq.should have( @hash['ldapSyntaxes'].length ).members
209
+
210
+ @schema.matching_rule_uses.should be_empty()
211
+
212
+ # Not yet supported
213
+ # @schema.dit_structure_rules.values.uniq.should have( @hash['dITStructureRules'].length ).members
214
+ # @schema.dit_content_rules.values.uniq.should have( @hash['dITContentRules'].length ).members
215
+ # @schema.name_forms.values.uniq.should have( @hash['nameForms'].length ).members
216
+
217
+ dirop_count = @hash['attributeTypes'].
218
+ count {|type| type.index('USAGE directoryOperation') }
219
+ dsaop_count = @hash['attributeTypes'].
220
+ count {|type| type.index('USAGE dSAOperation') }
221
+ distop_count = @hash['attributeTypes'].
222
+ count {|type| type.index('USAGE distributedOperation') }
223
+ op_attrcount = dirop_count + dsaop_count + distop_count
224
+
225
+ @schema.operational_attribute_types.should have( op_attrcount ).members
226
+ end
128
227
 
129
- it "keeps a numeric OID as a String when parsing it" do
130
- Treequel::Schema.parse_oid( TEST_NUMERICOID ).should be_a( String )
131
- Treequel::Schema.parse_oid( TEST_NUMERICOID ).should == TEST_NUMERICOID
132
228
  end
133
229
 
134
- it "transforms a named OID as a Symbol when parsing it" do
135
- Treequel::Schema.parse_oid( TEST_DESCR ).should be_a( Symbol )
136
- Treequel::Schema.parse_oid( TEST_DESCR ).should == TEST_DESCR.to_sym
230
+
231
+ # Attribute types and matching rules from ticket #11
232
+ context "ticket 11 schema artifacts" do
233
+
234
+ before( :all ) do
235
+ @schema_dumpfile = @datadir + 'ticket11.yml'
236
+ @hash = YAML.load_file( @schema_dumpfile )
237
+ @schemahash = LDAP::Schema.new( @hash )
238
+ @schema = Treequel::Schema.new( @schemahash )
239
+ end
240
+
241
+ it "can parse schema artifacts from ticket 11" do
242
+ @schema.attribute_types.values.uniq.should have( @hash['attributeTypes'].length ).members
243
+ @schema.matching_rules.values.uniq.should have( @hash['matchingRules'].length ).members
244
+
245
+ dsaop_count = @hash['attributeTypes'].
246
+ count {|type| type.index('USAGE dsaOperation') }
247
+
248
+ @schema.operational_attribute_types.should have( dsaop_count ).members
249
+ end
250
+
137
251
  end
138
252
 
253
+
139
254
  end
140
255
 
141
256
 
data.tar.gz.sig CHANGED
Binary file