cpr_adressematch 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +17 -0
  3. data/Rakefile +65 -0
  4. data/VERSION +1 -0
  5. data/lib/cpr/adressematch/req1100.rb +29 -0
  6. data/lib/cpr/adressematch/req1200.rb +20 -0
  7. data/lib/cpr/adressematch/req1300.rb +13 -0
  8. data/lib/cpr/adressematch/req1400.rb +14 -0
  9. data/lib/cpr/adressematch/resp000.rb +12 -0
  10. data/lib/cpr/adressematch/resp001.rb +33 -0
  11. data/lib/cpr/adressematch/resp001a.rb +10 -0
  12. data/lib/cpr/adressematch/resp002.rb +17 -0
  13. data/lib/cpr/adressematch/resp003.rb +17 -0
  14. data/lib/cpr/adressematch/resp004.rb +13 -0
  15. data/lib/cpr/adressematch/resp005.rb +18 -0
  16. data/lib/cpr/adressematch/resp010.rb +11 -0
  17. data/lib/cpr/adressematch/resp011.rb +16 -0
  18. data/lib/cpr/adressematch/resp012.rb +12 -0
  19. data/lib/cpr/adressematch/resp013.rb +15 -0
  20. data/lib/cpr/adressematch/resp901.rb +17 -0
  21. data/lib/cpr/adressematch/resp902.rb +27 -0
  22. data/lib/cpr/adressematch/resp903.rb +12 -0
  23. data/lib/cpr/adressematch/resp910.rb +12 -0
  24. data/lib/cpr/adressematch/resp998.rb +16 -0
  25. data/lib/cpr/adressematch/resp999.rb +10 -0
  26. data/lib/cpr/alphanumeric_field.rb +13 -0
  27. data/lib/cpr/class_generator.rb +90 -0
  28. data/lib/cpr/field.rb +50 -0
  29. data/lib/cpr/kunderefnr.rb +42 -0
  30. data/lib/cpr/numeric_field.rb +19 -0
  31. data/lib/cpr/req_document.rb +14 -0
  32. data/lib/cpr/resp_document.rb +34 -0
  33. data/lib/cpr/row.rb +103 -0
  34. data/lib/cpr_adressematch.rb +10 -0
  35. data/test/helper.rb +9 -0
  36. data/test/test_cpr_adressematch.rb +7 -0
  37. data/test/test_cpr_adressematch_resp001.rb +39 -0
  38. data/test/test_cpr_alphanumeric_field.rb +38 -0
  39. data/test/test_cpr_field.rb +18 -0
  40. data/test/test_cpr_numeric_field.rb +28 -0
  41. data/test/test_cpr_req_document.rb +13 -0
  42. data/test/test_cpr_resp_document.rb +28 -0
  43. data/test/test_cpr_row.rb +67 -0
  44. metadata +115 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Anders Johannsen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = cpr_adressematch
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Anders Johannsen. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,65 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cpr_adressematch"
8
+ gem.summary = %Q{Interface for generating and parsing the Danish CPR Registry data files}
9
+ gem.description = %Q{Interface for generating and parsing the Danish CPR Registry data files.
10
+ Support the 'adressematch' protocol, which can be used to query by name and adress as well as
11
+ by the personal identifical number (CPR)
12
+ }
13
+ gem.email = "anders@johannsen.com"
14
+ gem.homepage = "http://github.com/andersjo/cpr_adressematch"
15
+ gem.authors = ["Anders Johannsen"]
16
+ gem.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/test_*.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/test_*.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ desc "Generate classes from XML definition"
45
+ task :generate do
46
+ $: << "./lib"
47
+ require 'cpr_adressematch'
48
+ require 'cpr/class_generator'
49
+ g = Cpr::ClassGenerator.new("adressematch", "data/adressematch.xml")
50
+ g.generate
51
+ end
52
+
53
+ task :test => :check_dependencies
54
+
55
+ task :default => :test
56
+
57
+ require 'rake/rdoctask'
58
+ Rake::RDocTask.new do |rdoc|
59
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
60
+
61
+ rdoc.rdoc_dir = 'rdoc'
62
+ rdoc.title = "cpr_adressematch #{version}"
63
+ rdoc.rdoc_files.include('README*')
64
+ rdoc.rdoc_files.include('lib/**/*.rb')
65
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Req1100 < Cpr::Row
4
+ title 'Match tilgangs og engangstransaktion (1100)'
5
+
6
+ field 'Inddatatyp', 'A', 0..1, :default => '10'
7
+ field 'Kundenr', 'N', 2..5
8
+ field 'Kunderefnr', 'A', 6..20
9
+ field 'Sortbyte', 'A', 21..21, :default => '4'
10
+ field 'Matchtyp', 'A', 22..22
11
+ field 'Pnrsenrmrk', 'A', 23..23, :default => 'P'
12
+ field 'Matchnvn', 'A', 24..73
13
+ field 'Suplnvn', 'A', 74..123
14
+ field 'Formelnvn', 'A', 124..173
15
+ field 'Efternvn', 'A', 174..213
16
+ field 'Komkod', 'N', 214..217
17
+ field 'Postnr', 'N', 218..221
18
+ field 'Vejkod', 'N', 222..225
19
+ field 'Vejnvn', 'A', 226..265
20
+ field 'Klaradr', 'A', 266..333
21
+ field 'Husnummer', 'A', 334..336
22
+ field 'Husbogstav', 'A', 337..337
23
+ field 'Etage', 'A', 338..339
24
+ field 'Sidedoer', 'A', 340..343
25
+ field 'Bynvn', 'A', 344..377
26
+ field 'Koen', 'A', 378..378
27
+ field 'Foeddto', 'N', 379..386
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Req1200 < Cpr::Row
4
+ title 'Vejtransaktion (1200)'
5
+
6
+ field 'Inddatatyp', 'A', 0..1, :default => '10'
7
+ field 'Kundenr', 'N', 2..5
8
+ field 'Kunderefnr', 'A', 6..20
9
+ field 'Sortbyte', 'A', 21..21, :default => '4'
10
+ field 'Matchtyp', 'A', 22..22
11
+ field 'Postnr', 'N', 23..26
12
+ field 'Vejnvn', 'A', 27..66
13
+ field 'Klaradr', 'A', 67..134
14
+ field 'Husnummer', 'A', 135..137
15
+ field 'Husbogstav', 'A', 138..138
16
+ field 'Etage', 'A', 139..140
17
+ field 'Sidedoer', 'A', 141..144
18
+ field 'Bynvn', 'A', 145..178
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Req1300 < Cpr::Row
4
+ title 'Rekvisitioner og slettetransaktioner til abonnement (1300)'
5
+
6
+ field 'Inddatatyp', 'A', 0..1, :default => '10'
7
+ field 'Kundenr', 'N', 2..5
8
+ field 'Kunderefnr', 'A', 6..20
9
+ field 'Sortbyte', 'A', 21..21
10
+ field 'Matchtyp', 'A', 22..22
11
+ field 'Pnrsenrmrk', 'A', 23..23
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Req1400 < Cpr::Row
4
+ title 'Ændringstransaktioner til abonnement (1400)'
5
+
6
+ field 'Inddatatyp', 'A', 0..1, :default => '10'
7
+ field 'Kundenr', 'N', 2..5
8
+ field 'Kunderefnr', 'A', 6..20
9
+ field 'Sortbyte', 'A', 21..21, :default => '2'
10
+ field 'Matchtyp', 'A', 22..22
11
+ field 'Pnrsenrmrk', 'A', 23..23
12
+ field 'Kunderefnrgl', 'A', 24..38
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp000 < Cpr::Row
4
+ title 'Startrecord (000)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '0'
7
+ field 'Sortfelt', 'A', 3..25
8
+ field 'Opgavenr', 'N', 26..31
9
+ field 'Proddto', 'N', 32..39
10
+ field 'Proddtoforrig', 'N', 40..47
11
+ end
12
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp001 < Cpr::Row
4
+ title 'Aktuelle data (001)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '1'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Matchtyp', 'A', 27..27
11
+ field 'Statushaenstart', 'N', 28..39
12
+ field 'Status', 'N', 40..41
13
+ field 'Nvnadrbeskhaenstart', 'N', 42..53
14
+ field 'Adrnvn', 'A', 54..87
15
+ field 'Tilflydto', 'N', 88..99
16
+ field 'Convn', 'A', 100..133
17
+ field 'Lokalitet', 'A', 134..167
18
+ field 'Standardadr', 'A', 168..201
19
+ field 'Bynvn', 'A', 202..235
20
+ field 'Postnr', 'N', 236..239
21
+ field 'Postdisttxt', 'A', 240..259
22
+ field 'Komkod', 'N', 260..263
23
+ field 'Vejkod', 'N', 264..267
24
+ field 'Husnr', 'A', 268..271
25
+ field 'Etage', 'A', 272..273
26
+ field 'Sidedoer', 'A', 274..277
27
+ field 'BNR', 'A', 278..281
28
+ field 'Formelnvn', 'A', 282..331
29
+ field 'Efternvn', 'A', 332..371
30
+ field 'Vejadrnvn', 'A', 372..391
31
+ field 'Rekbeskhaenstart', 'N', 392..403
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp001A < Cpr::Row
4
+ title 'Aktuelle data for reklamebeskyttelsesudtræk (001A)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '1'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Rekmrk', 'N', 18..18
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp002 < Cpr::Row
4
+ title 'Udlandsadresse (for udrejste personer) (002)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '2'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Udlandadr1', 'A', 27..60
11
+ field 'Udlandadr2', 'A', 61..94
12
+ field 'Udlandadr3', 'A', 95..128
13
+ field 'Udlandadr4', 'A', 129..162
14
+ field 'Udlandadr5', 'A', 163..196
15
+ field 'Udlandadrdto', 'N', 197..208
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp003 < Cpr::Row
4
+ title 'Kontaktadresse (kontaktperson ved udrejse/forsvinding/død) (003)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '3'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Kontaktadr1', 'A', 27..60
11
+ field 'Kontaktadr2', 'A', 61..94
12
+ field 'Kontaktadr3', 'A', 95..128
13
+ field 'Kontaktadr4', 'A', 129..162
14
+ field 'Kontaktadr5', 'A', 163..196
15
+ field 'Kontaktadrdato', 'N', 197..208
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp004 < Cpr::Row
4
+ title 'Civilstand (004)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '4'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Civst', 'A', 27..27
11
+ field 'Haenstart-ctciv', 'N', 28..39
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp005 < Cpr::Row
4
+ title 'Værgemål (005)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '5'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Umynmyn haenstart', 'N', 27..38
11
+ field 'Værgeadrnvn/adressat', 'A', 39..72
12
+ field 'Værgeadressetxt-linie1', 'A', 73..106
13
+ field 'Værgeadressetxt-linie2', 'A', 107..140
14
+ field 'Værgeadressetxt-linie3', 'A', 141..174
15
+ field 'Værgeadressetxt-linie4', 'A', 175..208
16
+ field 'Værgeadressetxt-linie5', 'A', 209..242
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp010 < Cpr::Row
4
+ title 'Kvittering for sletning (010)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '10'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp011 < Cpr::Row
4
+ title 'Andre kundereferencenumre (011)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '11'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Kunderefnrandet-1', 'A', 27..41
11
+ field 'Kunderefnrandet-2', 'A', 42..56
12
+ field 'Kunderefnrandet-3', 'A', 57..71
13
+ field 'Kunderefnrandet-4', 'A', 72..86
14
+ field 'Kunderefnrandet-5', 'A', 87..101
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp012 < Cpr::Row
4
+ title 'Personnummer abonnement (012)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '12'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Pnr', 'A', 27..36
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp013 < Cpr::Row
4
+ title 'Personnummer oplysninger (013)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '12'
7
+ field 'Kunderefnr', 'A', 3..17
8
+ field 'Proddto', 'N', 18..25
9
+ field 'Pnrsenrmrk', 'A', 26..26
10
+ field 'Pnr', 'A', 27..36
11
+ field 'Foeddto', 'N', 37..44
12
+ field 'Koen', 'A', 45..45
13
+ field 'Pnrgaeld', 'A', 46..55
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp901 < Cpr::Row
4
+ title 'Fejlmeddelelser fra Adressematch (901)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '901'
7
+ field 'Sort-high-value', 'A', 3..7
8
+ field 'Sort-proddto', 'N', 8..15
9
+ field 'Sort-medtyp', 'A', 16..25
10
+ field 'Indvnr', 'N', 26..29
11
+ field 'Kundenr', 'N', 30..33
12
+ field 'Kunderefnr', 'A', 34..48
13
+ field 'Matchtyp', 'A', 49..49
14
+ field 'Fejlnr', 'N', 50..53
15
+ field 'Fejlfelt', 'A', 54..105
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp902 < Cpr::Row
4
+ title 'Veje fra Adressematch (902)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '902'
7
+ field 'Sort-high-value', 'A', 3..7
8
+ field 'Sort-proddto', 'N', 8..15
9
+ field 'Sort-medtyp', 'A', 16..25
10
+ field 'Indvnr', 'N', 26..29
11
+ field 'Kundenr', 'N', 30..33
12
+ field 'Kunderefnr', 'A', 34..48
13
+ field 'Matchtyp', 'A', 49..49
14
+ field 'Komkod', 'N', 50..53
15
+ field 'Vejkod', 'N', 54..57
16
+ field 'Postnr', 'N', 58..61
17
+ field 'Postdisttxt', 'A', 62..81
18
+ field 'Vejadrnvn', 'A', 82..101
19
+ field 'Husnr', 'A', 102..105
20
+ field 'Etage', 'A', 106..107
21
+ field 'Sidedoer', 'A', 108..111
22
+ field 'BNR', 'A', 112..115
23
+ field 'Lokalitet', 'A', 116..149
24
+ field 'Standardadr', 'A', 150..183
25
+ field 'Bynvn', 'A', 184..217
26
+ end
27
+ end
@@ -0,0 +1,12 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp903 < Cpr::Row
4
+ title 'Optællinger fra Adressematch (903)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '903'
7
+ field 'Sort-high-value', 'A', 3..7
8
+ field 'Sort-proddto', 'N', 8..15
9
+ field 'Sort-medtyp', 'A', 16..25
10
+ field 'Kundeliste', 'A', 26..130
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp910 < Cpr::Row
4
+ title 'Fejlmeddelelser vedr. PNR-abonnementer (910)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '910'
7
+ field 'Sortfelt-10', 'A', 3..12
8
+ field 'Inddata', 'A', 13..87
9
+ field 'Fejlnr', 'N', 88..91
10
+ field 'Fejltxt-udtræk', 'A', 92..156
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp998 < Cpr::Row
4
+ title 'Nøgletal fra Adressematchen (998)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '998'
7
+ field 'Nøgletal1', 'N', 3..12
8
+ field 'Nøgletal2', 'N', 13..22
9
+ field 'Nøgletal3', 'N', 23..32
10
+ field 'Nøgletal4', 'N', 33..42
11
+ field 'Nøgletal5', 'N', 43..52
12
+ field 'Nøgletal6', 'N', 53..62
13
+ field 'Nøgletal7', 'N', 63..72
14
+ field 'Nøgletal8', 'N', 73..82
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ # coding: utf-8
2
+ module Cpr::Adressematch
3
+ class Resp999 < Cpr::Row
4
+ title 'Slutrecord (der dannes en pr. udtræk) (999)'
5
+
6
+ field 'Recordtype', 'N', 0..2, :default => '999'
7
+ field 'Sortfelt', 'A', 3..25
8
+ field 'Taeller', 'N', 26..33
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+ module Cpr
3
+ class AlphanumericField < Field
4
+ def cast_for_read(val)
5
+ val.strip.encode("utf-8")
6
+ end
7
+
8
+ def cast_for_write(val)
9
+ val.ljust(length)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,90 @@
1
+ # coding: utf-8
2
+ require 'ostruct'
3
+ require 'nokogiri'
4
+
5
+ module Cpr
6
+ class FieldSpec < OpenStruct
7
+ def self.parse_from_tr(tr)
8
+ # 0 1 2 3 4 5
9
+ # Feltnavn|Format|Længde|Record pos|Indhold i feltet|Krævede felter
10
+ #
11
+ # Record pos begins at 1
12
+ tds = tr.xpath("TD").map {|td| td.content.strip }
13
+ unless tds[0] == '' or tds[0] == "Recordlængde"
14
+ FieldSpec.new(:name => tds[0],
15
+ :type => tds[1],
16
+ :range => (tds[3].to_i-1)..(tds[3].to_i-2 + tds[2].to_i),
17
+ :default => extract_default(tds[4]))
18
+ end
19
+ end
20
+
21
+ def self.extract_default(text)
22
+ if text =~ /^(\d+)$/
23
+ $1.to_i
24
+ end
25
+ end
26
+
27
+ def field_def
28
+ str = %{field '#{name}', '#{type}', #{range}}
29
+ str += %{, :default => '#{default}'} if default
30
+ str
31
+ end
32
+
33
+
34
+ def to_s
35
+ "#{name} (#{type}) #{range}: #{default}"
36
+ end
37
+ end
38
+ class RowSpec < OpenStruct
39
+ def self.parse_from_table(table)
40
+ RowSpec.new(:name => table["name"],
41
+ :title => table["title"],
42
+ :fields => table.xpath("TR[position() != 1]").map {|tr| FieldSpec.parse_from_tr(tr)}.compact)
43
+ end
44
+
45
+ def class_def(module_name, class_name)
46
+ <<DEF
47
+ # coding: utf-8
48
+ module #{module_name}
49
+ class #{class_name} < Cpr::Row
50
+ \ttitle '#{title}'
51
+
52
+ #{field_defs}
53
+ end
54
+ end
55
+ DEF
56
+ end
57
+
58
+ def field_defs
59
+ fields.map {|field| "\t#{field.field_def}" }*"\n"
60
+ end
61
+
62
+ def to_s
63
+ "#{title} - #{name}\n" +
64
+ fields.map {|field| "\t#{field}" }*"\n"
65
+ end
66
+ end
67
+
68
+ class ClassGenerator
69
+ def initialize(prefix, filename)
70
+ @prefix = prefix
71
+ @filename = filename
72
+ end
73
+
74
+ def generate
75
+ rows.each do |row|
76
+ filename = "lib/cpr/#{@prefix}/#{row.name}.rb"
77
+ File.open(filename, 'w') do |file|
78
+ file << row.class_def("Cpr::#{@prefix.capitalize}", row.name)
79
+ end
80
+ end
81
+ end
82
+
83
+ def rows
84
+ doc = Nokogiri::XML.parse(File.read(@filename))
85
+ (doc / "//Table").map do |table|
86
+ RowSpec.parse_from_table(table)
87
+ end
88
+ end
89
+ end
90
+ end
data/lib/cpr/field.rb ADDED
@@ -0,0 +1,50 @@
1
+ # coding: utf-8
2
+ module Cpr
3
+ class Field
4
+ attr_reader :name, :range, :default
5
+ def initialize(name, range, opts = {})
6
+ @name = name
7
+ @range = range
8
+ @default = opts[:default]
9
+ end
10
+
11
+ def read(raw)
12
+ cast_for_read(raw[range])
13
+ end
14
+
15
+ def write(raw, value)
16
+ raw[range] = cast_for_write(value).encode("iso-8859-1")[0...length]
17
+ raw
18
+ end
19
+
20
+ def fill
21
+ if @default != nil
22
+ cast_for_write @default
23
+ else
24
+ " "*length
25
+ end
26
+ end
27
+
28
+ def length
29
+ @range.max - @range.begin + 1
30
+ end
31
+
32
+ def pattern
33
+ if default
34
+ cast_for_write(default)
35
+ else
36
+ typed_pattern
37
+ end
38
+ end
39
+
40
+ def self.create_type(type, *args)
41
+ klass = case type
42
+ when 'A' then AlphanumericField
43
+ when 'N' then NumericField
44
+ else raise "Invalid value for type '#{type}'"
45
+ end
46
+ klass.new(*args)
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,42 @@
1
+ module Cpr
2
+ module Kunderefnr
3
+ def pnr
4
+ @pnr ||= self['Kunderefnr'] =~ /^PNR=(\d+)/ && $1
5
+ end
6
+
7
+ def birthday
8
+ if pnr
9
+ day = pnr[0..1].to_i
10
+ month = pnr[2..3].to_i
11
+ year_without_century = pnr[4..5].to_i
12
+ Date.new(year_without_century + birthday_century, month, day)
13
+ end
14
+ end
15
+
16
+ def pnr_assigned_digits
17
+ pnr[6..9] if pnr
18
+ end
19
+
20
+ # private
21
+ def birthday_century
22
+ d = pnr[6].to_i
23
+ year = pnr[0..1].to_i
24
+ if pnr
25
+ if d < 4
26
+ 1900
27
+ else
28
+ if year <= 36
29
+ 2000
30
+ elsif [9,4].include?(d)
31
+ 1900
32
+ elsif [5,6,7,8].include?(d) and year > 58
33
+ 1800
34
+ else
35
+ raise "Invalid birthday century for #{pnr}"
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ module Cpr
3
+ class NumericField < Field
4
+ def cast_for_read(val)
5
+ val.to_i if val =~ /^\d+$/
6
+ end
7
+
8
+ def cast_for_write(val)
9
+ if val.nil?
10
+ fill
11
+ else
12
+ str = "%0#{length}d" % val
13
+ raise "Value #{val} overflows length #{length}" if str.length > length
14
+ str
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+ module Cpr
3
+ class ReqDocument
4
+ attr_reader :rows
5
+ def initialize
6
+ @rows = []
7
+ end
8
+
9
+ def data
10
+ @rows.map(&:data)*"\r\n"
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ module Cpr
3
+ class RespDocument
4
+ attr_accessor :rows
5
+ def initialize(rows = [])
6
+ @rows = rows
7
+ end
8
+
9
+ def self.from_lines(lines)
10
+ rows = []
11
+ lines.each do |line|
12
+ row = Row.parse(line)
13
+ raise "Parse error while processing row:\n\t'#{line}'\n\tlen:#{line.length}" if row.nil?
14
+ rows << row
15
+ end
16
+ RespDocument.new(rows)
17
+ end
18
+
19
+ def self.from_file(filename)
20
+ file = File.open(filename, "r:iso-8859-1")
21
+ from_lines(file.readlines.map(&:strip))
22
+ end
23
+
24
+ def groups
25
+ if @groups.nil?
26
+ @groups = rows.group_by {|row| row.class.to_s.split("::").last }
27
+ @groups.default = []
28
+ end
29
+ @groups
30
+ end
31
+
32
+
33
+ end
34
+ end
data/lib/cpr/row.rb ADDED
@@ -0,0 +1,103 @@
1
+ # coding: utf-8
2
+ require 'pathname'
3
+ module Cpr
4
+ class Row
5
+ include Kunderefnr
6
+ attr_reader :data
7
+ def initialize(data = nil)
8
+ if data
9
+ @data = data
10
+ else
11
+ @data = self.class.fill
12
+ end
13
+ end
14
+
15
+ def [](fieldname)
16
+ self.class.field_by_name(fieldname).read(@data)
17
+ end
18
+
19
+ def []=(fieldname, value)
20
+ self.class.field_by_name(fieldname).write(@data, value)
21
+ end
22
+
23
+ def content
24
+ h = {}
25
+ self.class.fields.each do |field|
26
+ h[field.name] = self[field.name]
27
+ end
28
+ h
29
+ end
30
+
31
+ class << self
32
+ def title(title)
33
+ @title = title
34
+ end
35
+
36
+ def create(fields_with_vals = {})
37
+ instance = new
38
+ fields_with_vals.each do |key,val|
39
+ instance[key] = val
40
+ end
41
+ instance
42
+ end
43
+
44
+ def field(fieldname, type, range, opts = {})
45
+ @fields ||= []
46
+ @fields_map ||= {}
47
+ check_contiguous!(fieldname, range)
48
+ @fields << Cpr::Field.create_type(type, fieldname, range, opts)
49
+ @fields_map[fieldname] = @fields.last
50
+ end
51
+
52
+ def fields
53
+ @fields
54
+ end
55
+
56
+ def field_by_name(fieldname)
57
+ @fields_map[fieldname] or raise "No field by name '#{fieldname}"
58
+ end
59
+
60
+ def length
61
+ @fields.last.range.last + 1 unless @fields.empty?
62
+ end
63
+
64
+ def fill
65
+ @fields.map(&:fill).join
66
+ end
67
+
68
+ def parses?(str)
69
+ f = @fields_map['Recordtype']
70
+ f && str.start_with?(f.fill) && str.length == length
71
+ end
72
+
73
+ def parse(str)
74
+ load_subclasses if @subclasses.nil?
75
+ parser = @subclasses.find {|subclass| subclass.parses? str }
76
+ parser.new(str) if parser
77
+ end
78
+
79
+ def inherited(subclass)
80
+ @subclasses ||= []
81
+ @subclasses << subclass
82
+ end
83
+
84
+ private
85
+ def load_subclasses
86
+ class_dir = Pathname.new(__FILE__).dirname + "adressematch"
87
+ class_dir.children.select {|file| file.to_s.end_with? ".rb" }.each do |file|
88
+ require file.to_s
89
+ end
90
+ end
91
+
92
+ def check_contiguous!(fieldname, range)
93
+ if @fields.empty?
94
+ raise "First field '#{fieldname}' should start at index 0" unless range.begin == 0
95
+ else
96
+ last_end = @fields.last.range.max
97
+ raise "Field '#{fieldname}' leaves gap" if range.begin > (last_end+1)
98
+ raise "Field '#{fieldname}' overlaps" if range.begin < (last_end+1)
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,10 @@
1
+ require 'cpr/kunderefnr'
2
+ require 'cpr/row'
3
+ require 'cpr/field'
4
+ require 'cpr/alphanumeric_field'
5
+ require 'cpr/numeric_field'
6
+ require 'cpr/resp_document'
7
+ require 'cpr/req_document'
8
+ Dir.glob("#{File.dirname(__FILE__)}/cpr/adressematch/*.rb").each do |file|
9
+ require "cpr/adressematch/#{File.basename(file)}"
10
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'cpr_adressematch'
7
+
8
+ class Test::Unit::TestCase
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestCprAdressematch < Test::Unit::TestCase
4
+ def test_something_for_real
5
+ # flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ require 'helper'
3
+ require 'date'
4
+
5
+ class TestCprAdressematchResp001 < Test::Unit::TestCase
6
+ def example_no_pnr
7
+ input = "001A0006 20020107P 00000000000001000000000000Niels Nielsen 19930203 Vesterbrogade 86 2 1620K�benhavn V 01018204086B Niels Nielsen Vesterbrogade 200111111130"\
8
+ .force_encoding("iso-8859-1")
9
+ Cpr::Adressematch::Resp001.new(input)
10
+ end
11
+
12
+ def example_pnr
13
+ input = "001PNR=0801852063 20020107P 00000000000001000000000000Niels Nielsen 19930203 Vesterbrogade 86 2 1620K�benhavn V 01018204086B Niels Nielsen Vesterbrogade 200111111130"\
14
+ .force_encoding("iso-8859-1")
15
+ Cpr::Adressematch::Resp001.new(input)
16
+ end
17
+
18
+
19
+ def test_no_pnr
20
+ example = example_no_pnr
21
+ assert_nil example.pnr
22
+ assert_nil example.birthday
23
+ assert_nil example.pnr_assigned_digits
24
+ end
25
+
26
+ def test_pnr_pnr
27
+ assert_equal "0801852063", example_pnr.pnr
28
+ end
29
+
30
+ def test_pnr_birthday
31
+ assert_equal Date.new(1985, 1, 8), example_pnr.birthday
32
+ end
33
+
34
+ def test_pnr_assigned_digits
35
+ assert_equal "2063", example_pnr.pnr_assigned_digits
36
+ end
37
+
38
+
39
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ require 'helper'
3
+
4
+ class TestCprAlphanumericField < Test::Unit::TestCase
5
+ def test_read_welformed_string
6
+ f = Cpr::Field.create_type('A', 'f1', 3..5)
7
+ assert_equal "ABC", f.read("XXXABCXXXX")
8
+ assert_equal "A", f.read("XXXA XXXX")
9
+ assert_equal "", f.read("XXX XXXX")
10
+ end
11
+
12
+ def test_read_unicode
13
+ f = Cpr::Field.create_type('A', 'f1', 3..5)
14
+ assert_equal(Encoding::UTF_8, f.read("XXXABCXXXX".encode("binary")).encoding)
15
+ end
16
+
17
+ def test_write
18
+ f = Cpr::Field.create_type('A', 'f1', 3..5)
19
+ assert_equal "XXXABCXXXX", f.write("XXX XXXX", "ABC")
20
+ end
21
+
22
+ def test_write_unicode
23
+ f = Cpr::Field.create_type('A', 'f1', 3..5)
24
+ assert_equal "XXXüæøXXXX".encode("iso-8859-1"), f.write("XXX XXXX", "üæø")
25
+ end
26
+
27
+
28
+ def test_write_overflow_truncates
29
+ f = Cpr::Field.create_type('A', 'f1', 3..5)
30
+ assert_equal "XXXABCXXXX", f.write("XXX XXXX", "ABCDEFG")
31
+ end
32
+
33
+ def test_write_underflow_fills
34
+ f = Cpr::Field.create_type('A', 'f1', 3..5)
35
+ assert_equal "XXXA XXXX", f.write("XXXXXXXXXX", "A")
36
+ end
37
+
38
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+ require 'helper'
3
+
4
+ class TestCprField < Test::Unit::TestCase
5
+ def test_creates_correct_type
6
+ assert_kind_of Cpr::AlphanumericField, Cpr::Field.create_type('A', 'f1', 0..10)
7
+ assert_kind_of Cpr::NumericField, Cpr::Field.create_type('N', 'f1', 0..10)
8
+ assert_raise(RuntimeError) {
9
+ Cpr::Field.create_type('X', 'f1', 0..10)
10
+ }
11
+ end
12
+
13
+ def test_fill
14
+ f1 = Cpr::Field.create_type('A', 'f1', 0..10)
15
+ assert_equal " "*11, f1.fill
16
+ end
17
+
18
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ require 'helper'
3
+
4
+ class TestCprNumericField < Test::Unit::TestCase
5
+ def test_read_integer
6
+ f = Cpr::NumericField.new('f1', 3..5)
7
+ assert_equal 100, f.read("XXX100XXXX")
8
+ assert_equal 10, f.read("XXX010XXXX")
9
+ assert_equal 0, f.read("XXX000XXXX")
10
+ assert_nil f.read("XXX XXXX")
11
+ end
12
+
13
+ def test_write_integer
14
+ f = Cpr::NumericField.new('f1', 3..5)
15
+ assert_equal "XXX100XXXX", f.write("XXX000XXXX", 100)
16
+ assert_equal "XXX010XXXX", f.write("XXX000XXXX", 10)
17
+ assert_equal "XXX000XXXX", f.write("XXX000XXXX", 0)
18
+ assert_equal "XXX XXXX", f.write("XXX000XXXX", nil)
19
+ end
20
+
21
+ def test_write_overflow_fails
22
+ f = Cpr::NumericField.new('f1', 3..5)
23
+ assert_raise(RuntimeError) {
24
+ f.write("XXX000XXXX", 1000)
25
+ }
26
+ end
27
+
28
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+ require 'helper'
3
+
4
+ class TestCprReqDocument < Test::Unit::TestCase
5
+ def test_combines_records
6
+ row = Cpr::Row.dup
7
+ row.field 'name', 'A', 0..99
8
+ doc = Cpr::ReqDocument.new
9
+ doc.rows << row.create('name' => "NameA")
10
+ doc.rows << row.create('name' => "NameB")
11
+ assert_match(/^NameA {95}\r\nNameB {95}$/, doc.data)
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ require 'helper'
3
+
4
+ class TestCprDoc < Test::Unit::TestCase
5
+ def test_from_file
6
+ doc = Cpr::RespDocument.from_file("data/cpr_uddata_eksempel.txt")
7
+ assert_equal 8, doc.rows.length
8
+ assert doc.rows.none?(&:nil?), "nil rows not allowed"
9
+ names = File.open("data/cpr_uddata_eksempel.txt", "r:iso-8859-1")\
10
+ .read.split("\r\n").map do |line|
11
+ line[54..86].strip
12
+ end
13
+ doc.rows.zip(names) do |row,name|
14
+ assert_kind_of(Cpr::Adressematch::Resp001, row)
15
+ assert_equal name, row['Adrnvn']
16
+ end
17
+ end
18
+
19
+ def test_groups
20
+ doc = Cpr::RespDocument.from_file("data/cpr_uddata_eksempel.txt")
21
+ counts = {}
22
+ doc.groups.each do |name,rows|
23
+ counts[name] = rows.count
24
+ end
25
+ assert_equal 1, doc.groups.keys.size
26
+ assert_equal 8, counts["Resp001"]
27
+ end
28
+ end
@@ -0,0 +1,67 @@
1
+ # coding: utf-8
2
+ require 'helper'
3
+
4
+ class TestCprRow < Test::Unit::TestCase
5
+ def setup
6
+ @row = Cpr::Row.dup
7
+ end
8
+
9
+ def test_row_length
10
+ @row.field 'f1', 'A', 0..2
11
+ @row.field 'f2', 'A', 3..6
12
+ assert_equal 7, @row.length
13
+ end
14
+
15
+ def test_non_contiguous_field_throws_error
16
+ @row.field 'f1', 'A', 0..2
17
+ assert_raise(RuntimeError) {
18
+ @row.field 'f2', 'A', 4..6
19
+ }
20
+ assert_raise(RuntimeError) {
21
+ @row.field 'f2', 'A', 2..6
22
+ }
23
+ end
24
+
25
+ def test_fill
26
+ @row.field 'f1', 'A', 0..2
27
+ @row.field 'f1', 'N', 3..5
28
+ assert_equal " ", @row.fill
29
+ end
30
+
31
+ def test_field_by_name_existing_and_non_existing
32
+ @row.field 'f1', 'A', 0..2
33
+ assert_kind_of(Cpr::AlphanumericField, @row.field_by_name('f1'))
34
+ assert_raise(RuntimeError) { @row.field_by_name('non_existing_field') }
35
+ end
36
+
37
+ def test_read_field
38
+ @row.field 'f1', 'N', 0..2
39
+ instance = @row.new
40
+ assert_equal nil, instance['f1']
41
+ end
42
+
43
+ def test_write_field
44
+ @row.field 'f1', 'N', 0..2
45
+ instance = @row.new
46
+ instance['f1'] = 100
47
+ assert_equal 100, instance['f1']
48
+ end
49
+
50
+ def test_parse_valid_input
51
+ @row.field 'f1', 'N', 0..2
52
+ @row.field 'f2', 'A', 3..5
53
+ str = "999ABC"
54
+ valid_parse = @row.new(str)
55
+ assert_not_nil valid_parse
56
+ assert_equal 999, valid_parse['f1']
57
+ assert_equal "ABC", valid_parse['f2']
58
+ end
59
+
60
+ def test_create_with_valid_input
61
+ @row.field 'f1', 'N', 0..2
62
+ @row.field 'f2', 'A', 3..5
63
+ instance = @row.create('f1' => 999, 'f2' => 'ABC')
64
+ assert_equal '999ABC', instance.data
65
+ end
66
+
67
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cpr_adressematch
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Anders Johannsen
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-24 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: "Interface for generating and parsing the Danish CPR Registry data files.\n Support the 'adressematch' protocol, which can be used to query by name and adress as well as\n by the personal identifical number (CPR)\n "
22
+ email: anders@johannsen.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ - README.rdoc
30
+ files:
31
+ - LICENSE
32
+ - README.rdoc
33
+ - Rakefile
34
+ - VERSION
35
+ - lib/cpr/adressematch/req1100.rb
36
+ - lib/cpr/adressematch/req1200.rb
37
+ - lib/cpr/adressematch/req1300.rb
38
+ - lib/cpr/adressematch/req1400.rb
39
+ - lib/cpr/adressematch/resp000.rb
40
+ - lib/cpr/adressematch/resp001.rb
41
+ - lib/cpr/adressematch/resp001a.rb
42
+ - lib/cpr/adressematch/resp002.rb
43
+ - lib/cpr/adressematch/resp003.rb
44
+ - lib/cpr/adressematch/resp004.rb
45
+ - lib/cpr/adressematch/resp005.rb
46
+ - lib/cpr/adressematch/resp010.rb
47
+ - lib/cpr/adressematch/resp011.rb
48
+ - lib/cpr/adressematch/resp012.rb
49
+ - lib/cpr/adressematch/resp013.rb
50
+ - lib/cpr/adressematch/resp901.rb
51
+ - lib/cpr/adressematch/resp902.rb
52
+ - lib/cpr/adressematch/resp903.rb
53
+ - lib/cpr/adressematch/resp910.rb
54
+ - lib/cpr/adressematch/resp998.rb
55
+ - lib/cpr/adressematch/resp999.rb
56
+ - lib/cpr/alphanumeric_field.rb
57
+ - lib/cpr/class_generator.rb
58
+ - lib/cpr/field.rb
59
+ - lib/cpr/kunderefnr.rb
60
+ - lib/cpr/numeric_field.rb
61
+ - lib/cpr/req_document.rb
62
+ - lib/cpr/resp_document.rb
63
+ - lib/cpr/row.rb
64
+ - lib/cpr_adressematch.rb
65
+ - test/helper.rb
66
+ - test/test_cpr_adressematch.rb
67
+ - test/test_cpr_adressematch_resp001.rb
68
+ - test/test_cpr_alphanumeric_field.rb
69
+ - test/test_cpr_field.rb
70
+ - test/test_cpr_numeric_field.rb
71
+ - test/test_cpr_req_document.rb
72
+ - test/test_cpr_resp_document.rb
73
+ - test/test_cpr_row.rb
74
+ has_rdoc: true
75
+ homepage: http://github.com/andersjo/cpr_adressematch
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options: []
80
+
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ requirements: []
100
+
101
+ rubyforge_project:
102
+ rubygems_version: 1.3.7
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Interface for generating and parsing the Danish CPR Registry data files
106
+ test_files:
107
+ - test/helper.rb
108
+ - test/test_cpr_adressematch.rb
109
+ - test/test_cpr_adressematch_resp001.rb
110
+ - test/test_cpr_alphanumeric_field.rb
111
+ - test/test_cpr_field.rb
112
+ - test/test_cpr_numeric_field.rb
113
+ - test/test_cpr_req_document.rb
114
+ - test/test_cpr_resp_document.rb
115
+ - test/test_cpr_row.rb