edi4r 0.9.4.1 → 0.9.6.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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/AuthorCopyright +3 -3
  3. data/{ChangeLog → Changelog} +60 -0
  4. data/README +15 -10
  5. data/Tutorial +2 -3
  6. data/VERSION +1 -1
  7. data/bin/edi2xml.rb +12 -16
  8. data/bin/editool.rb +9 -5
  9. data/bin/sedas2eancom02.rb +1385 -0
  10. data/bin/xml2edi.rb +7 -12
  11. data/data/edifact/iso9735/SDCD.20000.csv +1 -0
  12. data/data/edifact/iso9735/SDCD.3for2.csv +1 -0
  13. data/data/edifact/iso9735/SDED.20000.csv +6 -0
  14. data/data/edifact/iso9735/SDED.30000.csv +43 -43
  15. data/data/edifact/iso9735/SDED.3for2.csv +6 -0
  16. data/data/edifact/iso9735/SDED.40000.csv +129 -129
  17. data/data/edifact/iso9735/SDED.40100.csv +130 -130
  18. data/data/edifact/iso9735/SDMD.20000.csv +6 -0
  19. data/data/edifact/iso9735/SDMD.30000.csv +6 -6
  20. data/data/edifact/iso9735/SDMD.3for2.csv +6 -0
  21. data/data/edifact/iso9735/SDMD.40000.csv +17 -17
  22. data/data/edifact/iso9735/SDMD.40100.csv +17 -17
  23. data/data/edifact/iso9735/SDSD.20000.csv +5 -0
  24. data/data/edifact/iso9735/SDSD.3for2.csv +5 -0
  25. data/data/edifact/untdid/EDMD.d01b.csv +1 -1
  26. data/data/sedas/EDCD..csv +0 -0
  27. data/data/sedas/EDED..csv +859 -0
  28. data/data/sedas/EDMD..csv +16 -0
  29. data/data/sedas/EDSD..csv +44 -0
  30. data/lib/edi4r.rb +147 -67
  31. data/lib/edi4r/ansi_x12-rexml.rb +91 -0
  32. data/lib/edi4r/ansi_x12.rb +1684 -0
  33. data/lib/edi4r/diagrams.rb +75 -14
  34. data/lib/edi4r/edifact-rexml.rb +4 -3
  35. data/lib/edi4r/edifact.rb +505 -202
  36. data/lib/edi4r/rexml.rb +13 -7
  37. data/lib/edi4r/sedas.rb +854 -0
  38. data/lib/edi4r/standards.rb +150 -33
  39. data/test/damaged_file.edi +1 -0
  40. data/test/eancom2webedi.rb +1 -0
  41. data/test/groups.edi +1 -1
  42. data/test/test_basics.rb +16 -9
  43. data/test/test_edi_split.rb +30 -0
  44. data/test/test_loopback.rb +7 -2
  45. data/test/test_rexml.rb +34 -2
  46. data/test/test_service_messages.rb +190 -0
  47. data/test/test_streaming.rb +167 -0
  48. data/test/test_tut_examples.rb +3 -1
  49. data/test/webedi2eancom.rb +1 -0
  50. metadata +121 -77
@@ -1,7 +1,12 @@
1
- #!/usr/bin/env ruby
1
+ # #!/usr/bin/env ruby
2
+ # -*- encoding: iso-8859-1 -*-
2
3
  # :include: ../AuthorCopyright
3
4
 
4
5
  require 'test/unit'
6
+ require 'rbconfig'
7
+ $ruby_cmd = File.join(RbConfig::CONFIG["bindir"],
8
+ RbConfig::CONFIG["RUBY_INSTALL_NAME"] + RbConfig::CONFIG["EXEEXT"])
9
+ $ruby_cmd << " -E iso-8859-1" if RUBY_VERSION >= '1.9'
5
10
 
6
11
  #######################################################################
7
12
  # Test the accompanying standalone mapping tools
@@ -13,7 +18,7 @@ class EDIFACT_Tests < Test::Unit::TestCase
13
18
  def test_loopback
14
19
  s1 = nil
15
20
  File.open('in1.inh') {|hnd| hnd.binmode; s1 = hnd.read}
16
- s2 = `ruby ./webedi2eancom.rb -a in1.inh | ruby ./eancom2webedi.rb`
21
+ s2 = `#$ruby_cmd ./webedi2eancom.rb -a in1.inh | #$ruby_cmd ./eancom2webedi.rb`
17
22
  assert_equal( 0, $? )
