rubysync 0.0.1 → 0.0.2

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