lis 0.2.2 → 0.2.3

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.
data/features/lis.feature CHANGED
@@ -7,7 +7,7 @@ Feature:
7
7
  Given LIS Interface listening for messages
8
8
  And the following requests are pending for DPC:
9
9
  | id | patient_id | last_name | first_name | test_names |
10
- | 123ABC | 98 | Sierra | Rudolph | TSH, FT3, FT4, FOO, BAR, BAZ |
10
+ | 123ABC | 98 | Müller | Rudolph | TSH, FT3, FT4, FOO, BAR, BAZ |
11
11
  When receiving data
12
12
  """
13
13
  1H|\^&||PASSWORD|DPC||Randolph^New^Jersey^07869||(201)927-2828|N81|Your System||P|1|19940407120613 51
@@ -17,7 +17,7 @@ Feature:
17
17
  Then LIS should have sent test orders to client:
18
18
  """
19
19
  1H|\^&|||LIS||||8N1|DPC||P|1|
20
- 2P|1||||Sierra^Rudolph||||||||
20
+ 2P|1||||Müller^Rudolph||||||||
21
21
  3O|1|123ABC||^^^TSH
22
22
  4O|1|123ABC||^^^FT3
23
23
  5O|1|123ABC||^^^FT4
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'mocha'
2
4
  require 'yaml'
3
5
 
@@ -8,7 +10,7 @@ Given /^LIS Interface listening for messages$/ do
8
10
  @server = LIS::InterfaceServer.create(@io, "http://localhost/lis/")
9
11
 
10
12
  stub_request(:post, /http:\/\/localhost\/lis\/result\/.*/).
