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.
- data/ChangeLog +354 -0
- data/LICENSE +27 -0
- data/README +66 -0
- data/Rakefile +345 -0
- data/Rakefile.local +43 -0
- data/bin/treeirb +14 -0
- data/bin/treequel +229 -0
- data/examples/company-directory.rb +112 -0
- data/examples/ldap-monitor.rb +143 -0
- data/examples/ldap-monitor/public/css/master.css +328 -0
- data/examples/ldap-monitor/public/images/card_small.png +0 -0
- data/examples/ldap-monitor/public/images/chain_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small_green.png +0 -0
- data/examples/ldap-monitor/public/images/plug.png +0 -0
- data/examples/ldap-monitor/public/images/shadows/large-30-down.png +0 -0
- data/examples/ldap-monitor/public/images/tick.png +0 -0
- data/examples/ldap-monitor/public/images/tick_circle.png +0 -0
- data/examples/ldap-monitor/public/images/treequel-favicon.png +0 -0
- data/examples/ldap-monitor/views/backends.erb +41 -0
- data/examples/ldap-monitor/views/connections.erb +74 -0
- data/examples/ldap-monitor/views/databases.erb +39 -0
- data/examples/ldap-monitor/views/dump_subsystem.erb +14 -0
- data/examples/ldap-monitor/views/index.erb +14 -0
- data/examples/ldap-monitor/views/layout.erb +35 -0
- data/examples/ldap-monitor/views/listeners.erb +30 -0
- data/examples/ldap_state.rb +62 -0
- data/lib/treequel.rb +145 -0
- data/lib/treequel/branch.rb +589 -0
- data/lib/treequel/branchcollection.rb +204 -0
- data/lib/treequel/branchset.rb +360 -0
- data/lib/treequel/constants.rb +604 -0
- data/lib/treequel/directory.rb +541 -0
- data/lib/treequel/exceptions.rb +32 -0
- data/lib/treequel/filter.rb +704 -0
- data/lib/treequel/mixins.rb +325 -0
- data/lib/treequel/schema.rb +245 -0
- data/lib/treequel/schema/attributetype.rb +252 -0
- data/lib/treequel/schema/ldapsyntax.rb +96 -0
- data/lib/treequel/schema/matchingrule.rb +124 -0
- data/lib/treequel/schema/matchingruleuse.rb +124 -0
- data/lib/treequel/schema/objectclass.rb +289 -0
- data/lib/treequel/sequel_integration.rb +26 -0
- data/lib/treequel/utils.rb +169 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/helpers.rb +434 -0
- data/rake/hg.rb +261 -0
- data/rake/manual.rb +782 -0
- data/rake/packaging.rb +135 -0
- data/rake/publishing.rb +318 -0
- data/rake/rdoc.rb +30 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/rake/win32.rb +190 -0
- data/spec/lib/constants.rb +93 -0
- data/spec/lib/helpers.rb +100 -0
- data/spec/treequel/branch_spec.rb +569 -0
- data/spec/treequel/branchcollection_spec.rb +213 -0
- data/spec/treequel/branchset_spec.rb +376 -0
- data/spec/treequel/directory_spec.rb +487 -0
- data/spec/treequel/filter_spec.rb +482 -0
- data/spec/treequel/mixins_spec.rb +330 -0
- data/spec/treequel/schema/attributetype_spec.rb +237 -0
- data/spec/treequel/schema/ldapsyntax_spec.rb +83 -0
- data/spec/treequel/schema/matchingrule_spec.rb +158 -0
- data/spec/treequel/schema/matchingruleuse_spec.rb +137 -0
- data/spec/treequel/schema/objectclass_spec.rb +262 -0
- data/spec/treequel/schema_spec.rb +118 -0
- data/spec/treequel/utils_spec.rb +49 -0
- data/spec/treequel_spec.rb +179 -0
- metadata +169 -0
@@ -0,0 +1,330 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
extdir = basedir + "ext"
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
|
+
$LOAD_PATH.unshift( extdir ) unless $LOAD_PATH.include?( extdir )
|
12
|
+
}
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'spec'
|
16
|
+
require 'spec/lib/constants'
|
17
|
+
require 'spec/lib/helpers'
|
18
|
+
|
19
|
+
require 'treequel'
|
20
|
+
require 'treequel/mixins'
|
21
|
+
rescue LoadError
|
22
|
+
unless Object.const_defined?( :Gem )
|
23
|
+
require 'rubygems'
|
24
|
+
retry
|
25
|
+
end
|
26
|
+
raise
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
include Treequel::TestConstants
|
31
|
+
include Treequel::Constants
|
32
|
+
|
33
|
+
#####################################################################
|
34
|
+
### C O N T E X T S
|
35
|
+
#####################################################################
|
36
|
+
|
37
|
+
describe Treequel, "mixin" do
|
38
|
+
include Treequel::SpecHelpers
|
39
|
+
|
40
|
+
describe Treequel::Loggable, "mixed into a class" do
|
41
|
+
before(:each) do
|
42
|
+
@logfile = StringIO.new('')
|
43
|
+
Treequel.logger = Logger.new( @logfile )
|
44
|
+
|
45
|
+
@test_class = Class.new do
|
46
|
+
include Treequel::Loggable
|
47
|
+
|
48
|
+
def log_test_message( level, msg )
|
49
|
+
self.log.send( level, msg )
|
50
|
+
end
|
51
|
+
|
52
|
+
def logdebug_test_message( msg )
|
53
|
+
self.log_debug.debug( msg )
|
54
|
+
end
|
55
|
+
end
|
56
|
+
@obj = @test_class.new
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
it "is able to output to the log via its #log method" do
|
61
|
+
@obj.log_test_message( :debug, "debugging message" )
|
62
|
+
@logfile.rewind
|
63
|
+
@logfile.read.should =~ /debugging message/
|
64
|
+
end
|
65
|
+
|
66
|
+
it "is able to output to the log via its #log_debug method" do
|
67
|
+
@obj.logdebug_test_message( "sexydrownwatch" )
|
68
|
+
@logfile.rewind
|
69
|
+
@logfile.read.should =~ /sexydrownwatch/
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#################################################################
|
74
|
+
### E X A M P L E S
|
75
|
+
#################################################################
|
76
|
+
|
77
|
+
describe Treequel::HashUtilities do
|
78
|
+
it "includes a function for stringifying Hash keys" do
|
79
|
+
testhash = {
|
80
|
+
:foo => 1,
|
81
|
+
:bar => {
|
82
|
+
:klang => 'klong',
|
83
|
+
:barang => { :kerklang => 'dumdumdum' },
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
result = Treequel::HashUtilities.stringify_keys( testhash )
|
88
|
+
|
89
|
+
result.should be_an_instance_of( Hash )
|
90
|
+
result.should_not be_equal( testhash )
|
91
|
+
result.should == {
|
92
|
+
'foo' => 1,
|
93
|
+
'bar' => {
|
94
|
+
'klang' => 'klong',
|
95
|
+
'barang' => { 'kerklang' => 'dumdumdum' },
|
96
|
+
}
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
it "includes a function for symbolifying Hash keys" do
|
102
|
+
testhash = {
|
103
|
+
'foo' => 1,
|
104
|
+
'bar' => {
|
105
|
+
'klang' => 'klong',
|
106
|
+
'barang' => { 'kerklang' => 'dumdumdum' },
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
result = Treequel::HashUtilities.symbolify_keys( testhash )
|
111
|
+
|
112
|
+
result.should be_an_instance_of( Hash )
|
113
|
+
result.should_not be_equal( testhash )
|
114
|
+
result.should == {
|
115
|
+
:foo => 1,
|
116
|
+
:bar => {
|
117
|
+
:klang => 'klong',
|
118
|
+
:barang => { :kerklang => 'dumdumdum' },
|
119
|
+
}
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
it "includes a function that can be used as the key-collision callback for " +
|
124
|
+
"Hash#merge that does recursive merging" do
|
125
|
+
hash1 = {
|
126
|
+
:foo => 1,
|
127
|
+
:bar => [:one],
|
128
|
+
:baz => {
|
129
|
+
:glom => [:chunker]
|
130
|
+
}
|
131
|
+
}
|
132
|
+
hash2 = {
|
133
|
+
:klong => 88.8,
|
134
|
+
:bar => [:locke],
|
135
|
+
:baz => {
|
136
|
+
:trim => :liquor,
|
137
|
+
:glom => [:plunker]
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
hash1.merge( hash2, &Treequel::HashUtilities.method(:merge_recursively) ).should == {
|
142
|
+
:foo => 1,
|
143
|
+
:bar => [:one, :locke],
|
144
|
+
:baz => {
|
145
|
+
:glom => [:chunker, :plunker],
|
146
|
+
:trim => :liquor,
|
147
|
+
},
|
148
|
+
:klong => 88.8,
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
describe Treequel::ArrayUtilities do
|
155
|
+
it "includes a function for stringifying Array elements" do
|
156
|
+
testarray = [:a, :b, :c, [:d, :e, [:f, :g]]]
|
157
|
+
|
158
|
+
result = Treequel::ArrayUtilities.stringify_array( testarray )
|
159
|
+
|
160
|
+
result.should be_an_instance_of( Array )
|
161
|
+
result.should_not be_equal( testarray )
|
162
|
+
result.should == ['a', 'b', 'c', ['d', 'e', ['f', 'g']]]
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
it "includes a function for symbolifying Array elements" do
|
167
|
+
testarray = ['a', 'b', 'c', ['d', 'e', ['f', 'g']]]
|
168
|
+
|
169
|
+
result = Treequel::ArrayUtilities.symbolify_array( testarray )
|
170
|
+
|
171
|
+
result.should be_an_instance_of( Array )
|
172
|
+
result.should_not be_equal( testarray )
|
173
|
+
result.should == [:a, :b, :c, [:d, :e, [:f, :g]]]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
describe Treequel::AttributeDeclarations do
|
179
|
+
before( :all ) do
|
180
|
+
setup_logging( :debug )
|
181
|
+
end
|
182
|
+
after( :all ) do
|
183
|
+
reset_logging()
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "predicate attribute declaration" do
|
187
|
+
before( :all ) do
|
188
|
+
@testclass = Class.new do
|
189
|
+
extend Treequel::AttributeDeclarations
|
190
|
+
|
191
|
+
def initialize( val )
|
192
|
+
@testable = val
|
193
|
+
end
|
194
|
+
|
195
|
+
predicate_attr :testable
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
it "creates a plain predicate method" do
|
200
|
+
@testclass.new( true ).should be_testable()
|
201
|
+
@testclass.new( false ).should_not be_testable()
|
202
|
+
@testclass.new( 1 ).should be_testable()
|
203
|
+
@testclass.new( :something_else ).should be_testable()
|
204
|
+
end
|
205
|
+
|
206
|
+
it "creates a mutator" do
|
207
|
+
obj = @testclass.new( true )
|
208
|
+
obj.testable = false
|
209
|
+
obj.should_not be_testable()
|
210
|
+
obj.testable = true
|
211
|
+
obj.should be_testable()
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe Treequel::Delegation do
|
217
|
+
|
218
|
+
before( :all ) do
|
219
|
+
setup_logging( :debug )
|
220
|
+
end
|
221
|
+
after( :all ) do
|
222
|
+
reset_logging()
|
223
|
+
end
|
224
|
+
|
225
|
+
describe "method delegation" do
|
226
|
+
before( :all ) do
|
227
|
+
@testclass = Class.new do
|
228
|
+
extend Treequel::Delegation
|
229
|
+
|
230
|
+
def initialize( obj )
|
231
|
+
@obj = obj
|
232
|
+
end
|
233
|
+
|
234
|
+
def_method_delegators :demand_loaded_object, :delegated_method
|
235
|
+
def_method_delegators :nonexistant_method, :erroring_delegated_method
|
236
|
+
|
237
|
+
def demand_loaded_object
|
238
|
+
return @obj
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
before( :each ) do
|
244
|
+
@subobj = mock( "delegate" )
|
245
|
+
@obj = @testclass.new( @subobj )
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
it "can be used to set up delegation through a method" do
|
250
|
+
@subobj.should_receive( :delegated_method )
|
251
|
+
@obj.delegated_method
|
252
|
+
end
|
253
|
+
|
254
|
+
it "passes any arguments through to the delegate object's method" do
|
255
|
+
@subobj.should_receive( :delegated_method ).with( :arg1, :arg2 )
|
256
|
+
@obj.delegated_method( :arg1, :arg2 )
|
257
|
+
end
|
258
|
+
|
259
|
+
it "reports errors from its caller's perspective" do
|
260
|
+
pending "doesn't work under 1.9, but may not be necessary" if
|
261
|
+
vvec(RUBY_VERSION) > vvec('1.8.7')
|
262
|
+
|
263
|
+
begin
|
264
|
+
@obj.erroring_delegated_method
|
265
|
+
rescue NoMethodError => err
|
266
|
+
err.message.should =~ /nonexistant_method/
|
267
|
+
err.backtrace.first.should =~ /#{__FILE__}/
|
268
|
+
rescue ::Exception => err
|
269
|
+
fail "Expected a NoMethodError, but got a %p (%s)" % [ err.class, err.message ]
|
270
|
+
else
|
271
|
+
fail "Expected a NoMethodError, but no exception was raised."
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
describe "instance variable delegation (ala Forwardable)" do
|
278
|
+
before( :all ) do
|
279
|
+
@testclass = Class.new do
|
280
|
+
extend Treequel::Delegation
|
281
|
+
|
282
|
+
def initialize( obj )
|
283
|
+
@obj = obj
|
284
|
+
end
|
285
|
+
|
286
|
+
def_ivar_delegators :@obj, :delegated_method
|
287
|
+
def_ivar_delegators :@glong, :erroring_delegated_method
|
288
|
+
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
before( :each ) do
|
293
|
+
@subobj = mock( "delegate" )
|
294
|
+
@obj = @testclass.new( @subobj )
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
it "can be used to set up delegation through a method" do
|
299
|
+
@subobj.should_receive( :delegated_method )
|
300
|
+
@obj.delegated_method
|
301
|
+
end
|
302
|
+
|
303
|
+
it "passes any arguments through to the delegate's method" do
|
304
|
+
@subobj.should_receive( :delegated_method ).with( :arg1, :arg2 )
|
305
|
+
@obj.delegated_method( :arg1, :arg2 )
|
306
|
+
end
|
307
|
+
|
308
|
+
it "reports errors from its caller's perspective" do
|
309
|
+
pending "doesn't work under 1.9, but may not be necessary" if
|
310
|
+
vvec(RUBY_VERSION) > vvec('1.8.7')
|
311
|
+
|
312
|
+
begin
|
313
|
+
@obj.erroring_delegated_method
|
314
|
+
rescue NoMethodError => err
|
315
|
+
err.message.should =~ /`erroring_delegated_method' for nil/
|
316
|
+
err.backtrace.first.should =~ /#{__FILE__}/
|
317
|
+
rescue ::Exception => err
|
318
|
+
fail "Expected a NoMethodError, but got a %p (%s)" % [ err.class, err.message ]
|
319
|
+
else
|
320
|
+
fail "Expected a NoMethodError, but no exception was raised."
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
# vim: set nosta noet ts=4 sw=4:
|
@@ -0,0 +1,237 @@
|
|
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/attributetype'
|
21
|
+
rescue LoadError
|
22
|
+
unless Object.const_defined?( :Gem )
|
23
|
+
require 'rubygems'
|
24
|
+
retry
|
25
|
+
end
|
26
|
+
raise
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
include Treequel::TestConstants
|
31
|
+
include Treequel::Constants
|
32
|
+
|
33
|
+
#####################################################################
|
34
|
+
### C O N T E X T S
|
35
|
+
#####################################################################
|
36
|
+
|
37
|
+
describe Treequel::Schema::AttributeType do
|
38
|
+
include Treequel::SpecHelpers
|
39
|
+
|
40
|
+
|
41
|
+
before( :all ) do
|
42
|
+
setup_logging( :fatal )
|
43
|
+
@datadir = Pathname( __FILE__ ).dirname.parent.parent + 'data'
|
44
|
+
end
|
45
|
+
|
46
|
+
before( :each ) do
|
47
|
+
@schema = mock( "treequel schema object" )
|
48
|
+
end
|
49
|
+
|
50
|
+
after( :all ) do
|
51
|
+
reset_logging()
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
describe "parsed from the 'objectClass' attributeType" do
|
56
|
+
|
57
|
+
OBJECTCLASS_ATTRTYPE = %{( 2.5.4.0 NAME 'objectClass' } +
|
58
|
+
%{DESC 'RFC2256: object classes of the entity' } +
|
59
|
+
%{EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )}
|
60
|
+
|
61
|
+
before( :each ) do
|
62
|
+
@attrtype = Treequel::Schema::AttributeType.parse( @schema, OBJECTCLASS_ATTRTYPE )
|
63
|
+
end
|
64
|
+
|
65
|
+
it "knows what OID corresponds to the type" do
|
66
|
+
@attrtype.oid.should == '2.5.4.0'
|
67
|
+
end
|
68
|
+
|
69
|
+
it "knows what its NAME attribute is" do
|
70
|
+
@attrtype.name.should == :objectClass
|
71
|
+
end
|
72
|
+
|
73
|
+
it "knows what its DESC attribute is" do
|
74
|
+
@attrtype.desc.should == 'RFC2256: object classes of the entity'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "knows it doesn't have a superior type" do
|
78
|
+
@attrtype.sup.should be_nil()
|
79
|
+
end
|
80
|
+
|
81
|
+
it "knows what the name of its equality matching rule is" do
|
82
|
+
@attrtype.eqmatch_oid.should == :objectIdentifierMatch
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns a matchingRule object from its schema for its equality matching rule" do
|
86
|
+
@schema.should_receive( :matching_rules ).
|
87
|
+
and_return({ :objectIdentifierMatch => :a_matching_rule })
|
88
|
+
@attrtype.equality_matching_rule.should == :a_matching_rule
|
89
|
+
end
|
90
|
+
|
91
|
+
it "doesn't have an order matchingRule" do
|
92
|
+
@attrtype.ordering_matching_rule.should be_nil()
|
93
|
+
end
|
94
|
+
|
95
|
+
it "returns a matchingRule object from its schema for its substring matching rule" do
|
96
|
+
@attrtype.substr_matching_rule.should be_nil()
|
97
|
+
end
|
98
|
+
|
99
|
+
it "knows that it is not obsolete" do
|
100
|
+
@attrtype.should_not be_obsolete()
|
101
|
+
end
|
102
|
+
|
103
|
+
it "knows what its syntax OID is" do
|
104
|
+
@attrtype.syntax_oid.should == '1.3.6.1.4.1.1466.115.121.1.38'
|
105
|
+
end
|
106
|
+
|
107
|
+
it "knows that its syntax length is not set" do
|
108
|
+
@attrtype.syntax_len.should be_nil()
|
109
|
+
end
|
110
|
+
|
111
|
+
it "returns an ldapSyntax object from its schema for its syntax" do
|
112
|
+
@schema.should_receive( :ldap_syntaxes ).
|
113
|
+
and_return({ '1.3.6.1.4.1.1466.115.121.1.38' => :the_syntax })
|
114
|
+
@attrtype.syntax.should == :the_syntax
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
describe "parsed from an attributeType that has a SUP attribute" do
|
122
|
+
DERIVED_ATTRTYPE = %{( 1.11.2.11.1 SUP aSuperType } +
|
123
|
+
%{SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )}
|
124
|
+
|
125
|
+
before( :each ) do
|
126
|
+
@attrtype = Treequel::Schema::AttributeType.parse( @schema, DERIVED_ATTRTYPE )
|
127
|
+
end
|
128
|
+
|
129
|
+
it "can fetch its superior type from its schema" do
|
130
|
+
@schema.should_receive( :attribute_types ).
|
131
|
+
and_return({ :aSuperType => :the_superior_type })
|
132
|
+
@attrtype.sup.should == :the_superior_type
|
133
|
+
end
|
134
|
+
|
135
|
+
it "returns a matchingRule object from its supertype's equality matching rule if it " +
|
136
|
+
"doesn't have one" do
|
137
|
+
supertype = mock( "superior attribute type object" )
|
138
|
+
@schema.should_receive( :attribute_types ).twice.
|
139
|
+
and_return({ :aSuperType => supertype })
|
140
|
+
supertype.should_receive( :equality_matching_rule ).and_return( :a_matching_rule )
|
141
|
+
|
142
|
+
@attrtype.equality_matching_rule.should == :a_matching_rule
|
143
|
+
end
|
144
|
+
|
145
|
+
it "returns a matchingRule object from its supertype's ordering matching rule if it " +
|
146
|
+
"doesn't have one" do
|
147
|
+
supertype = mock( "superior attribute type object" )
|
148
|
+
@schema.should_receive( :attribute_types ).twice.
|
149
|
+
and_return({ :aSuperType => supertype })
|
150
|
+
supertype.should_receive( :ordering_matching_rule ).and_return( :a_matching_rule )
|
151
|
+
|
152
|
+
@attrtype.ordering_matching_rule.should == :a_matching_rule
|
153
|
+
end
|
154
|
+
|
155
|
+
it "returns a matchingRule object from its supertype's substr matching rule if it " +
|
156
|
+
"doesn't have one" do
|
157
|
+
supertype = mock( "superior attribute type object" )
|
158
|
+
@schema.should_receive( :attribute_types ).twice.
|
159
|
+
and_return({ :aSuperType => supertype })
|
160
|
+
supertype.should_receive( :substr_matching_rule ).and_return( :a_matching_rule )
|
161
|
+
|
162
|
+
@attrtype.substr_matching_rule.should == :a_matching_rule
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
describe "parsed from an attributeType that has a SUP attribute but no SYNTAX" do
|
169
|
+
DERIVED_NOSYN_ATTRTYPE = %{( 1.11.2.11.1 SUP aSuperType )}
|
170
|
+
|
171
|
+
before( :each ) do
|
172
|
+
@attrtype = Treequel::Schema::AttributeType.parse( @schema, DERIVED_NOSYN_ATTRTYPE )
|
173
|
+
end
|
174
|
+
|
175
|
+
it "fetches its SYNTAX from its supertype" do
|
176
|
+
supertype = mock( "supertype object" )
|
177
|
+
@schema.should_receive( :attribute_types ).at_least( :once ).
|
178
|
+
and_return({ :aSuperType => supertype })
|
179
|
+
supertype.should_receive( :syntax ).and_return( :the_syntax )
|
180
|
+
|
181
|
+
@attrtype.syntax.should == :the_syntax
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "parsed from an attributeType that has a list as the value of its NAME attribute" do
|
187
|
+
|
188
|
+
MULTINAME_ATTRIBUTETYPE = %{( 1.1.1.1 NAME ('firstname' 'secondname') )}
|
189
|
+
|
190
|
+
before( :each ) do
|
191
|
+
@attrtype = Treequel::Schema::AttributeType.parse( @schema, MULTINAME_ATTRIBUTETYPE )
|
192
|
+
end
|
193
|
+
|
194
|
+
it "knows what both names are" do
|
195
|
+
@attrtype.names.should have(2).members
|
196
|
+
@attrtype.names.should include( :firstname, :secondname )
|
197
|
+
end
|
198
|
+
|
199
|
+
it "returns the first of its names for the #name method" do
|
200
|
+
@attrtype.name.should == :firstname
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "parsed from an attributeType that has escaped characters in its DESC attribute" do
|
206
|
+
|
207
|
+
ESCAPED_DESC_ATTRIBUTETYPE = %{( 1.1.1.1 DESC } +
|
208
|
+
%{'This spec\\27s example, which includes a \\5c character.' )}
|
209
|
+
|
210
|
+
before( :each ) do
|
211
|
+
@attrtype = Treequel::Schema::AttributeType.parse( @schema, ESCAPED_DESC_ATTRIBUTETYPE )
|
212
|
+
end
|
213
|
+
|
214
|
+
it "unscapes the escaped characters" do
|
215
|
+
@attrtype.desc.should == %{This spec's example, which includes a \\ character.}
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
describe "parsed from an attributeType that has the OBSOLETE attribute" do
|
221
|
+
|
222
|
+
OBSOLETE_ATTRIBUTETYPE = %{( 1.1.1.1 OBSOLETE )}
|
223
|
+
|
224
|
+
before( :each ) do
|
225
|
+
@attrtype = Treequel::Schema::AttributeType.parse( @schema, OBSOLETE_ATTRIBUTETYPE )
|
226
|
+
end
|
227
|
+
|
228
|
+
it "knows that it's obsolete" do
|
229
|
+
@attrtype.should be_obsolete()
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
# vim: set nosta noet ts=4 sw=4:
|