18
23
  assert_match( s1, s2 )
19
24
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # *-* encoding: iso-8859-1 -*-
2
3
  # :include: ../AuthorCopyright
3
4
 
4
5
  #######################################################################
@@ -10,9 +11,13 @@
10
11
  # Include statement during test setup:
11
12
 
12
13
  $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
14
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'tdid', 'lib')
15
+
13
16
  require 'edi4r'
14
17
  require 'edi4r/edifact'
15
18
  require 'edi4r/rexml'
19
+ require 'edi4r-tdid'
20
+ require 'edi4r/edifact-rexml'
16
21
 
17
22
  # Regular include statements:
18
23
 
@@ -62,14 +67,41 @@ class EDIFACT_REXML_Tests < Test::Unit::TestCase
62
67
  end
63
68
 
64
69
 
70
+ def test_joko
71
+ icx = nil
72
+ assert_nothing_raised do
73
+ icx = EDI::Interchange.parse(File.open("joko2.xml"))
74
+ assert_equal( 0, icx.validate )
75
+ end
76
+
77
+ ice = EDI::Interchange.parse(File.open("joko_in.edi"))
78
+ assert_equal( ice.to_s, icx.to_s ) # EDIFACT representations equal?
79
+
80
+ se = StringIO.new
81
+ xdoc_e = REXML::Document.new
82
+ ice.to_xml(xdoc_e)
83
+ xdoc_e.write( se, 0 )
84
+ xdoc_e.write( File.open('joko2a.xml','w'), 0 )
85
+
86
+ sx = StringIO.new
87
+ xdoc_x = REXML::Document.new
88
+ icx.to_xml(xdoc_x)
89
+ xdoc_x.write( sx, 0 )
90
+
91
+ ie = EDI::E::Interchange.parse_xml( xdoc_e )
92
+ ix = EDI::E::Interchange.parse_xml( xdoc_x )
93
+ assert_equal( ie.to_s, ix.to_s )
94
+ end
95
+
96
+
65
97
  def test_groups
66
98
 
67
99
  xdoc = REXML::Document.new
68
100
  assert_nothing_raised{ @icg.to_xml( xdoc ) }
69
101
 
70
102
  sg = StringIO.new
71
- xdoc.write( sg, 0 )
72
- # xdoc.write( File.open("groups2.xml",'w'), 0 )
103
+ xdoc.write( sg )
104
+ # xdoc.write( File.open("groups2.xml",'w') )
73
105
 
74
106
  ic = nil
