treequel 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: