rubysync 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/bin/rubysync +3 -3
  2. data/examples/ims2/connectors/hr_db_connector.rb +3 -5
  3. data/examples/my_ims/connectors/my_csv_connector.rb +10 -0
  4. data/examples/my_ims/connectors/my_db_connector.rb +7 -0
  5. data/examples/my_ims/pipelines/{finance_pipeline.rb → my_pipeline.rb} +9 -9
  6. data/lib/net/ldif.rb +302 -0
  7. data/lib/ruby_sync/connectors/active_record_connector.rb +33 -32
  8. data/lib/ruby_sync/connectors/base_connector.rb +21 -10
  9. data/lib/ruby_sync/connectors/csv_file_connector.rb +17 -22
  10. data/lib/ruby_sync/connectors/file_connector.rb +11 -11
  11. data/lib/ruby_sync/connectors/ldap_connector.rb +206 -53
  12. data/lib/ruby_sync/connectors/memory_connector.rb +5 -8
  13. data/lib/ruby_sync/event.rb +11 -3
  14. data/lib/ruby_sync/operation.rb +1 -1
  15. data/lib/ruby_sync/pipelines/base_pipeline.rb +6 -0
  16. data/lib/ruby_sync/util/utilities.rb +22 -3
  17. data/lib/ruby_sync.rb +25 -2
  18. data/test/data/example1.ldif +20 -0
  19. data/test/data/example2.ldif +14 -0
  20. data/test/data/example3.ldif +13 -0
  21. data/test/data/example4.ldif +55 -0
  22. data/test/data/example5.ldif +12 -0
  23. data/test/data/example6.ldif +62 -0
  24. data/test/data/example7.ldif +8 -0
  25. data/test/test_active_record_vault.rb +3 -4
  26. data/test/test_base_pipeline.rb +58 -0
  27. data/test/test_csv_file_connector.rb +7 -7
  28. data/test/test_ldap_connector.rb +71 -13
  29. data/test/test_ldap_vault.rb +91 -0
  30. data/test/test_ldif.rb +122 -0
  31. data/test/test_utilities.rb +63 -0
  32. metadata +19 -7
  33. data/examples/my_ims/connectors/corp_directory_connector.rb +0 -12
  34. data/examples/my_ims/connectors/finance_connector.rb +0 -7
  35. data/examples/my_ims/connectors/hr_db_connector.rb +0 -7
  36. data/examples/my_ims/pipelines/hr_import_pipeline.rb +0 -29