75
107
  assert_nothing_raised do
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: iso-8859-1 -*-
3
+ # :include: ../AuthorCopyright
4
+
5
+ # Load path magic...
6
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
7
+
8
+ require 'test/unit'
9
+
10
+ require 'edi4r'
11
+ # require 'edi4r-tdid'
12
+ require 'edi4r/edifact'
13
+
14
+ class EDIFACT_Tests < Test::Unit::TestCase
15
+
16
+ # edi@energy sample:
17
+ # UCI+10001+4078901000029:14+4012345000023:14+4'
18
+ # Dieses Beispiel identifiziert die Übertragung 10001 vom Absender
19
+ # 4078901000029 (ILN) an den Empfänger 4012345000023 (ILN).
20
+ # In der empfangenen Datei wurde ein Syntaxfehler festgestellt.
21
+
22
+ def fill_CONTRL( msg )
23
+ seg = msg.new_segment('UCI')
24
+ msg.add seg
25
+ seg.d0020 = '10001'
26
+ seg.cS002.d0004 = '4078901000029'
27
+ seg.cS002.d0007 = '14'
28
+ seg.cS003.d0010 = '4012345000023'
29
+ seg.cS003.d0007 = '14'
30
+ seg.d0083 = '4'
31
+ end
32
+
33
+ # Sample data from EANCOM 2002 example 2:
34
+ #
35
+ # UNH+AUT0001+AUTACK:4:1:UN:EAN001'
36
+ # USH+7+1+3+1+2+1++++1:20020102:100522:0100'
37
+ # USA+1:16:1:6:1:7:1'
38
+ # USC+AXZ4711+4::541234500006:2+3'
39
+ # USA+6:16:1:10:1:7:1'
40
+ # USB+1++5412345678908:14+8798765432106:14'
41
+ # USX+INT12435+5412345678908:14+8798765432106:14'
42
+ # USY+1+1:139B7CB..........7C72B03CE5F'
43
+ # UST+1+5'
44
+ # UNT+10+AUT0001
45
+ #
46
+ def fill_AUTACK( msg )
47
+ msg.header.d0062 = 'AUT0001'
48
+
49
+ seg = msg.new_segment('USH')
50
+ msg.add seg
51
+ seg.d0501 = 7
52
+ seg.d0534 = 1
53
+ seg.d0541 = 3
54
+ seg.d0503 = 1
55
+ seg.d0505 = 2
56
+ seg.d0507 = 1
57
+ seg.cS501.d0517 = 1
58
+ seg.cS501.d0338 = '20020102'
59
+ seg.cS501.d0314 = '100522'
60
+ seg.cS501.d0336 = '0100'
61
+
62
+ seg = msg.new_segment('USA')
63
+ msg.add seg
64
+ seg.cS502.d0523 = 1
65
+ seg.cS502.d0525 = 16
66
+ seg.cS502.d0533 = 6
67
+ seg.cS502.d0527 = 1
68
+ seg.cS502.d0529 = 6
69
+ seg.cS502.d0591 = 7
70
+ seg.cS502.d0601 = 1
71
+
72
+ seg = msg.new_segment('USC')
73
+ msg.add seg
74
+ seg.d0536 = 'AXZ4711'
75
+ seg.cS500.d0577 = 4
76
+ seg.cS500.d0511 = '541234500006'
77
+ seg.cS500.d0513 = 2
78
+ seg.d0545 = 3
79
+
80
+ seg = msg.new_segment('USA')
81
+ msg.add seg
82
+ seg.cS502.d0523 = 6
83
+ seg.cS502.d0525 = 16
84
+ seg.cS502.d0533 = 1
85
+ seg.cS502.d0527 = 10
86
+ seg.cS502.d0529 = 1
87
+ seg.cS502.d0591 = 7
88
+ seg.cS502.d0601 = 1
89
+
90
+ seg = msg.new_segment('USB')
91
+ msg.add seg
92
+ seg.d0503 = 1
93
+ seg.cS002.d0004 = '5412345678908'
94
+ seg.cS002.d0007 = 14
95
+ seg.cS003.d0010 = '8798765432106'
96
+ seg.cS003.d0007 = 14
97
+
98
+ seg = msg.new_segment('USX')
99
+ msg.add seg
100
+ seg.d0020 = 'INT12435'
101
+ seg.cS002.d0004 = '5412345678908'
102
+ seg.cS002.d0007 = 14
103
+ seg.cS003.d0010 = '8798765432106'
104
+ seg.cS003.d0007 = 14
105
+
106
+ seg = msg.new_segment('USY')
107
+ msg.add seg
108
+ seg.d0534 = 1
109
+ seg.cS508.d0563 = 1
110
+ seg.cS508.d0560 = '139B7CB..........7C72B03CE5F'
111
+
112
+ seg = msg.new_segment('UST')
113
+ msg.add seg
114
+ seg.d0534 = 1
115
+ seg.d0588 = 5
116
+ end
117
+
118
+
119
+
120
+ def test_CONTRL_creation
121
+
122
+ test_set = [
123
+ {:sv => 2, :version => '2', :release => '2'}, # Can't work - segments missing?
124
+ {:sv => 3, :version => 'D', :release => '3'},
125
+ {:sv => 3, :version => 'D', :release => '3', :assigned_code => '1.3c'},
126
+ # {:sv => 3, :version => 'D', :release => '96A', :assigned_code => 'EAN002'},
127
+ ]
128
+ test_set.each do |testcase|
129
+ ic = nil
130
+ assert_nothing_raised { ic = EDI::E::Interchange.new(
131
+ :version => testcase[:sv],
132
+ :charset => testcase[:sv] == 2 ? 'UNOB' : 'UNOC') }
133
+ ic.header.d0035 = 1 # Test indicator
134
+ msg = ic.new_message(:msg_type => 'CONTRL',
135
+ :version => testcase[:version],
136
+ :release => testcase[:release],
137
+ :assigned_code => testcase[:assigned_code])
138
+ fill_CONTRL(msg)
139
+ ic.add msg
140
+ assert_equal( 1, msg.header.first.value ) # value of DE 0062
141
+ s009 = ['CONTRL', testcase[:version], testcase[:release], 'UN'].join ic.una.ce_sep
142
+ s009 << ":#{testcase[:assigned_code]}" unless testcase[:assigned_code].nil?
143
+ assert_equal( s009, msg.header[1].to_s ) # S009
144
+ assert_equal( ['UNH', 1, s009].join(ic.una.de_sep), msg.header.to_s ) # UNH
145
+ # puts ic
146
+ end
147
+ end
148
+
149
+ def test_AUTACK_creation
150
+
151
+ test_set = [
152
+ {:sv => 4, :version => '4', :release => '1'},
153
+ {:sv => 4, :version => '4', :release => '1', :assigned_code => 'EAN008'},
154
+ {:sv => 3, :version => '4', :release => '1', :should_fail => true}
155
+ ]
156
+ test_set.each do |testcase|
157
+ ic = nil
158
+ assert_nothing_raised { ic = EDI::E::Interchange.new(
159
+ :version => testcase[:sv], :charset => 'UNOA') }
160
+ unb = ic.header
161
+ unb.d0020 = 'INT12435'
162
+ unb.cS002.d0004 = '5412345678908'
163
+ unb.cS002.d0007 = 14
164
+ unb.cS003.d0010 = '8798765432106'
165
+ unb.cS003.d0007 = 14
166
+ msg = ic.new_message(:msg_type => 'AUTACK',
167
+ :version => testcase[:version],
168
+ :release => testcase[:release],
169
+ :assigned_code => testcase[:assigned_code])
170
+ if testcase[:should_fail]
171
+ assert_raise(RuntimeError, EDI::EDILookupError) do
172
+ fill_AUTACK(msg) # Lookup error?
173
+ ic.add msg # Validation error?
174
+ end
175
+ else
176
+ assert_nothing_raised do
177
+ fill_AUTACK(msg)
178
+ ic.add msg
179
+ end
180
+ end
181
+
182
+ assert_equal( 'AUT0001', msg.header.first.value ) # value of DE 0062
183
+ s009 = "AUTACK:#{testcase[:version]}:#{testcase[:release]}:UN"
184
+ s009 << ":#{testcase[:assigned_code]}" unless testcase[:assigned_code].nil?
185
+ assert_equal( s009, msg.header[1].to_s ) # S009
186
+ assert_equal( "UNH+AUT0001+"+s009, msg.header.to_s ) # UNH
187
+ end
188
+ end
189
+
190
+ end
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env ruby
2
+ # :include: ../AuthorCopyright
3
+
4
+ # Load path magic...
5
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
+
7
+ require 'test/unit'
8
+
9
+ require 'edi4r'
10
+ require 'edi4r/edifact'
11
+
12
+ #######################################################################
13
+ # Test the streaming parser with a large interchange
14
+ #
15
+ # Instead of mapping, we derive some statistics:
16
+ # Count number of line items, report no. of messages
17
+
18
+ module MyParserAddons
19
+
20
+ attr_accessor :lin, :all
21
+
22
+ def on_other( s )
23
+ $stderr.puts "other: #{s}"
24
+ end
25
+
26
+ def on_segment( s, tag )
27
+ case tag
28
+ when 'LIN'
29
+ self.lin += 1
30
+ self.all += 1
31
+ else
32
+ self.all += 1
33
+ end
34
+ super
35
+ end
36
+
37
+ def to_s
38
+ "Found %d LIN segments, %d total segments" % [self.lin, self.all]
39
+ end
40
+ end
41
+
42
+
43
+ class MyParser < EDI::E::StreamingParser
44
+ include MyParserAddons
45
+
46
+ def initialize
47
+ @lin = @all = 0
48
+ super
49
+ end
50
+ end
51
+
52
+
53
+ class MyLWBuilder < EDI::E::StreamingBuilder
54
+ include MyParserAddons
55
+
56
+ def initialize( validate )
57
+ @lin = @all = 0
58
+ super
59
+ end
60
+
61
+ def on_segment( s, tag )
62
+ case tag
63
+ when 'LIN'
64
+ self.lin += 1
65
+ self.all += 1
66
+ else
67
+ self.all += 1
68
+ end
69
+ # super
70
+ end
71
+
72
+ def on_interchange_end
73
+ # @ic.validate
74
+ # super
75
+ end
76
+ end
77
+
78
+
79
+ class MyBuilder < EDI::E::StreamingBuilder
80
+ include MyParserAddons
81
+
82
+ def initialize( validate )
83
+ @lin = @all = 0
84
+ super
85
+ end
86
+ end
87
+
88
+
89
+ class MyDemoParser < EDI::E::StreamingParser
90
+ attr_reader :counters
91
+
92
+ def initialize
93
+ @counters = Hash.new(0)
94
+ super
95
+ end
96
+
97
+ def on_segment( s, tag )
98
+ @counters[tag] += 1
99
+ end
100
+ end
101
+
102
+
103
+ class StreamParser_Tests < Test::Unit::TestCase
104
+
105
+ def test_streaming_parser
106
+ parser = MyParser.new
107
+ assert_nothing_raised{ parser.go File.open('in1.edi') }
108
+ assert_equal( 2, parser.lin )
109
+ assert_equal( 35, parser.all )
110
+
111
+ # Syntax check
112
+ #
113
+ parser = EDI::E::StreamingParser.new
114
+ assert_raise(EDI::E::EDISyntaxError){ parser.go( File.open('damaged_file.edi') ) }
115
+ end
116
+
117
+ def test_sample_code
118
+ assert_nothing_raised {
119
+ parser = MyDemoParser.new
120
+ parser.go( File.open( 'remadv101.edi' ) )
121
+ # parser.go( File.open( 'I0002352726' ) ) # Huge interchange, 5MB
122
+ puts "Segment tag statistics:"
123
+ parser.counters.keys.sort.each do |tag|
124
+ print "%03s: %4d\n" % [ tag, parser.counters[tag] ]
125
+ end
126
+ }
127
+ parser = EDI::E::StreamingParser.new
128
+ def parser.on_segment( s, tag ) # singleton
129
+ if tag == 'AJT'
130
+ puts "Interchange in '#{self.path}' contains at least one segment AJT."
131
+ puts "Here is its contents: #{s}"
132
+ throw :done # Skip further parsing
133
+ end
134
+ end
135
+ def parser.on_unz_uiz( s, tag )
136
+ puts "Interchange in '#{self.path}' does NOT contain a segment AJT!"
137
+ end
138
+ assert_nothing_raised do
139
+ parser.go( File.open( 'in1.edi' ) )
140
+ parser.go( File.open( 'remadv101.edi' ) )
141
+ end
142
+
143
+ end
144
+
145
+ def test_streaming_lightweight_builder
146
+ builder = MyLWBuilder.new( false )
147
+ assert_nothing_raised{ builder.go File.open('I0002352726') }
148
+ ic = builder.interchange
149
+ assert_equal( 35679, builder.lin )
150
+ assert_equal( 290947, builder.all )
151
+ assert_equal( 28, ic.size )
152
+ end
153
+
154
+ def test_streaming_builder
155
+ builder = MyBuilder.new( false )
156
+ assert_nothing_raised{ builder.go File.open('in1.edi') }
157
+ ic = builder.interchange
158
+ assert_equal( 2, builder.lin )
159
+ assert_equal( 35, builder.all )
160
+ assert_equal( 1, ic.size )
161
+ assert_nothing_raised{ assert(ic.validate) }
162
+
163
+ builder = MyBuilder.new( true )
164
+ assert_nothing_raised{ builder.go File.open('groups.edi') }
165
+ end
166
+
167
+ end
@@ -3,11 +3,13 @@
3
3
 
4
4
  # Load path magic...
5
5
  $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'tdid', 'lib')
6
7
 
7
8
  require 'test/unit'
8
9
 
9
10
  require 'edi4r'
10
11
  require 'edi4r/edifact'
12
+ require 'edi4r-tdid'
11
13
 
12
14
  # require "rubygems"
13
15
  # require_gem "edi4r"
@@ -119,7 +121,7 @@ class Tutorial_Tests < Test::Unit::TestCase
119
121
  last_msg = ic.last
120
122
  d = last_msg['DTM'] # Array of all DTM segments, any segment group
121
123
  assert( d. is_a?( Array ) )
122
- d = msg.find_all {|seg| seg.name == 'DTM' && seg.sg_name == 'SG4'}
124
+ d = last_msg.find_all {|seg| seg.name == 'DTM' && seg.sg_name == 'SG4'}
123
125
  assert_equal( 11, d.size )
124
126
 
125
127
  doc1 = last_msg['DOC'].first