activeldap 1.2.0 → 1.2.1

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 (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