11
- with(:body => /.*/, :headers => {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded', 'User-Agent'=>'Ruby'}).
13
+ with(:body => /.*/, :headers => {'Accept'=>'*/*', 'Content-Type'=>'application/x-www-form-urlencoded'}).
12
14
  to_return(:status => 200, :body => "", :headers => {})
13
15
 
14
16
  @t = Thread.new do
@@ -49,17 +51,14 @@ end
49
51
  #
50
52
  Given /^the following requests are pending for (\w+):$/ do |device_name, table|
51
53
  table.hashes.each do |patient|
52
- p patient
53
-
54
54
  body = { "patient" => { "last_name" => patient["last_name"],
55
55
  "first_name" => patient["first_name"],
56
56
  "id" => patient["patient_id"]},
57
57
  "id" => patient["id"],
58
58
  "types" => patient["test_names"].strip.split(/\s+/) }
59
- p body
60
59
 
61
60
  stub_request(:get, "http://localhost/lis/find_requests/#{device_name}-#{patient["id"]}").
62
- with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
61
+ with(:headers => {'Accept'=>'*/*'}).
63
62
  to_return(:status => 200, :body => body.to_yaml, :headers => {})
64
63
 
65
64
  end
@@ -69,11 +68,14 @@ end
69
68
 
70
69
  Then /^LIS should have sent test orders to client:$/ do |text|
71
70
  @data = @client.read_all
71
+ @data.force_encoding("utf-8") if @data.respond_to?(:force_encoding)
72
72
  @packets = @data.split("\002").select { |s| s =~ /^\d[A-Z]/ }
73
- @packets.zip(text.lines) do |actual, expected|
73
+ @packets.zip(text.split(/\n/)) do |actual, expected|
74
+ @called = true
74
75
  rx = Regexp.new("^" + Regexp.escape(expected.strip))
75
76
  assert_match(rx, actual.gsub(/\r\003.*$/, "").strip)
76
77
  end
78
+ assert_equal(true, @called)
77
79
  end
78
80
 
79
81
 
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'optparse'
2
4
 
3
5
  module LIS
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Message
2
4
 
3
5
  # = Comment Message
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Message
2
4
 
3
5
  # = Header Message
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Message
2
4
 
3
5
  # = Order Message
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Message
2
4
 
3
5
  # = Patient Message
@@ -72,7 +74,7 @@ module LIS::Message
72
74
  self.sequence_number = sequence_number
73
75
  self.practice_assigned_patient_id = patient_id
74
76
  self.patient_id = patient_id
75
- self.name = [last_name.force_encoding("UTF-8"), first_name.force_encoding("UTF-8")].join("^")
77
+ self.name = [last_name, first_name].join("^")
76
78
  end
77
79
 
78
80
  end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Message
2
4
 
3
5
  # = Query Message
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Message
2
4
 
3
5
  # = Result Message
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Message
2
4
 
3
5
  # = Terminator Message
data/lib/lis/messages.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'date'
2
4
 
3
5
  module LIS::Message
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
 
2
3
  module LIS::Transfer
3
4
  class ApplicationProtocol < ::PacketIO::Base
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS::Transfer
2
4
 
3
5
  module ASTM
@@ -34,14 +36,14 @@ module LIS::Transfer
34
36
 
35
37
  def initialize(*args)
36
38
  super(*args)
37
- @memo = ""
39
+ @data = StringScanner.new("")
38
40
  @inside_transmission = false
39
41
  end
40
42
 
41
43
  def receive(data)
42
- scanner = StringScanner.new(@memo + data)
43
- while scanner.scan_until(RX)
44
- match = scanner.matched
44
+ @data.concat(data)
45
+ while @data.scan_until(RX)
46
+ match = @data.matched
45
47
  case match
46
48
  when ENQ then transmission_start
47
49
  when EOT then transmission_end
@@ -51,7 +53,6 @@ module LIS::Transfer
51
53
  write :ack
52
54
  end
53
55
  end
54
- @memo = scanner.rest
55
56
  nil
56
57
  end
57
58
 
data/lib/lis/version.rb CHANGED
@@ -1,4 +1,6 @@
1
+ # encoding: UTF-8
2
+
1
3
  module LIS
2
- VERSION = "0.2.2"
4
+ VERSION = "0.2.3"
3
5
  end
4
6
 
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  require 'net/http'
2
4
  require 'yaml'
3
5
 
data/lis.gemspec CHANGED
@@ -20,12 +20,12 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
  s.summary = %q{LIS interface to Siemens Immulite 2000XPi or other similar analyzers}
22
22
 
23
- s.add_dependency "packet_io", "~> 0.4.0.rc4"
23
+ s.add_dependency "packet_io", "~> 0.4.0"
24
24
 
25
- s.add_development_dependency("shoulda", ["~> 2.11.3"])
26
- s.add_development_dependency("mocha", ["~> 0.9.12"])
27
- s.add_development_dependency("yard", ["~> 0.7.1"])
28
- s.add_development_dependency("cucumber", ["~> 0.10.3"])
29
- s.add_development_dependency("webmock")
25
+ s.add_development_dependency("shoulda", "~> 2.11.3")
26
+ s.add_development_dependency("mocha", "~> 0.9.12")
27
+ s.add_development_dependency("yard", "~> 0.7.1")
28
+ s.add_development_dependency("cucumber", "~> 0.10.3")
29
+ s.add_development_dependency("webmock", "~> 1.6.4")
30
30
  end
31
31
 
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lis
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 17
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 2
8
- - 2
9
- version: 0.2.2
9
+ - 3
10
+ version: 0.2.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - Levin Alexander
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2011-06-01 00:00:00 +02:00
18
+ date: 2011-06-11 00:00:00 +02:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -25,12 +26,12 @@ dependencies:
25
26
  requirements:
26
27
  - - ~>
27
28
  - !ruby/object:Gem::Version
29
+ hash: 15
28
30
  segments:
29
31
  - 0
30
32
  - 4
31
33
  - 0
32
- - rc4
33
- version: 0.4.0.rc4
34
+ version: 0.4.0
34
35
  type: :runtime
35
36
  version_requirements: *id001
36
37
  - !ruby/object:Gem::Dependency
@@ -41,6 +42,7 @@ dependencies:
41
42
  requirements:
42
43
  - - ~>
43
44
  - !ruby/object:Gem::Version
45
+ hash: 37
44
46
  segments:
45
47
  - 2
46
48
  - 11
@@ -56,6 +58,7 @@ dependencies:
56
58
  requirements:
57
59
  - - ~>
58
60
  - !ruby/object:Gem::Version
61
+ hash: 35
59
62
  segments:
60
63
  - 0
61
64
  - 9
@@ -71,6 +74,7 @@ dependencies:
71
74
  requirements:
72
75
  - - ~>
73
76
  - !ruby/object:Gem::Version
77
+ hash: 1
74
78
  segments:
75
79
  - 0
76
80
  - 7
@@ -86,6 +90,7 @@ dependencies:
86
90
  requirements:
87
91
  - - ~>
88
92
  - !ruby/object:Gem::Version
93
+ hash: 49
89
94
  segments:
90
95
  - 0
91
96
  - 10
@@ -99,11 +104,14 @@ dependencies:
99
104
  requirement: &id006 !ruby/object:Gem::Requirement
100
105
  none: false
101
106
  requirements:
102
- - - ">="
107
+ - - ~>
103
108
  - !ruby/object:Gem::Version
109
+ hash: 7
104
110
  segments:
105
- - 0
106
- version: "0"
111
+ - 1
112
+ - 6
113
+ - 4
114
+ version: 1.6.4
107
115
  type: :development
108
116
  version_requirements: *id006
109
117
  description: ""
@@ -127,7 +135,6 @@ files:
127
135
  - features/step_definitions/lis_steps.rb
128
136
  - features/support/env.rb
129
137
  - lib/lis.rb
130
- - lib/lis/application_protocol.rb
131
138
  - lib/lis/commands/application.rb
132
139
  - lib/lis/interface_server.rb
133
140
  - lib/lis/messages.rb
@@ -138,7 +145,6 @@ files:
138
145
  - lib/lis/messages/query.rb
139
146
  - lib/lis/messages/result.rb
140
147
  - lib/lis/messages/terminator.rb
141
- - lib/lis/packetized_protocol.rb
142
148
  - lib/lis/transfer/application_protocol.rb
143
149
  - lib/lis/transfer/astm_e1394.rb
144
150
  - lib/lis/version.rb
@@ -167,6 +173,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
167
173
  requirements:
168
174
  - - ">="
169
175
  - !ruby/object:Gem::Version
176
+ hash: 3
170
177
  segments:
171
178
  - 0
172
179
  version: "0"
@@ -175,6 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
182
  requirements:
176
183
  - - ">="
177
184
  - !ruby/object:Gem::Version
185
+ hash: 3
178
186
  segments:
179
187
  - 0
180
188
  version: "0"
@@ -1,104 +0,0 @@
1
-
2
- module LIS::Transfer
3
- class ApplicationProtocol < Base
4
- attr_reader :device_name
5
-
6
- def on_result(&block)
7
- @on_result_callback = block
8
- end
9
-
10
- def on_request(&block)
11
- @on_request_callback = block
12
- end
13
-
14
- def received_header(message)
15
- @patient_information_requests ||= {} # delete the list of patients
16
- @device_name = message.sender_name
17
- end
18
-
19
- def result_for(patient, order, result)
20
- @on_result_callback.call(@device_name, patient, order, result)
21
- end
22
-
23
- def received_patient_information(message)
24
- @last_order = nil
25
- @last_patient = message
26
- end
27
-
28
- def received_order_record(message)
29
- @last_order = message
30
- end
31
-
32
- def received_result(message)
33
- result_for(@last_patient, @last_order, message)
34
- end
35
-
36
- def received_request_for_information(message)
37
- @patient_information_requests ||= {}
38
- requests = @on_request_callback.call(@device_name, message.starting_range_id)
39
- @patient_information_requests[message.sequence_number] = requests if requests
40
- end
41
-
42
- def send_pending_requests
43
- sending_session(@patient_information_requests) do |patient_information|
44
- patient_information.each do |sequence_nr, data|
45
- write :message, LIS::Message::Patient.new(sequence_nr,
46
- data["patient"]["number"],
47
- data["patient"]["last_name"],
48
- data["patient"]["first_name"]).to_message
49
- data["types"].each do |request|
50
- write :message, LIS::Message::Order.new(sequence_nr, data["id"], request).to_message
51
- end
52
- end
53
- end
54
- @patient_information_requests = {}
55
- end
56
-
57
- def initialize(*args)
58
- super
59
-
60
- @patient_information_requests = {}
61
- @last_patient = nil
62
- @last_order = nil
63
- @handlers = {
64
- LIS::Message::Header => :received_header,
65
- LIS::Message::Patient => :received_patient_information,
66
- LIS::Message::Order => :received_order_record,
67
- LIS::Message::Result => :received_result,
68
- LIS::Message::Query => :received_request_for_information
69
- }
70
- end
71
-
72
- def receive(type, message = nil)
73
- warn "[R] #{message}" if type == :message and $VERBOSE
74
- case type
75
- when :begin
76
- @last_patient = nil
77
- @last_order = nil
78
- when :idle
79
- send_pending_requests
80
- when :message
81
- @message = LIS::Message::Base.from_string(message)
82
- handler = @handlers[@message.class]
83
- send(handler, @message) if handler
84
- end
85
- end
86
-
87
- def write(type, message=nil)
88
- warn "[S] #{message}" if type == :message and $VERBOSE
89
- super
90
- end
91
-
92
- # @yield data
93
- def sending_session(data)
94
- # don't send anything if there are no pending requests
95
- return if data.nil? or data.empty?
96
-
97
- write :begin
98
- write :message, LIS::Message::Header.new("LIS", @device_name).to_message
99
- yield data
100
- write :message, LIS::Message::Terminator.new.to_message
101
- write :idle
102
- end
103
- end
104
- end
@@ -1,119 +0,0 @@
1
-
2
- module LIS::Transfer
3
-
4
- # splits a stream into lis packets and only lets packets through
5
- # that are inside a session delimited by ENQ .. EOT
6
- #
7
- # check the checksum and do acknowledgement of messages
8
- #
9
- # forwards the following events:
10
- #
11
- # - :message, String :: when a message is received
12
- # - :idle :: when a transmission is finished (after EOT is received)
13
- #
14
- class PacketizedProtocol < Base
15
- ACK = "\006"
16
- NAK = "\025"
17
- ENQ = "\005"
18
- EOT = "\004"
19
-
20
- # format of a message
21
- RX = /(?:
22
- \005 | # ENQ - start a transaction
23
- \004 | # EOT - ends a transaction
24
- \005 | # ACK
25
- \025 | # NAK
26
- (?:\002 (.) (.*?) \015 \003 (.+?) \015 \012) # a message with a checksum
27
- # | | `-- checksum
28
- # | `------------------ message
29
- # `---------------------- frame number
30
- )
31
- /xm
32
-
33
- def initialize(*args)
34
- super(*args)
35
- @memo = ""
36
- @inside_transmission = false
37
- end
38
-
39
- def receive(data)
40
- scanner = StringScanner.new(@memo + data)
41
- while scanner.scan_until(RX)
42
- match = scanner.matched
43
- case match
44
- when ENQ then transmission_start
45
- when EOT then transmission_end
46
- when ACK, NAK then nil
47
- else
48
- received_message(match)
49
- write :ack
50
- end
51
- end
52
- @memo = scanner.rest
53
- nil
54
- end
55
-
56
- def write(type, data = nil)
57
- str = case type
58
- when :ack then ACK
59
- when :nak then NAK
60
- when :begin then
61
- @frame_number = 0
62
- ENQ
63
- when :idle then EOT
64
- when :message then
65
- @frame_number = (@frame_number + 1) % 8
66
- self.class.wrap_message(data, @frame_number)
67
- else
68
- raise ArgumentError
69
- end
70
- super(str)
71
- end
72
-
73
-
74
- private
75
-
76
- def self.message_from_string(string)
77
- match = string.match(RX)
78
-
79
- frame_number, data, checksum = match[1 .. 3]
80
-
81
- expected_checksum = (frame_number + data).each_byte.inject(16) { |a,b| (a+b) % 0x100 }
82
- actual_checksum = checksum.to_i(16)
83
-
84
- raise "checksum mismatch" unless expected_checksum == actual_checksum
85
- return [frame_number.to_i, data]
86
- end
87
-
88
- def self.wrap_message(string, frame_number)
89
- frame_number = (frame_number % 8).to_s
90
- checksum = (frame_number + string).each_byte.inject(16) { |a,b| (a+b) % 0x100 }
91
- checksum = checksum.to_s(16).upcase.rjust(2,"0")
92
-
93
- "\002#{frame_number}#{string}\015\003#{checksum}\015\012"
94
- end
95
-
96
-
97
- def received_message(message)
98
- return false unless @inside_transmission
99
- frame_number, message = *self.class.message_from_string(message)
100
- forward(:message, message)
101
- end
102
-
103
- def transmission_start
104
- return false if @inside_transmission
105
- write :ack
106
- forward :begin
107
- @inside_transmission = true
108
- true
109
- end
110
-
111
- def transmission_end
112
- return false unless @inside_transmission
113
- forward :idle
114
- @inside_transmission = false
115
- true
116
- end
117
- end
118
-
119
- end