treequel 1.0.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.
Files changed (74) hide show
  1. data/ChangeLog +354 -0
  2. data/LICENSE +27 -0
  3. data/README +66 -0
  4. data/Rakefile +345 -0
  5. data/Rakefile.local +43 -0
  6. data/bin/treeirb +14 -0
  7. data/bin/treequel +229 -0
  8. data/examples/company-directory.rb +112 -0
  9. data/examples/ldap-monitor.rb +143 -0
  10. data/examples/ldap-monitor/public/css/master.css +328 -0
  11. data/examples/ldap-monitor/public/images/card_small.png +0 -0
  12. data/examples/ldap-monitor/public/images/chain_small.png +0 -0
  13. data/examples/ldap-monitor/public/images/globe_small.png +0 -0
  14. data/examples/ldap-monitor/public/images/globe_small_green.png +0 -0
  15. data/examples/ldap-monitor/public/images/plug.png +0 -0
  16. data/examples/ldap-monitor/public/images/shadows/large-30-down.png +0 -0
  17. data/examples/ldap-monitor/public/images/tick.png +0 -0
  18. data/examples/ldap-monitor/public/images/tick_circle.png +0 -0
  19. data/examples/ldap-monitor/public/images/treequel-favicon.png +0 -0
  20. data/examples/ldap-monitor/views/backends.erb +41 -0
  21. data/examples/ldap-monitor/views/connections.erb +74 -0
  22. data/examples/ldap-monitor/views/databases.erb +39 -0
  23. data/examples/ldap-monitor/views/dump_subsystem.erb +14 -0
  24. data/examples/ldap-monitor/views/index.erb +14 -0
  25. data/examples/ldap-monitor/views/layout.erb +35 -0
  26. data/examples/ldap-monitor/views/listeners.erb +30 -0
  27. data/examples/ldap_state.rb +62 -0
  28. data/lib/treequel.rb +145 -0
  29. data/lib/treequel/branch.rb +589 -0
  30. data/lib/treequel/branchcollection.rb +204 -0
  31. data/lib/treequel/branchset.rb +360 -0
  32. data/lib/treequel/constants.rb +604 -0
  33. data/lib/treequel/directory.rb +541 -0
  34. data/lib/treequel/exceptions.rb +32 -0
  35. data/lib/treequel/filter.rb +704 -0
  36. data/lib/treequel/mixins.rb +325 -0
  37. data/lib/treequel/schema.rb +245 -0
  38. data/lib/treequel/schema/attributetype.rb +252 -0
  39. data/lib/treequel/schema/ldapsyntax.rb +96 -0
  40. data/lib/treequel/schema/matchingrule.rb +124 -0
  41. data/lib/treequel/schema/matchingruleuse.rb +124 -0
  42. data/lib/treequel/schema/objectclass.rb +289 -0
  43. data/lib/treequel/sequel_integration.rb +26 -0
  44. data/lib/treequel/utils.rb +169 -0
  45. data/rake/191_compat.rb +26 -0
  46. data/rake/dependencies.rb +76 -0
  47. data/rake/helpers.rb +434 -0
  48. data/rake/hg.rb +261 -0
  49. data/rake/manual.rb +782 -0
  50. data/rake/packaging.rb +135 -0
  51. data/rake/publishing.rb +318 -0
  52. data/rake/rdoc.rb +30 -0
  53. data/rake/style.rb +62 -0
  54. data/rake/svn.rb +668 -0
  55. data/rake/testing.rb +187 -0
  56. data/rake/verifytask.rb +64 -0
  57. data/rake/win32.rb +190 -0
  58. data/spec/lib/constants.rb +93 -0
  59. data/spec/lib/helpers.rb +100 -0
  60. data/spec/treequel/branch_spec.rb +569 -0
  61. data/spec/treequel/branchcollection_spec.rb +213 -0
  62. data/spec/treequel/branchset_spec.rb +376 -0
  63. data/spec/treequel/directory_spec.rb +487 -0
  64. data/spec/treequel/filter_spec.rb +482 -0
  65. data/spec/treequel/mixins_spec.rb +330 -0
  66. data/spec/treequel/schema/attributetype_spec.rb +237 -0
  67. data/spec/treequel/schema/ldapsyntax_spec.rb +83 -0
  68. data/spec/treequel/schema/matchingrule_spec.rb +158 -0
  69. data/spec/treequel/schema/matchingruleuse_spec.rb +137 -0
  70. data/spec/treequel/schema/objectclass_spec.rb +262 -0
  71. data/spec/treequel/schema_spec.rb +118 -0
  72. data/spec/treequel/utils_spec.rb +49 -0
  73. data/spec/treequel_spec.rb +179 -0
  74. metadata +169 -0
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
6
+
7
+ libdir = basedir + "lib"
8
+
9
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
+ }
11
+
12
+ require 'spec'
13
+ require 'spec/lib/constants'
14
+ require 'spec/lib/helpers'
15
+
16
+ require 'yaml'
17
+ require 'ldap'
18
+ require 'ldap/schema'
19
+ require 'treequel/schema/ldapsyntax'
20
+
21
+
22
+ include Treequel::TestConstants
23
+
24
+ #####################################################################
25
+ ### C O N T E X T S
26
+ #####################################################################
27
+
28
+ describe Treequel::Schema::LDAPSyntax do
29
+ include Treequel::SpecHelpers
30
+
31
+
32
+ before( :all ) do
33
+ setup_logging( :fatal )
34
+ end
35
+
36
+ before( :each ) do
37
+ @schema = mock( "treequel schema object" )
38
+ end
39
+
40
+ after( :all ) do
41
+ reset_logging()
42
+ end
43
+
44
+
45
+ describe "parsed from the 'Boolean' syntax" do
46
+
47
+ BOOLEAN_SYNTAX = %{( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )}
48
+
49
+ before( :each ) do
50
+ @syntax = Treequel::Schema::LDAPSyntax.parse( @schema, BOOLEAN_SYNTAX )
51
+ end
52
+
53
+ it "knows what its OID is" do
54
+ @syntax.oid.should == '1.3.6.1.4.1.1466.115.121.1.7'
55
+ end
56
+
57
+ it "knows what its DESC attribute is" do
58
+ @syntax.desc.should == 'Boolean'
59
+ end
60
+
61
+ end
62
+
63
+
64
+ describe "parsed from a syntax with no DESC" do
65
+ NODESC_SYNTAX = %{( 1.3.6.1.4.1.1466.115.121.1.14 )}
66
+
67
+ before( :each ) do
68
+ @syntax = Treequel::Schema::LDAPSyntax.parse( @schema, NODESC_SYNTAX )
69
+ end
70
+
71
+ it "knows what its OID is" do
72
+ @syntax.oid.should == '1.3.6.1.4.1.1466.115.121.1.14'
73
+ end
74
+
75
+ it "knows that it doesn't have a DESC attribute" do
76
+ @syntax.desc.should be_nil()
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+
83
+ # vim: set nosta noet ts=4 sw=4:
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
6
+
7
+ libdir = basedir + "lib"
8
+
9
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
+ }
11
+
12
+ require 'spec'
13
+ require 'spec/lib/constants'
14
+ require 'spec/lib/helpers'
15
+
16
+ require 'yaml'
17
+ require 'ldap'
18
+ require 'ldap/schema'
19
+ require 'treequel/schema/matchingrule'
20
+
21
+
22
+ include Treequel::TestConstants
23
+ include Treequel::Constants
24
+
25
+ #####################################################################
26
+ ### C O N T E X T S
27
+ #####################################################################
28
+
29
+ describe Treequel::Schema::MatchingRule do
30
+ include Treequel::SpecHelpers
31
+
32
+
33
+ before( :all ) do
34
+ setup_logging( :fatal )
35
+ @datadir = Pathname( __FILE__ ).dirname.parent.parent + 'data'
36
+ end
37
+
38
+ before( :each ) do
39
+ @schema = mock( "treequel schema object" )
40
+ end
41
+
42
+ after( :all ) do
43
+ reset_logging()
44
+ end
45
+
46
+
47
+ describe "parsed from the 'octetStringMatch' matchingRule" do
48
+
49
+ OCTETSTRINGMATCH_RULE = %{( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )}
50
+
51
+ before( :each ) do
52
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, OCTETSTRINGMATCH_RULE )
53
+ end
54
+
55
+ it "knows what OID corresponds to the type" do
56
+ @rule.oid.should == '2.5.13.17'
57
+ end
58
+
59
+ it "knows what its NAME attribute is" do
60
+ @rule.name.should == :octetStringMatch
61
+ end
62
+
63
+ it "knows what its SYNTAX OID is" do
64
+ @rule.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.40'
65
+ end
66
+
67
+ it "knows what its syntax is" do
68
+ @schema.should_receive( :ldap_syntaxes ).
69
+ and_return({ '1.3.6.1.4.1.1466.115.121.1.40' => :the_syntax })
70
+ @rule.syntax.should == :the_syntax
71
+ end
72
+
73
+ it "knows that it is not obsolete" do
74
+ @rule.should_not be_obsolete()
75
+ end
76
+
77
+ end
78
+
79
+ describe "parsed from an matchingRule that has a DESC attribute" do
80
+
81
+ DESCRIBED_RULE = %{( 9.9.9.9.9 DESC 'Hot dog propulsion device' SYNTAX 9.9.9.9.9.9 )}
82
+
83
+ before( :each ) do
84
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, DESCRIBED_RULE )
85
+ end
86
+
87
+ it "knows what its DESC attribute" do
88
+ @rule.desc.should == 'Hot dog propulsion device'
89
+ end
90
+
91
+ end
92
+
93
+ describe "parsed from an matchingRule that doesn't have a NAME attribute" do
94
+
95
+ ANONYMOUS_RULE = %{( 9.9.9.9.9 SYNTAX 9.9.9.9.9.9 )}
96
+
97
+ before( :each ) do
98
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, ANONYMOUS_RULE )
99
+ end
100
+
101
+ it "knows that its NAME is nil" do
102
+ @rule.name.should be_nil()
103
+ end
104
+
105
+ end
106
+
107
+ describe "parsed from an matchingRule that has a list as the value of its NAME attribute" do
108
+
109
+ MULTINAME_MATCHINGRULE = %{( 1.1.1.1 NAME ('firstname' 'secondname') SYNTAX 9.9.9.9.9.9 )}
110
+
111
+ before( :each ) do
112
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, MULTINAME_MATCHINGRULE )
113
+ end
114
+
115
+ it "knows what both names are" do
116
+ @rule.names.should have(2).members
117
+ @rule.names.should include( :firstname, :secondname )
118
+ end
119
+
120
+ it "returns the first of its names for the #name method" do
121
+ @rule.name.should == :firstname
122
+ end
123
+
124
+ end
125
+
126
+ describe "parsed from an matchingRule that has escaped characters in its DESC attribute" do
127
+
128
+ ESCAPED_DESC_MATCHINGRULE = %{( 1.1.1.1 DESC } +
129
+ %{'This spec\\27s example, which includes a \\5c character.' SYNTAX 9.9.9.9.9.9 )}
130
+
131
+ before( :each ) do
132
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, ESCAPED_DESC_MATCHINGRULE )
133
+ end
134
+
135
+ it "unscapes the escaped characters" do
136
+ @rule.desc.should == %{This spec's example, which includes a \\ character.}
137
+ end
138
+
139
+ end
140
+
141
+ describe "parsed from an matchingRule that has the OBSOLETE attribute" do
142
+
143
+ OBSOLETE_MATCHINGRULE = %{( 1.1.1.1 OBSOLETE SYNTAX 9.9.9.9.9.9 )}
144
+
145
+ before( :each ) do
146
+ @rule = Treequel::Schema::MatchingRule.parse( @schema, OBSOLETE_MATCHINGRULE )
147
+ end
148
+
149
+ it "knows that it's obsolete" do
150
+ @rule.should be_obsolete()
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+
157
+
158
+ # vim: set nosta noet ts=4 sw=4:
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
6
+
7
+ libdir = basedir + "lib"
8
+
9
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
+ }
11
+
12
+ require 'spec'
13
+ require 'spec/lib/constants'
14
+ require 'spec/lib/helpers'
15
+
16
+ require 'yaml'
17
+ require 'ldap'
18
+ require 'ldap/schema'
19
+ require 'treequel/schema/matchingruleuse'
20
+
21
+
22
+ include Treequel::TestConstants
23
+ include Treequel::Constants
24
+
25
+ #####################################################################
26
+ ### C O N T E X T S
27
+ #####################################################################
28
+
29
+ describe Treequel::Schema::MatchingRuleUse do
30
+ include Treequel::SpecHelpers
31
+
32
+
33
+ before( :all ) do
34
+ setup_logging( :fatal )
35
+ @datadir = Pathname( __FILE__ ).dirname.parent.parent + 'data'
36
+ end
37
+
38
+ before( :each ) do
39
+ @schema = mock( "treequel schema object" )
40
+ end
41
+
42
+ after( :all ) do
43
+ reset_logging()
44
+ end
45
+
46
+
47
+ describe "parsed from the 'uniqueMemberMatch' matchingRuleUse" do
48
+
49
+ UNIQUE_MEMBER_MATCH_DESC = %{( 2.5.13.23 NAME 'uniqueMemberMatch' APPLIES uniqueMember )}
50
+
51
+ before( :each ) do
52
+ @ruleuse = Treequel::Schema::MatchingRuleUse.parse( @schema, UNIQUE_MEMBER_MATCH_DESC )
53
+ end
54
+
55
+ it "knows what its OID is" do
56
+ @ruleuse.oid.should == '2.5.13.23'
57
+ end
58
+
59
+ it "knows what its NAME attribute is" do
60
+ @ruleuse.name.should == :uniqueMemberMatch
61
+ end
62
+
63
+ it "knows that it is not obsolete" do
64
+ @ruleuse.should_not be_obsolete()
65
+ end
66
+
67
+ it "knows what the OIDs of the attribute types it applies to are" do
68
+ @ruleuse.attr_oids.should == [:uniqueMember]
69
+ end
70
+
71
+ it "knows what Treequel::Schema::AttributeType objects it applies to are" do
72
+ @schema.should_receive( :attribute_types ).
73
+ and_return({ :uniqueMember => :a_attrtype_object })
74
+ @ruleuse.attribute_types.should == [ :a_attrtype_object ]
75
+ end
76
+ end
77
+
78
+
79
+ describe "parsed from a matchingRuleUse with a DESC attribute" do
80
+ DESCRIPTIVE_MATCHRULEUSE_DESC = %{( 9.9.9.9.9 DESC 'Woop' APPLIES uniqueMember )}
81
+
82
+ before( :each ) do
83
+ @ruleuse = Treequel::Schema::MatchingRuleUse.parse( @schema, DESCRIPTIVE_MATCHRULEUSE_DESC )
84
+ end
85
+
86
+ it "knows what its description is" do
87
+ @ruleuse.desc.should == "Woop"
88
+ end
89
+
90
+ end
91
+
92
+
93
+ describe "parsed from a matchingRuleUse with more than one applicable attribute type" do
94
+ PHONENUMBER_MATCHRULEUSE_DESC = %{( 2.5.13.20 NAME 'telephoneNumberMatch' APPLIES } +
95
+ %{( telephoneNumber $ homePhone $ mobile $ pager ) )}
96
+
97
+ before( :each ) do
98
+ @ruleuse = Treequel::Schema::MatchingRuleUse.parse( @schema, PHONENUMBER_MATCHRULEUSE_DESC )
99
+ end
100
+
101
+ it "knows what the OIDs of the attribute types it applies to are" do
102
+ @ruleuse.attr_oids.should have(4).members
103
+ @ruleuse.attr_oids.should include( :telephoneNumber, :homePhone, :mobile, :pager )
104
+ end
105
+
106
+ it "knows what Treequel::Schema::AttributeType objects it applies to are" do
107
+ oidmap = {
108
+ :telephoneNumber => :phone_number_attr,
109
+ :homePhone => :home_phone_attr,
110
+ :mobile => :mobile_attr,
111
+ :pager => :pager_attr,
112
+ }
113
+ @schema.should_receive( :attribute_types ).at_least( 4 ).times.
114
+ and_return( oidmap )
115
+ @ruleuse.attribute_types.should have(4).members
116
+ @ruleuse.attribute_types.should include( *oidmap.values )
117
+ end
118
+ end
119
+
120
+
121
+ describe "parsed from a matchingRuleUse that is marked as OBSOLETE" do
122
+ OBSOLETE_MATCHRULEUSE_DESC = %{( 9.9.9.9.9 OBSOLETE APPLIES uniqueMember )}
123
+
124
+ before( :each ) do
125
+ @ruleuse = Treequel::Schema::MatchingRuleUse.parse( @schema, OBSOLETE_MATCHRULEUSE_DESC )
126
+ end
127
+
128
+ it "knows that it's obsolete" do
129
+ @ruleuse.should be_obsolete()
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
136
+
137
+ # vim: set nosta noet ts=4 sw=4:
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
6
+
7
+ libdir = basedir + "lib"
8
+
9
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
+ }
11
+
12
+ begin
13
+ require 'spec'
14
+ require 'spec/lib/constants'
15
+ require 'spec/lib/helpers'
16
+
17
+ require 'yaml'
18
+ require 'ldap'
19
+ require 'ldap/schema'
20
+ require 'treequel/schema/objectclass'
21
+ require 'treequel/schema/attributetype'
22
+ rescue LoadError
23
+ unless Object.const_defined?( :Gem )
24
+ require 'rubygems'
25
+ retry
26
+ end
27
+ raise
28
+ end
29
+
30
+
31
+ include Treequel::TestConstants
32
+ include Treequel::Constants
33
+
34
+ #####################################################################
35
+ ### C O N T E X T S
36
+ #####################################################################
37
+
38
+ describe Treequel::Schema::ObjectClass do
39
+ include Treequel::SpecHelpers
40
+
41
+
42
+ before( :all ) do
43
+ setup_logging( :fatal )
44
+ @datadir = Pathname( __FILE__ ).dirname.parent.parent + 'data'
45
+ end
46
+
47
+ before( :each ) do
48
+ @schema = mock( "Treequel schema" )
49
+ end
50
+
51
+ after( :all ) do
52
+ reset_logging()
53
+ end
54
+
55
+
56
+ describe "parsed from the 'top' objectClass" do
57
+
58
+ TOP_OBJECTCLASS = %{( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRACT } +
59
+ %{MUST objectClass )}
60
+
61
+ before( :each ) do
62
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, TOP_OBJECTCLASS )
63
+ end
64
+
65
+ it "is an AbstractObjectClass because its 'kind' is 'ABSTRACT'" do
66
+ @oc.should be_an_instance_of( Treequel::Schema::AbstractObjectClass )
67
+ end
68
+
69
+ it "knows what OID corresponds to the class" do
70
+ @oc.oid.should == '2.5.6.0'
71
+ end
72
+
73
+ it "knows what its NAME attribute is" do
74
+ @oc.name.should == :top
75
+ end
76
+
77
+ it "knows what its DESC attribute is" do
78
+ @oc.desc.should == 'top of the superclass chain'
79
+ end
80
+
81
+ it "knows that it has one MUST attribute" do
82
+ @oc.must_oids.should have( 1 ).member
83
+ @oc.must_oids.should == [ :objectClass ]
84
+ end
85
+
86
+ it "returns attribute objects for its MUST OIDs" do
87
+ @schema.should_receive( :attribute_types ).at_least( :once ).
88
+ and_return({ :objectClass => :attribute_type })
89
+
90
+ @oc.must.should have( 1 ).member
91
+ @oc.must.should == [ :attribute_type ]
92
+ end
93
+
94
+ it "returns attribute objects for its MAY OIDs" do
95
+ @schema.should_receive( :attribute_types ).at_least( :once ).
96
+ and_return({ :objectClass => :attribute_type })
97
+
98
+ @oc.must.should have( 1 ).member
99
+ @oc.must.should == [ :attribute_type ]
100
+ end
101
+
102
+ it "knows that it doesn't have any MAY attributes" do
103
+ @oc.may_oids.should be_empty()
104
+ end
105
+
106
+ it "knows that it is not obsolete" do
107
+ @oc.should_not be_obsolete()
108
+ end
109
+
110
+ it "knows that it doesn't have a superclass" do
111
+ @oc.sup.should be_nil()
112
+ end
113
+
114
+ end
115
+
116
+
117
+ describe "parsed from the 'organizationalUnit' objectClass" do
118
+
119
+ OU_OBJECTCLASS = %{( 2.5.6.5 NAME 'organizationalUnit' } +
120
+ %{DESC 'RFC2256: an organizational unit' SUP top STRUCTURAL } +
121
+ %{MUST ou MAY ( userPassword $ searchGuide $ seeAlso $ } +
122
+ %{businessCategory $ x121Address $ registeredAddress $ } +
123
+ %{destinationIndicator $ preferredDeliveryMethod $ telexNumber $ } +
124
+ %{teletexTerminalIdentifier $ telephoneNumber $ internationaliSDNNumber $ } +
125
+ %{facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $ postalAddress $ } +
126
+ %{physicalDeliveryOfficeName $ st $ l $ description ) )}
127
+
128
+ before( :each ) do
129
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, OU_OBJECTCLASS )
130
+ end
131
+
132
+ it "is a StructuralObjectClass because its kind is 'STRUCTURAL'" do
133
+ @oc.should be_an_instance_of( Treequel::Schema::StructuralObjectClass )
134
+ end
135
+
136
+ it "knows what OID corresponds to the class" do
137
+ @oc.oid.should == '2.5.6.5'
138
+ end
139
+
140
+ it "knows what its NAME attribute is" do
141
+ @oc.name.should == :organizationalUnit
142
+ end
143
+
144
+ it "knows what its DESC attribute is" do
145
+ @oc.desc.should == 'RFC2256: an organizational unit'
146
+ end
147
+
148
+ it "knows that it has one MUST attribute" do
149
+ @oc.must_oids.should have( 1 ).member
150
+ @oc.must_oids.should == [ :ou ]
151
+ end
152
+
153
+ it "knows what its MAY attributes are" do
154
+ @oc.may_oids.should have( 21 ).members
155
+ @oc.may_oids.should include( :userPassword, :searchGuide, :seeAlso, :businessCategory,
156
+ :x121Address, :registeredAddress, :destinationIndicator, :preferredDeliveryMethod,
157
+ :telexNumber, :teletexTerminalIdentifier, :telephoneNumber, :internationaliSDNNumber,
158
+ :facsimileTelephoneNumber, :street, :postOfficeBox, :postalCode, :postalAddress,
159
+ :physicalDeliveryOfficeName, :st, :l, :description )
160
+ end
161
+
162
+ end
163
+
164
+
165
+ describe "parsed from an objectClass that doesn't specify an explicit KIND attribute" do
166
+
167
+ KINDLESS_OBJECTCLASS = %{( 1.1.1.1 )}
168
+
169
+ before( :each ) do
170
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, KINDLESS_OBJECTCLASS )
171
+ end
172
+
173
+ it "is the default kind (STRUCTURAL)" do
174
+ @oc.should be_an_instance_of( Treequel::Schema::StructuralObjectClass )
175
+ end
176
+
177
+ end
178
+
179
+ describe "parsed from an objectClass that has a list as the value of its NAME attribute" do
180
+
181
+ MULTINAME_OBJECTCLASS = %{( 1.1.1.1 NAME ('firstname' 'secondname') )}
182
+
183
+ before( :each ) do
184
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, MULTINAME_OBJECTCLASS )
185
+ end
186
+
187
+ it "knows what both names are" do
188
+ @oc.names.should have(2).members
189
+ @oc.names.should include( :firstname, :secondname )
190
+ end
191
+
192
+ it "returns the first of its names for the #name method" do
193
+ @oc.name.should == :firstname
194
+ end
195
+
196
+ end
197
+
198
+ describe "parsed from an objectClass that has escaped characters in its DESC attribute" do
199
+
200
+ ESCAPED_DESC_OBJECTCLASS = %{( 1.1.1.1 DESC } +
201
+ %{'This spec\\27s example, which includes a \\5c character.' )}
202
+
203
+ before( :each ) do
204
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, ESCAPED_DESC_OBJECTCLASS )
205
+ end
206
+
207
+ it "unscapes the escaped characters" do
208
+ @oc.desc.should == %{This spec's example, which includes a \\ character.}
209
+ end
210
+
211
+ end
212
+
213
+ describe "parsed from an objectClass that has the OBSOLETE attribute" do
214
+
215
+ OBSOLETE_OBJECTCLASS = %{( 1.1.1.1 OBSOLETE )}
216
+
217
+ before( :each ) do
218
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, OBSOLETE_OBJECTCLASS )
219
+ end
220
+
221
+ it "knows that it's obsolete" do
222
+ @oc.should be_obsolete()
223
+ end
224
+
225
+ end
226
+
227
+ describe "parsed from an objectClass that has organizationalPerson as its SUP" do
228
+
229
+ SUB_OBJECTCLASS = %{( 1.1.1.1 SUP organizationalPerson )}
230
+
231
+ before( :each ) do
232
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, SUB_OBJECTCLASS )
233
+ end
234
+
235
+ it "returns the corresponding objectClass from its schema" do
236
+ @schema.should_receive( :object_classes ).
237
+ and_return({ :organizationalPerson => :organizationalPerson_objectclass })
238
+ @oc.sup.should == :organizationalPerson_objectclass
239
+ end
240
+
241
+ end
242
+
243
+ describe "parsed from an objectClass that has no explicit SUP" do
244
+
245
+ ORPHAN_OBJECTCLASS = %{( 1.1.1.1 )}
246
+
247
+ before( :each ) do
248
+ @oc = Treequel::Schema::ObjectClass.parse( @schema, ORPHAN_OBJECTCLASS )
249
+ end
250
+
251
+ it "returns the objectClass for 'top' from its schema" do
252
+ @schema.should_receive( :object_classes ).
253
+ and_return({ :top => :top_objectclass })
254
+ @oc.sup.should == :top_objectclass
255
+ end
256
+
257
+ end
258
+
259
+ end
260
+
261
+
262
+ # vim: set nosta noet ts=4 sw=4: