activeldap 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CHANGES +11 -0
  2. data/README +6 -3
  3. data/Rakefile +6 -6
  4. data/examples/al-admin/config/environment.rb +3 -3
  5. data/examples/groupadd +1 -1
  6. data/examples/groupdel +1 -1
  7. data/examples/groupls +1 -1
  8. data/examples/groupmod +1 -1
  9. data/examples/lpasswd +1 -1
  10. data/examples/ouadd +1 -1
  11. data/examples/useradd +1 -1
  12. data/examples/useradd-binary +1 -1
  13. data/examples/userdel +1 -1
  14. data/examples/userls +1 -1
  15. data/examples/usermod +1 -1
  16. data/examples/usermod-binary-add +1 -1
  17. data/examples/usermod-binary-add-time +1 -1
  18. data/examples/usermod-binary-del +1 -1
  19. data/examples/usermod-lang-add +1 -1
  20. data/lib/active_ldap.rb +6 -6
  21. data/lib/active_ldap/adapter/base.rb +14 -1
  22. data/lib/active_ldap/adapter/jndi.rb +5 -1
  23. data/lib/active_ldap/adapter/net_ldap.rb +7 -1
  24. data/lib/active_ldap/association/belongs_to_many.rb +4 -0
  25. data/lib/active_ldap/association/has_many.rb +5 -5
  26. data/lib/active_ldap/association/has_many_utils.rb +5 -6
  27. data/lib/active_ldap/association/has_many_wrap.rb +13 -9
  28. data/lib/active_ldap/association/proxy.rb +5 -1
  29. data/lib/active_ldap/associations.rb +1 -1
  30. data/lib/active_ldap/attributes.rb +7 -3
  31. data/lib/active_ldap/base.rb +16 -2
  32. data/lib/active_ldap/distinguished_name.rb +3 -6
  33. data/lib/active_ldap/operations.rb +11 -8
  34. data/lib/active_ldap/timeout_stub.rb +1 -1
  35. data/lib/active_ldap/xml.rb +5 -2
  36. data/test-unit/History.txt +54 -0
  37. data/test-unit/Manifest.txt +3 -3
  38. data/test-unit/README.txt +4 -1
  39. data/test-unit/images/color-diff.png +0 -0
  40. data/test-unit/lib/test/unit.rb +23 -42
  41. data/test-unit/lib/test/unit/assertionfailederror.rb +11 -0
  42. data/test-unit/lib/test/unit/assertions.rb +77 -8
  43. data/test-unit/lib/test/unit/autorunner.rb +13 -2
  44. data/test-unit/lib/test/unit/collector/load.rb +2 -3
  45. data/test-unit/lib/test/unit/color-scheme.rb +13 -1
  46. data/test-unit/lib/test/unit/diff.rb +223 -37
  47. data/test-unit/lib/test/unit/failure.rb +27 -5
  48. data/test-unit/lib/test/unit/omission.rb +47 -3
  49. data/test-unit/lib/test/unit/testcase.rb +42 -0
  50. data/test-unit/lib/test/unit/ui/console/testrunner.rb +189 -3
  51. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +14 -0
  52. data/test-unit/lib/test/unit/ui/testrunner.rb +8 -0
  53. data/test-unit/lib/test/unit/version.rb +1 -1
  54. data/test-unit/sample/{tc_adder.rb → test_adder.rb} +3 -1
  55. data/test-unit/sample/{tc_subtracter.rb → test_subtracter.rb} +3 -1
  56. data/test-unit/sample/test_user.rb +1 -0
  57. data/test-unit/test/run-test.rb +2 -0
  58. data/test-unit/test/test-color-scheme.rb +7 -0
  59. data/test-unit/test/test-diff.rb +48 -7
  60. data/test-unit/test/test-omission.rb +1 -1
  61. data/test-unit/test/test-testcase.rb +27 -0
  62. data/test-unit/test/test_assertions.rb +43 -10
  63. data/test/al-test-utils.rb +15 -0
  64. data/test/test_associations.rb +46 -1
  65. data/test/test_attributes.rb +43 -20
  66. data/test/test_base.rb +60 -3
  67. metadata +12 -12
  68. data/test-unit/sample/ts_examples.rb +0 -7
@@ -70,7 +70,11 @@ module ActiveLdap
70
70
  end
71
71
 
72
72
  def primary_key
73
- @options[:primary_key_name] || foreign_class.dn_attribute
73
+ @options[:primary_key_name] || @owner.dn_attribute
74
+ end
75
+
76
+ def foreign_key
77
+ @options[:foreign_key_name] || foreign_class.dn_attribute
74
78
  end
75
79
 
76
80
  def load_target
@@ -125,13 +125,13 @@ module ActiveLdap
125
125
  :extend => options[:extend],
126
126
  }
127
127
  if opts[:wrap]
128
- opts[:foreign_key_name] ||= "#{association_id}_id"
129
128
  association_class = Association::HasManyWrap
130
129
  else
131
130
  association_class = Association::HasMany
132
131
  primary_key_name = opts[:primary_key_name]
133
132
  foreign_key_name = opts[:foreign_key_name]
134
133
  if primary_key_name != foreign_key_name and
134
+ primary_key_name != "dn" and
135
135
  !new.have_attribute?(primary_key_name)
136
136
  message = _(":primary_key and :foreign_key has_many options are " \
137
137
  "inverted their mean since 1.1.0. Please invert them.")
@@ -101,8 +101,7 @@ module ActiveLdap
101
101
  if value.is_a?(Hash)
102
102
  suffix, real_value = unnormalize_attribute_options(value)
103
103
  new_name = name + suffix
104
- result[new_name] ||= []
105
- result[new_name].concat(real_value)
104
+ unnormalize_attribute(new_name, real_value, result)
106
105
  else
107
106
  result[name] ||= []
108
107
  if value.is_a?(DN)
@@ -157,7 +156,13 @@ module ActiveLdap
157
156
  needless_attributes[to_real_attribute_name(name)] = true
158
157
  end
159
158
 
159
+ _dn_attribute = nil
160
+ begin
161
+ _dn_attribute = dn_attribute_with_fallback
162
+ rescue DistinguishedNameInvalid
163
+ end
160
164
  targets.collect do |key, value|
165
+ key = _dn_attribute if ["id", "dn"].include?(key.to_s)
161
166
  [to_real_attribute_name(key) || key, value]
162
167
  end.reject do |key, value|
163
168
  needless_attributes[key]
@@ -165,7 +170,6 @@ module ActiveLdap
165
170
  end
166
171
 
167
172
  def attributes_protected_by_default
168
- _dn_attribute = nil
169
173
  begin
170
174
  _dn_attribute = dn_attribute_with_fallback
171
175
  rescue DistinguishedNameInvalid
@@ -780,7 +780,6 @@ module ActiveLdap
780
780
 
781
781
  def dn=(value)
782
782
  set_attribute(dn_attribute_with_fallback, value)
783
- @dn = nil
784
783
  end
785
784
  alias_method(:id=, :dn=)
786
785
 
@@ -902,7 +901,8 @@ module ActiveLdap
902
901
  # This returns the key value pairs in @data with all values
903
902
  # cloned
904
903
  def attributes
905
- @data.clone
904
+ @simplified_data ||= simplify_data(@data)
905
+ @simplified_data.clone
906
906
  end
907
907
 
908
908
  # This allows a bulk update to the attributes of a record
@@ -1276,6 +1276,7 @@ module ActiveLdap
1276
1276
  raise UnknownAttribute.new(name) if real_name.nil?
1277
1277
 
1278
1278
  @data[real_name] = value
1279
+ @simplified_data = nil
1279
1280
  end
1280
1281
 
1281
1282
  def register_new_dn_attribute(name, value)
@@ -1443,6 +1444,19 @@ module ActiveLdap
1443
1444
  result
1444
1445
  end
1445
1446
 
1447
+ def simplify_data(data)
1448
+ _schema = schema
1449
+ result = {}
1450
+ data.each do |key, values|
1451
+ attribute = _schema.attribute(key)
1452
+ if attribute.single_value? and values.is_a?(Array) and values.size == 1
1453
+ values = values[0]
1454
+ end
1455
+ result[key] = type_cast(attribute, values)
1456
+ end
1457
+ result
1458
+ end
1459
+
1446
1460
  def collect_modified_attributes(ldap_data, data)
1447
1461
  klass = self.class
1448
1462
  _dn_attribute = dn_attribute
@@ -246,21 +246,18 @@ module ActiveLdap
246
246
  normalize(@rdns).to_s.hash
247
247
  end
248
248
 
249
- def inspect
250
- super
251
- end
252
-
253
249
  def to_s
250
+ klass = self.class
254
251
  @rdns.collect do |rdn|
255
252
  rdn.sort_by do |type, value|
256
253
  type.upcase
257
254
  end.collect do |type, value|
258
- "#{type}=#{self.class.escape_value(value)}"
255
+ "#{type}=#{klass.escape_value(value)}"
259
256
  end.join("+")
260
257
  end.join(",")
261
258
  end
262
259
 
263
- def to_str
260
+ def to_str # for backward compatibility
264
261
  to_s
265
262
  end
266
263
 
@@ -129,18 +129,21 @@ module ActiveLdap
129
129
  def truncate_base(target)
130
130
  return nil if target.blank?
131
131
  return target if base.nil?
132
- if /,/ =~ target
132
+
133
+ parsed_target = nil
134
+ if target.is_a?(DN)
135
+ parsed_target = target
136
+ elsif /,/ =~ target
133
137
  begin
134
138
  parsed_target = DN.parse(target)
135
- begin
136
- (parsed_target - base).to_s
137
- rescue ArgumentError
138
- target
139
- end
140
139
  rescue DistinguishedNameInvalid
141
- target
142
140
  end
143
- else
141
+ end
142
+
143
+ return target if parsed_target.nil?
144
+ begin
145
+ (parsed_target - base).to_s
146
+ rescue ArgumentError
144
147
  target
145
148
  end
146
149
  end
@@ -3,7 +3,7 @@ require 'timeout'
3
3
  module Timeout
4
4
  # STUB
5
5
  def Timeout.alarm(sec, exception=Timeout::Error, &block)
6
- return block.call
6
+ timeout(sec, exception, &block)
7
7
  end
8
8
  end # Timeout
9
9
 
@@ -57,14 +57,17 @@ module ActiveLdap
57
57
 
58
58
  def normalize_value(value, options=[])
59
59
  targets = []
60
- if value.is_a?(Hash)
60
+ case value
61
+ when Hash
61
62
  value.each do |real_option, real_value|
62
63
  targets.concat(normalize_value(real_value, options + [real_option]))
63
64
  end
64
- elsif value.is_a?(Array)
65
+ when Array
65
66
  value.each do |real_value|
66
67
  targets.concat(normalize_value(real_value, options))
67
68
  end
69
+ when DN
70
+ targets.concat(normalize_value(value.to_s, options))
68
71
  else
69
72
  if /\A#{PRINTABLE_STRING}\z/ !~ value
70
73
  value = [value].pack("m").gsub(/\n/u, '')
@@ -1,3 +1,57 @@
1
+ === 2.0.6 / 20XX-XX-XX
2
+
3
+ * X major enhancements
4
+ * [#27380] Declarative syntax? [Daniel Berger]
5
+ support declarative syntax:
6
+
7
+ test "test description in natural language" do
8
+ ...
9
+ end
10
+ * support test description:
11
+ description "test description in natural language"
12
+ def test_my_test
13
+ ...
14
+ end
15
+
16
+ * X bug fixes
17
+ * [#27374] omit_if unexpected behavior [David MARCHALAND]
18
+ * fix a bug that tests in sub directories aren't load with --basedir.
19
+ [Daniel Berger]
20
+
21
+ * Thanks
22
+ * David MARCHALAND
23
+ * Daniel Berger
24
+
25
+ === 2.0.5 / 2009-10-18
26
+
27
+ * 1 bug fixes
28
+ * [#27314] fix diff may raise an exception. [Erik Hollensbe]
29
+
30
+ * Thanks
31
+ * Erik Hollensbe
32
+
33
+ === 2.0.4 / 2009-10-17
34
+
35
+ * 4 major enhancements
36
+ * use ~/.test-unit.yml as global configuration file.
37
+ * add TAP runner. (--runner tap)
38
+ * support colorized diff:
39
+ http://test-unit.rubyforge.org/svn/trunk/images/color-diff.png
40
+ * add Test::Unit::AutoRunner.default_runner= to specify default test runner.
41
+
42
+ * 4 minor enhancements
43
+ * improve verbose mode output format. (use indent)
44
+ * support NOT_PASS_THROUGH_EXCEPTIONS.
45
+ * support arguments option in #{runner}_options.
46
+ * TC_ -> Test in sample test case name.
47
+
48
+ * 1 bug fixes
49
+ * [#27195] test-unit-2.0.3 + ruby-1.9.1 cannot properly test
50
+ DelegateClass subclasses [Mike Pomraning]
51
+
52
+ * Thanks
53
+ * Mike Pomraning
54
+
1
55
  === 2.0.3 / 2009-07-19
2
56
 
3
57
  * 6 major enhancements
@@ -8,6 +8,7 @@ html/classic.html
8
8
  html/index.html
9
9
  html/index.html.ja
10
10
  html/test-unit-classic.png
11
+ images/color-diff.png
11
12
  lib/test/unit.rb
12
13
  lib/test/unit/assertionfailederror.rb
13
14
  lib/test/unit/assertions.rb
@@ -49,10 +50,9 @@ lib/test/unit/util/procwrapper.rb
49
50
  lib/test/unit/version.rb
50
51
  sample/adder.rb
51
52
  sample/subtracter.rb
52
- sample/tc_adder.rb
53
- sample/tc_subtracter.rb
53
+ sample/test_adder.rb
54
+ sample/test_subtracter.rb
54
55
  sample/test_user.rb
55
- sample/ts_examples.rb
56
56
  test/collector/test-descendant.rb
57
57
  test/collector/test-load.rb
58
58
  test/collector/test_dir.rb
data/test-unit/README.txt CHANGED
@@ -46,7 +46,10 @@ This software is distributed under the same terms as ruby.
46
46
 
47
47
  * Daniel Berger: Suggestions and bug reports.
48
48
  * Designing Patterns: Suggestions.
49
- * Erik Hollensbe: Suggestions.
49
+ * Erik Hollensbe: Suggestions and bug reports.
50
50
  * Bill Lear: A suggestion.
51
51
  * Diego Pettenò: A bug report.
52
52
  * Angelo Lakra: A bug report.
53
+ * Mike Pomraning: A bug report.
54
+ * David MARCHALAND: A bug report.
55
+ * Andrew Grimm: A bug report.
Binary file
@@ -179,7 +179,7 @@ module Test # :nodoc:
179
179
  #
180
180
  # require 'test/unit'
181
181
  #
182
- # class TC_MyTest < Test::Unit::TestCase
182
+ # class MyTest < Test::Unit::TestCase
183
183
  # # def setup
184
184
  # # end
185
185
  #
@@ -194,21 +194,17 @@ module Test # :nodoc:
194
194
  #
195
195
  # == Test Runners
196
196
  #
197
- # So, now you have this great test class, but you still need a way to
198
- # run it and view any failures that occur during the run. This is
199
- # where Test::Unit::UI::Console::TestRunner (and others, such as
200
- # Test::Unit::UI::GTK::TestRunner) comes into play. The console test
201
- # runner is automatically invoked for you if you require 'test/unit'
202
- # and simply run the file. To use another runner, or to manually
203
- # invoke a runner, simply call its run class method and pass in an
204
- # object that responds to the suite message with a
205
- # Test::Unit::TestSuite. This can be as simple as passing in your
206
- # TestCase class (which has a class suite method). It might look
207
- # something like this:
208
- #
209
- # require 'test/unit/ui/console/testrunner'
210
- # Test::Unit::UI::Console::TestRunner.run(TC_MyTest)
197
+ # So, now you have this great test class, but you still
198
+ # need a way to run it and view any failures that occur
199
+ # during the run. There are some test runner; console test
200
+ # runner, GTK+ test runner and so on. The console test
201
+ # runner is automatically invoked for you if you require
202
+ # 'test/unit' and simply run the file. To use another
203
+ # runner simply set default test runner ID to
204
+ # Test::Unit::AutoRunner:
211
205
  #
206
+ # require 'test/unit'
207
+ # Test::Unit::AutoRunner.default_runner = "gtk2"
212
208
  #
213
209
  # == Test Suite
214
210
  #
@@ -220,33 +216,17 @@ module Test # :nodoc:
220
216
  # in response to a suite method. The TestSuite can, in turn, contain
221
217
  # other TestSuites or individual tests (typically created by a
222
218
  # TestCase). In other words, you can easily wrap up a group of
223
- # TestCases and TestSuites like this:
224
- #
225
- # require 'test/unit/testsuite'
226
- # require 'tc_myfirsttests'
227
- # require 'tc_moretestsbyme'
228
- # require 'ts_anothersetoftests'
229
- #
230
- # class TS_MyTests
231
- # def self.suite
232
- # suite = Test::Unit::TestSuite.new
233
- # suite << TC_MyFirstTests.suite
234
- # suite << TC_MoreTestsByMe.suite
235
- # suite << TS_AnotherSetOfTests.suite
236
- # return suite
237
- # end
238
- # end
239
- # Test::Unit::UI::Console::TestRunner.run(TS_MyTests)
240
- #
241
- # Now, this is a bit cumbersome, so Test::Unit does a little bit more
242
- # for you, by wrapping these up automatically when you require
243
- # 'test/unit'. What does this mean? It means you could write the above
244
- # test case like this instead:
219
+ # TestCases and TestSuites.
220
+ #
221
+ # Test::Unit does a little bit more for you, by wrapping
222
+ # these up automatically when you require
223
+ # 'test/unit'. What does this mean? It means you could
224
+ # write the above test case like this instead:
245
225
  #
246
226
  # require 'test/unit'
247
- # require 'tc_myfirsttests'
248
- # require 'tc_moretestsbyme'
249
- # require 'ts_anothersetoftests'
227
+ # require 'test_myfirsttests'
228
+ # require 'test_moretestsbyme'
229
+ # require 'test_anothersetoftests'
250
230
  #
251
231
  # Test::Unit is smart enough to find all the test cases existing in
252
232
  # the ObjectSpace and wrap them up into a suite for you. It then runs
@@ -323,12 +303,13 @@ module Test # :nodoc:
323
303
  #
324
304
 
325
305
  module Unit
326
- # If set to false Test::Unit will not automatically run at exit.
306
+ # Set true when Test::Unit has run. If set to true Test::Unit
307
+ # will not automatically run at exit.
327
308
  def self.run=(flag)
328
309
  @run = flag
329
310
  end
330
311
 
331
- # Automatically run tests at exit?
312
+ # Already tests have run?
332
313
  def self.run?
333
314
  @run ||= false
334
315
  end
@@ -9,6 +9,17 @@ module Test
9
9
 
10
10
  # Thrown by Test::Unit::Assertions when an assertion fails.
11
11
  class AssertionFailedError < StandardError
12
+ attr_accessor :expected, :actual, :user_message
13
+ attr_accessor :inspected_expected, :inspected_actual
14
+ def initialize(message=nil, options=nil)
15
+ options ||= {}
16
+ @expected = options[:expected]
17
+ @actual = options[:actual]
18
+ @inspected_expected = options[:inspected_expected]
19
+ @inspected_actual = options[:inspected_actual]
20
+ @user_message = options[:user_message]
21
+ super(message)
22
+ end
12
23
  end
13
24
  end
14
25
  end
@@ -84,7 +84,16 @@ module Test
84
84
  <?> expected but was
85
85
  <?>.?
86
86
  EOT
87
- assert_block(full_message) { expected == actual }
87
+ begin
88
+ assert_block(full_message) { expected == actual }
89
+ rescue AssertionFailedError => failure
90
+ failure.expected = expected
91
+ failure.actual = actual
92
+ failure.inspected_expected = AssertionMessage.convert(expected)
93
+ failure.inspected_actual = AssertionMessage.convert(actual)
94
+ failure.user_message = message
95
+ raise
96
+ end
88
97
  end
89
98
 
90
99
  ##
@@ -789,6 +798,54 @@ EOT
789
798
  end
790
799
  end
791
800
 
801
+ ##
802
+ # Passes if +object+#+alias_name+ is an alias method of
803
+ # +object+#+original_name+.
804
+ #
805
+ # Example:
806
+ # assert_alias_method([], :length, :size) # -> pass
807
+ # assert_alias_method([], :size, :length) # -> pass
808
+ # assert_alias_method([], :each, :size) # -> fail
809
+ def assert_alias_method(object, alias_name, original_name, message=nil)
810
+ _wrap_assertion do
811
+ find_method_failure_message = Proc.new do |method_name|
812
+ build_message(message,
813
+ "<?>.? doesn't exist\n" +
814
+ "(Class: <?>)",
815
+ object,
816
+ AssertionMessage.literal(method_name),
817
+ object.class)
818
+ end
819
+
820
+ alias_method = original_method = nil
821
+ assert_block(find_method_failure_message.call(alias_name)) do
822
+ begin
823
+ alias_method = object.method(alias_name)
824
+ true
825
+ rescue NameError
826
+ false
827
+ end
828
+ end
829
+ assert_block(find_method_failure_message.call(original_name)) do
830
+ begin
831
+ original_method = object.method(original_name)
832
+ true
833
+ rescue NameError
834
+ false
835
+ end
836
+ end
837
+
838
+ full_message = build_message(message,
839
+ "<?> is alias of\n" +
840
+ "<?> expected",
841
+ alias_method,
842
+ original_method)
843
+ assert_block(full_message) do
844
+ alias_method == original_method
845
+ end
846
+ end
847
+ end
848
+
792
849
  ##
793
850
  # Builds a failure message. +head+ is added before the +template+ and
794
851
  # +arguments+ replaces the '?'s positionally in the template.
@@ -889,15 +946,24 @@ EOT
889
946
  end
890
947
  end
891
948
 
949
+ def prepare_for_diff(from, to)
950
+ if !from.is_a?(String) or !to.is_a?(String)
951
+ from = convert(from)
952
+ to = convert(to)
953
+ end
954
+
955
+ if diff_target_string?(from) and diff_target_string?(to)
956
+ [from, to]
957
+ else
958
+ [nil, nil]
959
+ end
960
+ end
961
+
892
962
  def delayed_diff(from, to)
893
963
  delayed_literal do
894
- if !from.is_a?(String) or !to.is_a?(String)
895
- from = convert(from)
896
- to = convert(to)
897
- end
964
+ from, to = prepare_for_diff(from, to)
898
965
 
899
- diff = nil
900
- diff = "" if !diff_target_string?(from) or !diff_target_string?(to)
966
+ diff = "" if from.nil? or to.nil?
901
967
  diff ||= Diff.readable(from, to)
902
968
  if /^[-+]/ !~ diff
903
969
  diff = ""
@@ -930,7 +996,10 @@ EOM
930
996
  if use_pp
931
997
  begin
932
998
  require 'pp' unless defined?(PP)
933
- return PP.pp(object, '').chomp
999
+ begin
1000
+ return PP.pp(object, '').chomp
1001
+ rescue NameError
1002
+ end
934
1003
  rescue LoadError
935
1004
  self.use_pp = false
936
1005
  end