@@ -0,0 +1,13 @@
1
+ version: 1
2
+ dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com
3
+ objectclass: top
4
+ objectclass: person
5
+ objectclass: organizationalPerson
6
+ cn: Gern Jensen
7
+ cn: Gern O Jensen
8
+ sn: Jensen
9
+ uid: gernj
10
+ telephonenumber: +1 408 555 1212
11
+ description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVlIGlzIGJ
12
+ hc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdGVyIGluIGl0ICh
13
+ hIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQgb3V0IG1vcmUu
@@ -0,0 +1,55 @@
1
+ version: 1
2
+ dn:: b3U95Za25qWt6YOoLG89QWlyaXVz
3
+ # dn:: ou=<JapaneseOU>,o=Airius
4
+ objectclass: top
5
+ objectclass: organizationalUnit
6
+ ou:: 5Za25qWt6YOo
7
+ # ou:: <JapaneseOU>
8
+ ou;lang-ja:: 5Za25qWt6YOo
9
+ # ou;lang-ja:: <JapaneseOU>
10
+ ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
11
+
12
+ # ou;lang-ja:: <JapaneseOU_in_phonetic_representation>
13
+ ou;lang-en: Sales
14
+ description: Japanese office
15
+
16
+ dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz
17
+ # dn:: uid=<uid>,ou=<JapaneseOU>,o=Airius
18
+ userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
19
+ objectclass: top
20
+ objectclass: person
21
+ objectclass: organizationalPerson
22
+ objectclass: inetOrgPerson
23
+ uid: rogasawara
24
+ mail: rogasawara@airius.co.jp
25
+ givenname;lang-ja:: 44Ot44OJ44OL44O8
26
+ # givenname;lang-ja:: <JapaneseGivenname>
27
+ sn;lang-ja:: 5bCP56yg5Y6f
28
+ # sn;lang-ja:: <JapaneseSn>
29
+ cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
30
+ # cn;lang-ja:: <JapaneseCn>
31
+ title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==
32
+ # title;lang-ja:: <JapaneseTitle>
33
+ preferredlanguage: ja
34
+ givenname:: 44Ot44OJ44OL44O8
35
+ # givenname:: <JapaneseGivenname>
36
+ sn:: 5bCP56yg5Y6f
37
+ # sn:: <JapaneseSn>
38
+ cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
39
+ # cn:: <JapaneseCn>
40
+ title:: 5Za25qWt6YOoIOmDqOmVtw==
41
+ # title:: <JapaneseTitle>
42
+ givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8
43
+ # givenname;lang-ja;phonetic::
44
+ <JapaneseGivenname_in_phonetic_representation_kana>
45
+ sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ
46
+ # sn;lang-ja;phonetic:: <JapaneseSn_in_phonetic_representation_kana>
47
+ cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==
48
+ # cn;lang-ja;phonetic:: <JapaneseCn_in_phonetic_representation_kana>
49
+ title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==
50
+ # title;lang-ja;phonetic::
51
+ # <JapaneseTitle_in_phonetic_representation_kana>
52
+ givenname;lang-en: Rodney
53
+ sn;lang-en: Ogasawara
54
+ cn;lang-en: Rodney Ogasawara
55
+ title;lang-en: Sales, Director
@@ -0,0 +1,12 @@
1
+ version: 1
2
+ dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
3
+ objectclass: top
4
+ objectclass: person
5
+ objectclass: organizationalPerson
6
+ cn: Horatio Jensen
7
+
8
+ cn: Horatio N Jensen
9
+ sn: Jensen
10
+ uid: hjensen
11
+ telephonenumber: +1 408 555 1212
12
+ jpegphoto:< file:///usr/local/directory/photos/hjensen.jpg
@@ -0,0 +1,62 @@
1
+ version: 1
2
+ # Add a new entry
3
+ dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
4
+ changetype: add
5
+ objectclass: top
6
+ objectclass: person
7
+ objectclass: organizationalPerson
8
+ cn: Fiona Jensen
9
+ sn: Jensen
10
+ uid: fiona
11
+ telephonenumber: +1 408 555 1212
12
+ jpegphoto:< file:///etc/hosts
13
+
14
+ # Delete an existing entry
15
+ dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com
16
+ changetype: delete
17
+
18
+ # Modify an entry's relative distinguished name
19
+ dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
20
+ changetype: modrdn
21
+ newrdn: cn=Paula Jensen
22
+ deleteoldrdn: 1
23
+
24
+ # Rename an entry and move all of its children to a new location in
25
+ # the directory tree (only implemented by LDAPv3 servers).
26
+ dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
27
+ changetype: modrdn
28
+ newrdn: ou=Product Development Accountants
29
+ deleteoldrdn: 0
30
+ newsuperior: ou=Accounting, dc=airius, dc=com
31
+
32
+ # Modify an entry: add an additional value to the postaladdress
33
+ # attribute, completely delete the description attribute, replace
34
+ # the telephonenumber attribute with two values, and delete a specific
35
+ # value from the facsimiletelephonenumber attribute
36
+ dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
37
+ changetype: modify
38
+ add: postaladdress
39
+ postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
40
+ -
41
+
42
+ delete: description
43
+ -
44
+ replace: telephonenumber
45
+ telephonenumber: +1 408 555 1234
46
+ telephonenumber: +1 408 555 5678
47
+ -
48
+ delete: facsimiletelephonenumber
49
+ facsimiletelephonenumber: +1 408 555 9876
50
+ -
51
+
52
+ # Modify an entry: replace the postaladdress attribute with an empty
53
+ # set of values (which will cause the attribute to be removed), and
54
+ # delete the entire description attribute. Note that the first will
55
+ # always succeed, while the second will only succeed if at least
56
+ # one value for the description attribute is present.
57
+ dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com
58
+ changetype: modify
59
+ replace: postaladdress
60
+ -
61
+ delete: description
62
+ -
@@ -0,0 +1,8 @@
1
+ version: 1
2
+ # Delete an entry. The operation will attach the LDAPv3
3
+ # Tree Delete Control defined in [9]. The criticality
4
+ # field is "true" and the controlValue field is
5
+ # absent, as required by [9].
6
+ dn: ou=Product Development, dc=airius, dc=com
7
+ control: 1.2.840.113556.1.4.805 true
8
+ changetype: delete
@@ -20,11 +20,10 @@ $:.unshift lib_path unless $:.include?(lib_path) || $:.include?(File.expand_path
20
20
  require 'ruby_sync_test'
21
21
 
22
22
  class MyActiveRecordConnector < RubySync::Connectors::ActiveRecordConnector
23
- options(
24
- :model=>:person,
25
- :application=>"#{File.dirname(__FILE__)}/../examples/ar_webapp"
26
- )
23
+ model :person
24
+ application "#{File.dirname(__FILE__)}/../examples/ar_webapp"
27
25
  end
26
+
28
27
  class MyMemoryConnector < RubySync::Connectors::MemoryConnector; end
29
28
 
30
29
  class TestPipeline < RubySync::Pipelines::BasePipeline
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby -w
2
+ #
3
+ # Copyright (c) 2007 Ritchie Young. All rights reserved.
4
+ #
5
+ # This file is part of RubySync.
6
+ #
7
+ # RubySync is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
9
+ #
10
+ # RubySync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
11
+ # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along with RubySync; if not, write to the
14
+ # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
15
+
16
+
17
+ lib_path = File.dirname(__FILE__) + '/../lib'
18
+ $:.unshift lib_path unless $:.include?(lib_path) || $:.include?(File.expand_path(lib_path))
19
+
20
+ require 'ruby_sync'
21
+ require 'test/unit'
22
+
23
+ class ClientConnector < RubySync::Connectors::MemoryConnector
24
+ end
25
+
26
+ class VaultConnector < RubySync::Connectors::MemoryConnector
27
+ end
28
+
29
+ class TestPipeline < RubySync::Pipelines::BasePipeline
30
+
31
+ client :client
32
+ vault :vault
33
+
34
+ allow_in :cn, :givenName, :sn
35
+ allow_out :id, :name
36
+
37
+ # This is experimental at this stage
38
+ # map_vault_to_client :cn => :id,
39
+ # :givenName => calc { :name.split(/\w+/)[0] },
40
+ # :sn => calc { :name.split(/\w+/)[1] }
41
+
42
+ end
43
+
44
+ class TestBasePipeline < Test::Unit::TestCase
45
+
46
+
47
+ def setup
48
+ @pipeline = TestPipeline.new
49
+ @client = @pipeline.client
50
+ @vault = @pipeline.vault
51
+ end
52
+
53
+ def test_mappings
54
+
55
+ end
56
+
57
+
58
+ end
@@ -23,6 +23,10 @@ require 'csv'
23
23
 
24
24
 
25
25
  class TestCsvFileConnector < RubySync::Connectors::CsvFileConnector
26
+ field_names ['id', 'given name', 'last name', 'email']
27
+ path_field 'id'
28
+ in_path File.expand_path("~/rubysync/csv_test/in")
29
+ out_path File.expand_path("~/rubysync/csv_test/out")
26
30
  end
27
31
 
28
32
  class TestMemoryConnector < RubySync::Connectors::MemoryConnector
@@ -30,11 +34,7 @@ end
30
34
 
31
35
 
32
36
  class TestPipeline < RubySync::Pipelines::BasePipeline
33
- client :test_csv_file,
34
- :field_names => ['id', 'given name', 'last name', 'email'],
35
- :path_field => 'id',
36
- :in_path => File.expand_path("~/rubysync/csv_test/in"),
37
- :out_path => File.expand_path("~/rubysync/csv_test/out")
37
+ client :test_csv_file
38
38
 
39
39
  vault :test_memory
40
40
 
@@ -67,9 +67,9 @@ class TestCsvConnector < Test::Unit::TestCase
67
67
  assert_nil @vault["bob"], "Vault already contains bob"
68
68
  @pipeline.run_once
69
69
  assert_not_nil @vault["bob"], "Bob wasn't created in vault"
70
- modded_bob={}; @bob_details.each_pair {|k,v| modded_bob[k]=v.as_array}
70
+ modded_bob={}; @bob_details.each_pair {|k,v| modded_bob[k.to_s]=v.as_array}
71
71
  assert_equal modded_bob, @vault["bob"].reject {|k,v| ['modifier',:association].include? k}
72
72
  @pipeline.run_once
73
73
  end
74
-
74
+
75
75
  end
@@ -23,18 +23,30 @@ require 'ruby_sync/connectors/ldap_connector'
23
23
  require 'ruby_sync/connectors/memory_connector'
24
24
 
25
25
 
26
- class MyLdapConnector < RubySync::Connectors::LdapConnector; end
26
+ class ChangeLogConnector < RubySync::Connectors::LdapConnector
27
+ host '10.1.1.4'
28
+ port 389
29
+ username 'cn=directory manager'
30
+ password 'password'
31
+ changelog_dn 'cn=changelog'
32
+ search_filter "cn=*"
33
+ search_base "ou=people,dc=9to5magic,dc=com,dc=au"
34
+ end
35
+
36
+ class MyLdapConnector < RubySync::Connectors::LdapConnector
37
+ host 'localhost'
38
+ port 10389
39
+ username 'uid=admin,ou=system'
40
+ password 'secret'
41
+ search_filter "cn=*"
42
+ search_base "dc=example,dc=com"
43
+ end
44
+
27
45
  class MyMemoryConnector < RubySync::Connectors::MemoryConnector; end
28
46
 
29
47
  class TestPipeline < RubySync::Pipelines::BasePipeline
30
48
 
31
- client :my_ldap,
32
- :host=>'localhost',
33
- :port=>10389,
34
- :username=>'uid=admin,ou=system',
35
- :password=>'secret',
36
- :search_filter=>"cn=*",
37
- :search_base=>"dc=example,dc=com"
49
+ client :my_ldap
38
50
 
39
51
  vault :my_memory
40
52
 
@@ -73,17 +85,63 @@ class TestLdapConnector < Test::Unit::TestCase
73
85
 
74
86
  def test_ldap_add
75
87
  assert_nil @client[client_path], "#{client_path} already exists on client"
76
- ldap_attr = {
88
+ @client.add client_path, @client.create_operations_for(ldap_attr)
89
+ assert_not_nil @client[client_path], "#{client_path} wasn't created"
90
+ end
91
+
92
+ def test_client_to_vault
93
+ end
94
+
95
+
96
+ # Add various types of record and verifies that the appropriate
97
+ # changelog entries appear.
98
+ # Other activity on the LDAP server may interfere with this test.
99
+ def test_get_changes
100
+ banner "test_get_changes"
101
+ c = ChangeLogConnector.new
102
+ path = "cn=bob,#{c.search_base}"
103
+ c.delete(path) if c[path]
104
+ c.each_change do |event|
105
+ end # Ignore up til now
106
+
107
+
108
+ c.add(path, c.create_operations_for(ldap_attr))
109
+ assert_event :add, c, path
110
+
111
+ c.modify(path, [
112
+ RubySync::Operation.replace('mail', "bob@fischer.com"),
113
+ RubySync::Operation.add('givenName', "Robert")
114
+ ])
115
+ event = assert_event :modify, c, path
116
+ puts event.payload.inspect
117
+
118
+ c.delete(path)
119
+ assert_event :delete, c, path
120
+ end
121
+
122
+ private
123
+
124
+ def ldap_attr
125
+ {
77
126
  "objectclass"=>['inetOrgPerson'],
78
127
  "cn"=>'bob',
79
128
  "sn"=>'roberts',
80
129
  "mail"=>"bob@roberts.com"
81
130
  }
82
- @client.add client_path, @client.create_operations_for(ldap_attr)
83
- assert_not_nil @client[client_path], "#{client_path} wasn't created"
84
131
  end
85
132
 
86
- def test_client_to_vault
133
+ def assert_event type, connector, path
134
+ events = 0
135
+ the_event=nil
136
+ connector.each_change do |event|
137
+ the_event = event
138
+ events += 1
139
+ assert_equal type.to_sym, event.type
140
+ assert_equal connector, event.source
141
+ assert_equal path, event.source_path
142
+ end
143
+ assert_equal 1, events, "wrong number of events on #{type.to_s}"
144
+ the_event
87
145
  end
88
146
 
89
- end
147
+ end
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env ruby -w
2
+ #
3
+ # Copyright (c) 2007 Ritchie Young. All rights reserved.
4
+ #
5
+ # This file is part of RubySync.
6
+ #
7
+ # RubySync is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
9
+ #
10
+ # RubySync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
11
+ # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along with RubySync; if not, write to the
14
+ # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
15
+
16
+
17
+ lib_path = File.dirname(__FILE__) + '/../lib'
18
+ $:.unshift lib_path unless $:.include?(lib_path) || $:.include?(File.expand_path(lib_path))
19
+
20
+ require 'ruby_sync_test'
21
+ require 'hashlike_tests'
22
+ require 'ruby_sync/connectors/ldap_connector'
23
+ require 'ruby_sync/connectors/memory_connector'
24
+
25
+
26
+ class MyLdapConnector < RubySync::Connectors::LdapConnector
27
+ host '10.1.1.4'
28
+ port 389
29
+ username 'cn=directory manager'
30
+ password 'password'
31
+ changelog_dn 'cn=changelog'
32
+ search_filter "cn=*"
33
+ search_base "ou=people,dc=9to5magic,dc=com,dc=au"
34
+
35
+ def initialize options={}
36
+ super(options)
37
+ skip_existing_changelog_entries
38
+ end
39
+
40
+ end
41
+
42
+ class MyMemoryConnector < RubySync::Connectors::MemoryConnector; end
43
+
44
+ class TestPipeline < RubySync::Pipelines::BasePipeline
45
+
46
+ client :my_memory
47
+
48
+ vault :my_ldap
49
+
50
+ allow_out :cn, :givenName, :sn
51
+ allow_in :cn, :givenName, :sn, :objectclass
52
+
53
+ def in_place(event)
54
+ event.target_path = "cn=#{event.source_path},ou=people,dc=9to5magic,dc=com,dc=au"
55
+ end
56
+
57
+ def out_place(event)
58
+ event.target_path =~ /cn=(.+?),/oi
59
+ event.source_path = $1
60
+ end
61
+
62
+ in_transform do
63
+ if type == :add or type == :modify
64
+ each_operation_on("givenName") { |operation| append operation.same_but_on('cn') }
65
+ append RubySync::Operation.new(:add, "objectclass", ['inetOrgPerson', 'organizationalPerson', 'person', 'top', 'RubySyncSynchable'])
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+
72
+ class TestLdapVault < Test::Unit::TestCase
73
+
74
+ include RubySyncTest
75
+ include HashlikeTests
76
+
77
+
78
+ def unsynchable
79
+ ["objectclass", "interests", "cn", "dn", "rubysyncassociation"]
80
+ end
81
+
82
+ def client_path
83
+ 'bob'
84
+ end
85
+
86
+ def vault_path
87
+ 'cn=bob,ou=people,dc=9to5magic,dc=com,dc=au'
88
+ end
89
+
90
+
91
+ end
data/test/test_ldif.rb ADDED
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env ruby -w
2
+ #
3
+ # Copyright (c) 2007 Ritchie Young. All rights reserved.
4
+ #
5
+ # This file is part of RubySync.
6
+ #
7
+ # RubySync is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
9
+ #
10
+ # RubySync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
11
+ # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along with RubySync; if not, write to the
14
+ # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
15
+
16
+
17
+ lib_path = File.dirname(__FILE__) + '/../lib'
18
+ $:.unshift lib_path unless $:.include?(lib_path) || $:.include?(File.expand_path(lib_path))
19
+
20
+ require 'net/ldif'
21
+ require 'test/unit'
22
+
23
+ # TODO: Work out a cross platform method for testing file:// URL imports
24
+ class TestLDIF < Test::Unit::TestCase
25
+
26
+ def setup
27
+ @ldif = Net::LDIF
28
+ end
29
+
30
+ def test_tokenizer
31
+ a = array_for_file "example1.ldif"
32
+ #a.each_index {|i| puts "#{i}\t#{a[i][0]}:#{a[i][1]}"}
33
+ assert_equal ["version", "1"], a[0]
34
+ assert_equal ["dn", "cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com"],a[1]
35
+ assert_equal [nil,nil], a[12], "Blank line didn't yield nil name"
36
+ assert_equal ["telephonenumber", "+1 408 555 1212"], a[19]
37
+
38
+ a = array_for_file "example2.ldif"
39
+ assert_equal ["description", "Babs is a big sailing fan, and travels extensively in search of perfect sailing conditions."],a[11]
40
+ assert_equal ["title", "Product Manager, Rod and Reel Division"],a[12]
41
+ end
42
+
43
+ def test_tokenize_base64
44
+ a = array_for_file "example3.ldif"
45
+ #a.each_index {|i| puts "#{i}\t#{a[i][0]}:#{a[i][1]}"}
46
+ assert_equal ["description", "What a careful reader you are! This value is"+
47
+ " base-64-encoded because it has a control character in it (a CR).\r"+
48
+ " By the way, you should really get out more."], a[10]
49
+ end
50
+
51
+
52
+ def test_tokenize_hyphens
53
+ a = array_for_file "example6.ldif"
54
+ #a.each_index {|i| puts "#{i}\t#{a[i][0]}:#{a[i][1]}"}
55
+ assert_equal ["telephonenumber","+1 408 555 1212"], a[9]
56
+ [30,33,37,40,45,47].each {|i| assert_equal ["-","-"], a[i]}
57
+
58
+ end
59
+
60
+ def test_parse_simple_content
61
+ c = changes_for("example1.ldif")
62
+ assert_equal 2, c.length
63
+ assert_equal 'add', c[0].changetype
64
+ assert_equal 'cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com', c[0].dn
65
+ assert_equal ['top','person','organizationalPerson'], c[0].data['objectclass']
66
+ assert_equal ['Barbara Jensen','Barbara J Jensen','Babs Jensen'], c[0].data['cn']
67
+ assert_equal 'Jensen', c[0].data['sn']
68
+ assert_equal 'A big sailing fan.', c[0].data['description']
69
+
70
+ assert_equal 'add', c[1].changetype
71
+ assert_equal "cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com", c[1].dn
72
+ assert_equal '+1 408 555 1212', c[1].data['telephonenumber']
73
+ end
74
+
75
+ def test_parse_change_records
76
+ c = changes_for("example6.ldif")
77
+ assert_equal 6, c.length
78
+ #puts c.join("\n---\n")
79
+ assert_equal "cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com", c[0].dn
80
+ assert_equal 'add', c[0].changetype
81
+ assert_equal ['top', 'person', 'organizationalPerson'], c[0].data['objectclass']
82
+
83
+ assert_equal "Fiona Jensen", c[0].data['cn']
84
+ assert_equal "+1 408 555 1212", c[0].data['telephonenumber']
85
+
86
+ end
87
+
88
+ private
89
+
90
+ def changes_for(filename)
91
+ content = []
92
+ with_file(filename) do |file|
93
+ @ldif.parse(file) do |record|
94
+ assert_kind_of Net::ChangeRecord, record
95
+ content << record
96
+ end
97
+ end
98
+ content
99
+ end
100
+
101
+
102
+ def array_for_file filename
103
+ array = []
104
+ tokenize_file(filename) {|name, value| array << [name, value]}
105
+ array
106
+ end
107
+
108
+ def tokenize_file filename
109
+ with_file(filename) do |file|
110
+ @ldif.tokenize(file) { |name, value| yield name,value }
111
+ end
112
+ end
113
+
114
+ def with_file(filename)
115
+ File.open(path_for(filename), 'r') {|file| yield file}
116
+ end
117
+
118
+ def path_for filename
119
+ "#{File.dirname(__FILE__)}/data/#{filename}"
120
+ end
121
+
122
+ end
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby -w
2
+ #
3
+ # Copyright (c) 2007 Ritchie Young. All rights reserved.
4
+ #
5
+ # This file is part of RubySync.
6
+ #
7
+ # RubySync is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
8
+ # as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
9
+ #
10
+ # RubySync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
11
+ # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along with RubySync; if not, write to the
14
+ # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
15
+
16
+
17
+ lib_path = File.dirname(__FILE__) + '/../lib'
18
+ $:.unshift lib_path unless $:.include?(lib_path) || $:.include?(File.expand_path(lib_path))
19
+
20
+ require 'ruby_sync'
21
+ require 'test/unit'
22
+
23
+ RIGHT = "this is right"
24
+ WRONG = "this is wrong"
25
+
26
+ class A
27
+ include RubySync::Utilities
28
+
29
+ option :just_one
30
+ option :pet, :just_default, :with_default
31
+ just_default RIGHT
32
+ with_default WRONG
33
+ end
34
+
35
+ class B < A
36
+ pet RIGHT
37
+ with_default RIGHT
38
+ just_one RIGHT
39
+ end
40
+
41
+ class C < A
42
+ pet WRONG
43
+ with_default WRONG
44
+ just_one WRONG
45
+ end
46
+
47
+
48
+ class TestUtilities < Test::Unit::TestCase
49
+
50
+ def test_class_option
51
+ b = B.new
52
+ assert_equal RIGHT, b.pet
53
+ assert_equal RIGHT, b.just_default
54
+ assert_equal RIGHT, b.with_default
55
+ assert_equal RIGHT, b.just_one
56
+ c = C.new
57
+ assert_equal WRONG, c.pet
58
+ assert_equal RIGHT, c.just_default
59
+ assert_equal WRONG, c.with_default
60
+ assert_equal WRONG, c.just_one
61
+ end
62
+
63
+ end