simple_hl7 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in simple_hl7.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Rome Portlock
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # SimpleHl7
2
+
3
+ SimpleHL7 is a library that manages HL7 v2.x documents for interfacing with
4
+ health care systems. The goal of SimpleHL7 is to make it easy to create basic
5
+ HL7 messages while also having the power to create more complex ones. SimpleHL7
6
+ is agnostic of message and segment types, it works only with the basic
7
+ structure of HL7 documents.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'simple_hl7'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install simple_hl7
22
+
23
+ ## Usage
24
+
25
+ SimpleHL7 can be used for either message creation or parsing.
26
+
27
+ ### Message Creation
28
+
29
+ A simple example:
30
+
31
+ ```ruby
32
+ msg = SimpleHL7::Message.new
33
+ msg.msh[9][1] = "ADT"
34
+ msg.msh[9][2] = "A04"
35
+ msg.msh[10] = "12345678"
36
+ msg.msh[11] = "D"
37
+ msg.msh[12] = "2.5"
38
+
39
+ msg.pid[3] = "454545"
40
+ msg.pid[5][1] = "Doe"
41
+ msg.pid[5][2] = "John"
42
+
43
+ msg.pv1[2] = "O"
44
+
45
+ msg.to_hl7
46
+ ```
47
+
48
+ Would generate the following HL7 string.
49
+
50
+ ```
51
+ MSH|^~\&|||||||ADT^A04|12345678|D|2.5
52
+ PID|||454545||Doe^John
53
+ PV1||O
54
+ ```
55
+
56
+ This is the easiest way to use SimpleHL7, however most of the methods used
57
+ above are syntactic sugar for underlying methods that are explained in detail
58
+ later.
59
+
60
+ ### Adding a segment
61
+
62
+ The easiest way to add a segment to a new message is by calling its three
63
+ letter segment name as a method on the message. For example to create a PID
64
+ segment, do the following:
65
+
66
+ ```ruby
67
+ msg = SimpleHL7::Message.new
68
+ msg.pid
69
+ ```
70
+
71
+ Note that since the MSH segment is always required it is created automatically.
72
+ So if to_hl7 was called on the message above, the result would be
73
+
74
+ ```
75
+ MSH|^~\&|
76
+ PID
77
+ ```
78
+
79
+ ### Repeating segments
80
+
81
+ Using the segment name is the easiest way to create a new segment, but if you
82
+ have more than one segment with the same name it won't work. The first name
83
+ method call will create a segment, but subsequent calls will just reference
84
+ that first created segment.
85
+
86
+ To create multiple segments of the same type use the underlying `add_segment`
87
+ method.
88
+
89
+ ```ruby
90
+ obx1 = msg.add_segment('obx')
91
+ obx2 = msg.add_segment('obx')
92
+ ```
93
+
94
+ To later retreive a certain segment use the `segment` method.
95
+
96
+ ```
97
+ obx2 = msg.segment('obx', 2)
98
+ ```
99
+
100
+ ### Adding components, subcomponents, fields etc.
101
+
102
+ To add values to the message just specifiy the index in brackets
103
+
104
+ ```ruby
105
+ msg = SimpleHL7::Message.new
106
+ msg.msh[12] = '2.5'
107
+ ```
108
+
109
+ To specifiy a certain component use more brackets.
110
+
111
+ ```ruby
112
+ msg = SimpleHL7::Message.new
113
+ msg.msh[9][1] = "ADT"
114
+ msg.msh[9][2] = "A04"
115
+ ```
116
+
117
+ It is important to note that under the hood the the bracket syntax actually
118
+ adds the value to the first subcomponent of the first componenet of the first
119
+ repition in the specified field.
120
+
121
+ This means that:
122
+
123
+ ```ruby
124
+ msg.msh[9] = "ADT"
125
+ msg.msh[9][1] = "ADT"
126
+ msg.msh[9][1][1] = "ADT"
127
+ ```
128
+
129
+ are all equivalent.
130
+
131
+ ### Repeating fields
132
+
133
+ Since repeating fields are less common in HL7 they require a little bit of
134
+ extra work to create using SimpleHL7. Use the `r(index)` method to create
135
+ repeats.
136
+
137
+ ```ruby
138
+ msg.pid[13] = '123-4567'
139
+ msg.pid[13].r(2)[1] = '876-5432'
140
+ ```
141
+
142
+ Creates the following PID segment
143
+
144
+ ```
145
+ PID|||||||||||||123-4567~876-5432
146
+ ```
147
+
148
+ ### HL7 Escaping
149
+
150
+ HL7 special characters are automatically escaped properly when generating HL7,
151
+ without doing any extra work.
152
+
153
+ ```ruby
154
+ msg = SimpleHL7::Message.new
155
+ msg.nte[3] = "Testing & escaping notes"
156
+ msg.to_hl7
157
+ ```
158
+
159
+ Outputs:
160
+
161
+ ```
162
+ MSH|^~\&|
163
+ NTE|||Testing \T\ escaping notes
164
+ ```
165
+
166
+ ### Parsing
167
+
168
+ To parse HL7 string use the parse method
169
+
170
+ ```ruby
171
+ hl7_str = "MSH|^~\\&|||||||ADT^A04|12345678|D|2.5\rPID|||454545||Doe^John"
172
+ msg = SimpleHL7::Message.parse(hl7_str)
173
+ ```
174
+
175
+ Once the message is parsed use to_s to pull out values
176
+
177
+ ```ruby
178
+ msg.pid[5][1].to_s
179
+ => "Doe"
180
+ ```
181
+
182
+ ## Contributing
183
+
184
+ 1. Fork it
185
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
186
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
187
+ 4. Push to the branch (`git push origin my-new-feature`)
188
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/lib/simple_hl7.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "simple_hl7/version"
2
+
3
+ module SimpleHL7
4
+ # Your code goes here...
5
+ end
6
+
7
+ require "simple_hl7/separator_characters"
8
+ require "simple_hl7/composite"
9
+ require "simple_hl7/subcomponent"
10
+ require "simple_hl7/component"
11
+ require "simple_hl7/component_container"
12
+ require "simple_hl7/field"
13
+ require "simple_hl7/segment"
14
+ require "simple_hl7/msh_segment"
15
+ require "simple_hl7/message"
@@ -0,0 +1,11 @@
1
+ module SimpleHL7
2
+ class Component < Composite
3
+ def self.current_separator_char(separator_chars)
4
+ separator_chars.subcomponent
5
+ end
6
+
7
+ def self.subcomposite_class
8
+ Subcomponent
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module SimpleHL7
2
+ class ComponentContainer < Composite
3
+ def self.current_separator_char(separator_chars)
4
+ separator_chars.component
5
+ end
6
+
7
+ def self.subcomposite_class
8
+ Component
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,170 @@
1
+ module SimpleHL7
2
+ # Generic building block of a HL7 message. The parts of the message
3
+ # subclass this, and this class does most of the work.
4
+ class Composite
5
+ # Constructor
6
+ #
7
+ # @param value [String] a value that is passed down to the subclass
8
+ # constructor. This allows us to set values on top level components that
9
+ # are passed down to the lowest component. Default nil.
10
+ def initialize(value = nil)
11
+ @subcomposites = {}
12
+ cls = self.class
13
+ unless value.nil?
14
+ @subcomposites[cls.start_index] = cls.subcomposite_class.new(value)
15
+ end
16
+ end
17
+
18
+ # Set the value of the specified subcomposite.
19
+ # The value is actually passed down to the first subcomposite of the
20
+ # specified subcomposite and so on until it reaches a Subcomponent
21
+ # composite.
22
+ #
23
+ # @param index [Integer] the subcomposite index.
24
+ # @param value [String] the value to set.
25
+ def []=(index, value)
26
+ set_subcomposite(index, self.class.subcomposite_class.new(value))
27
+ end
28
+
29
+ # Get a specific subcomposite.
30
+ #
31
+ # @param index [Integer] The index of the subcomposite.
32
+ # @return [Subcomposite] The subcomposite at index or a new subcomposite
33
+ # if none exists. Note that this returns the Subcomposite object and not
34
+ # the string value. This differs from how []= works, but it seems to make
35
+ # the most sense when dealing with HL7 messages.
36
+ def [](index)
37
+ get_subcomposite(index)
38
+ end
39
+
40
+ # Alias for []
41
+ def get_subcomposite(index)
42
+ subcomposite = @subcomposites[index]
43
+ if subcomposite.nil?
44
+ subcomposite = self.class.subcomposite_class.new
45
+ set_subcomposite(index, subcomposite)
46
+ end
47
+ subcomposite
48
+ end
49
+
50
+ # Sets a specific subcomposite
51
+ #
52
+ # @param index [Integer] the indexs of the subcomposite, if there is an
53
+ # existing compsite at the location it is replaced.
54
+ # @param value [Subcomposite] the new subcomposite object for the
55
+ # specified location.
56
+ def set_subcomposite(index, value)
57
+ @subcomposites[index] = value
58
+ end
59
+
60
+ # Calls the specified block once for each index between the start index
61
+ # and the max specified subcomposite index.
62
+ #
63
+ # @yeild [subcomposite] Gives the subcomposite at the current index to the
64
+ # block. If there isn't a subcomposite specified for the index then nil
65
+ # is passed.
66
+ def each
67
+ start = self.class.start_index
68
+ (start..max_index).each { |i| yield @subcomposites[i] } if max_index
69
+ end
70
+
71
+ # Calls the specified block once for each index between the start index
72
+ # and the max specified subcomposite index and returns an array resulting
73
+ # from the return values of each block.
74
+ #
75
+ # @yeild [subcomposite] Gives the subcomposite at the current index to the
76
+ # block. If there isn't a subcomposite specified for the index then nil
77
+ # is passed.
78
+ def map
79
+ start = self.class.start_index
80
+ (start..max_index).map { |i| yield @subcomposites[i] } if max_index
81
+ end
82
+
83
+ # Get a HL7 string representation of this Composite.
84
+ #
85
+ # @separator_chars [SeparatorChars] The separator characters to be used
86
+ # when converting this Composite to a string of HL7.
87
+ def to_hl7(separator_chars)
88
+ sep_char = self.class.current_separator_char(separator_chars)
89
+ map { |subc| subc.to_hl7(separator_chars) if subc }.join(sep_char)
90
+ end
91
+
92
+ # Get the value stored at the first Subcomponent below this Composite
93
+ def to_s
94
+ @subcomposites[self.class.start_index].to_s
95
+ end
96
+
97
+ # Get all the subcomposites as an array. Note that this array has the
98
+ # actual subcomposite object and not clones, so any changes will affect
99
+ # this class as well.
100
+ def to_a
101
+ a = []
102
+ each {|subc| a << subc}
103
+ a
104
+ end
105
+
106
+ # The index where the first subcomposite is located. This is usually either
107
+ # 1 or 0 depending on the specific Composite.
108
+ def self.start_index
109
+ 1
110
+ end
111
+
112
+ # @abstract The character that is used to separate the subcomposites when
113
+ # generating a HL7 string.
114
+ #
115
+ # @param separator_chars [SeparatorChars] The separator characters in use
116
+ # during the HL7 string conversion.
117
+ def self.current_separator_char(separator_chars)
118
+ raise Exception.new("Subclass Responsibility")
119
+ end
120
+
121
+ # @abstract The class that is used for subcomposites.
122
+ def self.subcomposite_class
123
+ raise Exception.new("Subclass Responsibility")
124
+ end
125
+
126
+ # Create a composite from a HL7 string.
127
+ #
128
+ # @param str [String] The string of HL7.
129
+ # @param separator_chars [SeparatorChars] The separator characters used
130
+ # in the HL7 string.
131
+ # @return [Composite] The parsed composite.
132
+ def self.parse(str, separator_chars)
133
+ composite = new
134
+ parse_subcomposite_hash(str, separator_chars).each do |index, subc|
135
+ composite.set_subcomposite(start_index + index, subc)
136
+ end
137
+ composite
138
+ end
139
+
140
+ private
141
+
142
+ def max_index
143
+ @subcomposites.keys.max
144
+ end
145
+
146
+ class << self
147
+ private
148
+
149
+ # Parses the subcomposites of a HL7 string into a hash
150
+ #
151
+ # @param str [String] The HL7 string to parse.
152
+ # @param separator_chars [SeparatorChars] The separator characters used in
153
+ # the HL7 string.
154
+ # @return A hash of composites, one for each subcomposite in the string
155
+ # that actually had a value. Empty subcomposites are left out of the
156
+ # hash.
157
+ def parse_subcomposite_hash(str, separator_chars)
158
+ subc_strs = str.split(current_separator_char(separator_chars))
159
+ subc_h = {}
160
+ subc_strs.each_with_index do |subc_str, index|
161
+ unless subc_str.empty?
162
+ subc_h[index] = subcomposite_class.parse(subc_str, separator_chars)
163
+ end
164
+ end
165
+ subc_h
166
+ end
167
+ end
168
+
169
+ end
170
+ end
@@ -0,0 +1,23 @@
1
+ module SimpleHL7
2
+ class Field < Composite
3
+ def self.current_separator_char(separator_chars)
4
+ separator_chars.repetition
5
+ end
6
+
7
+ def self.subcomposite_class
8
+ ComponentContainer
9
+ end
10
+
11
+ def []=(index, value)
12
+ get_subcomposite(1)[index] = value
13
+ end
14
+
15
+ def [](index)
16
+ get_subcomposite(1)[index]
17
+ end
18
+
19
+ def r(index)
20
+ get_subcomposite(index)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,74 @@
1
+ module SimpleHL7
2
+ class Message
3
+ def initialize(default_msh = true)
4
+ @segments = []
5
+ @segments << MSHSegment.new if default_msh
6
+ end
7
+
8
+ def method_missing(meth, *args, &block)
9
+ if meth.to_s =~ /^[a-zA-Z][a-zA-Z0-9]{2}$/
10
+ get_named_segment(meth)
11
+ elsif meth.to_s =~ /^[a-zA-Z][a-zA-Z0-9]{2}_all$/
12
+ seg_name = meth[0..3]
13
+ all_segments(seg_name)
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ def to_hl7
20
+ separator_chars = get_named_segment('MSH').separator_chars
21
+ @segments.map {|s| s.to_hl7(separator_chars)}.join("\r")
22
+ end
23
+
24
+ def to_a
25
+ @segments.reduce([]) {|a, s| a << s.to_a}
26
+ end
27
+
28
+ def segment(name, index=1)
29
+ all = all_segments(name)
30
+ seg = nil
31
+ seg = all[index - 1] if all.size >= index
32
+ seg
33
+ end
34
+
35
+ def add_segment(name)
36
+ segment = Segment.new(name)
37
+ @segments << segment
38
+ segment
39
+ end
40
+
41
+ def append_segment(segment)
42
+ @segments << segment
43
+ segment
44
+ end
45
+
46
+ private
47
+
48
+ def all_segments(name)
49
+ @segments.select {|seg| seg.name == name}
50
+ end
51
+
52
+
53
+ def get_named_segment(name)
54
+ name_str = name.to_s.upcase
55
+ segment = @segments.select {|seg| seg.name == name_str}.first
56
+ unless segment
57
+ segment = Segment.new(name_str)
58
+ @segments << segment
59
+ end
60
+ segment
61
+ end
62
+
63
+ def self.parse(str)
64
+ msg = new(false)
65
+ segment_strs = str.split("\r")
66
+ msh = MSHSegment.parse(segment_strs[0])
67
+ msg.append_segment(msh)
68
+ segment_strs[1, segment_strs.length].each do |seg_str|
69
+ msg.append_segment(Segment.parse(seg_str, msh.separator_chars))
70
+ end
71
+ msg
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,38 @@
1
+ module SimpleHL7
2
+ class MSHSegment < Segment
3
+ def initialize
4
+ super('MSH')
5
+ self[1] = '|'
6
+ self[2] = '^~\&'
7
+ end
8
+
9
+ def separator_chars
10
+ enc_chars = @subcomposites[2].to_s
11
+ SeparatorCharacters.new(@subcomposites[1].to_s,
12
+ enc_chars[0],
13
+ enc_chars[1],
14
+ enc_chars[2],
15
+ enc_chars[3])
16
+ end
17
+
18
+ def self.parse(str)
19
+ msh = new
20
+ msh[1] = str[3]
21
+ msh[2] = str[4..7]
22
+
23
+ fields = parse_subcomposite_hash(str[9, str.length], msh.separator_chars)
24
+ fields.each { |index, subc| msh.set_subcomposite(index + 3, subc) }
25
+ msh
26
+ end
27
+
28
+ def to_hl7(separator_chars)
29
+ sep_char = self.class.current_separator_char(separator_chars)
30
+ base_msh = "#{name}#{self[1]}#{self[2]}"
31
+ max_index = @subcomposites.keys.max
32
+ rest_msh = (3..max_index).map { |i|
33
+ @subcomposites[i].to_hl7(separator_chars) if @subcomposites[i]
34
+ }.join(sep_char)
35
+ [base_msh, rest_msh].join(sep_char)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ module SimpleHL7
2
+ class Segment < Composite
3
+ def self.start_index
4
+ 0
5
+ end
6
+
7
+ def self.subcomposite_class
8
+ Field
9
+ end
10
+
11
+ def self.current_separator_char(separator_chars)
12
+ separator_chars.field
13
+ end
14
+
15
+ def name
16
+ self[0].to_s
17
+ end
18
+
19
+ def to_a
20
+ super.insert(0, name)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ module SimpleHL7
2
+ class SeparatorCharacters < Struct.new(:field, :component, :repetition,
3
+ :escape, :subcomponent)
4
+ def self.defaults
5
+ SeparatorCharacters.new('|', '^', '~', '\\', '&')
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ module SimpleHL7
2
+ class Subcomponent < Struct.new(:value)
3
+ def to_hl7(separator_chars)
4
+ hl7 = value
5
+ hl7.gsub!(separator_chars.escape, "\\E\\")
6
+ hl7.gsub!(separator_chars.field, "\\F\\")
7
+ hl7.gsub!(separator_chars.repetition, "\\R\\")
8
+ hl7.gsub!(separator_chars.component, "\\S\\")
9
+ hl7.gsub!(separator_chars.subcomponent, "\\T\\")
10
+ hl7
11
+ end
12
+
13
+ def to_s
14
+ value
15
+ end
16
+
17
+ def self.parse(str, separator_chars)
18
+ value = str
19
+ value.gsub!("\\E\\", separator_chars.escape)
20
+ value.gsub!("\\F\\", separator_chars.field)
21
+ value.gsub!("\\R\\", separator_chars.repetition)
22
+ value.gsub!("\\S\\", separator_chars.component)
23
+ value.gsub!("\\T\\", separator_chars.subcomponent)
24
+ Subcomponent.new(value)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleHL7
2
+ VERSION = "0.1.2"
3
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/simple_hl7/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Rome Portlock"]
6
+ gem.email = ["rome@alivecor.com"]
7
+ gem.description = %q{Parse and generate hl7 messages for interfacing with health care systems}
8
+ gem.summary = %q{Parse and generate hl7 messages}
9
+ gem.homepage = "https://github.com/alivecor/simple_hl7"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "simple_hl7"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = SimpleHL7::VERSION
17
+
18
+ gem.add_development_dependency "pry", "~> 0.9"
19
+ gem.add_development_dependency "rspec", "~> 2.14"
20
+ end
@@ -0,0 +1,22 @@
1
+ require "simple_hl7"
2
+
3
+ module SimpleHL7
4
+ describe ComponentContainer do
5
+ describe "#to_hl7" do
6
+ it "generates proper hl7 for a field with subfields" do
7
+ container = ComponentContainer.new
8
+ container[1] = "foo"
9
+ container[2] = "bar"
10
+ container.to_hl7(SeparatorCharacters.defaults).should == "foo^bar"
11
+ end
12
+
13
+ it "generates proper hl7 for a field with components and subfields" do
14
+ container = ComponentContainer.new
15
+ container[1] = "foo"
16
+ container[1][2] = "bar"
17
+ container[2] = "baz"
18
+ container.to_hl7(SeparatorCharacters.defaults).should == "foo&bar^baz"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ require "simple_hl7"
2
+
3
+ module SimpleHL7
4
+ describe Component do
5
+ describe "#to_hl7" do
6
+ it "generates proper hl7 for a field with subfields" do
7
+ field = Component.new
8
+ field[1] = "foo"
9
+ field[2] = "bar"
10
+ field.to_hl7(SeparatorCharacters.defaults).should == "foo&bar"
11
+ end
12
+ end
13
+
14
+ describe "[]" do
15
+ it "gets the proper value" do
16
+ field = Component.new
17
+ field[1] = "foo"
18
+ field[1].to_s.should == "foo"
19
+ end
20
+ end
21
+
22
+ describe "#parse" do
23
+ it "parse hl7 correctly" do
24
+ component = Component.parse("foo&bar", SeparatorCharacters.defaults)
25
+ component[1].to_s.should == "foo"
26
+ component[2].to_s.should == "bar"
27
+ end
28
+ end
29
+ end
30
+ end
File without changes
@@ -0,0 +1,15 @@
1
+ require "simple_hl7"
2
+
3
+ module SimpleHL7
4
+ describe Field do
5
+ describe "#to_hl7" do
6
+ it "generates proper hl7 for a field with subfields" do
7
+ field = Field.new
8
+ field[1] = "foo"
9
+ field[2] = "baz"
10
+ field.r(2)[1] = "bar"
11
+ field.to_hl7(SeparatorCharacters.defaults).should == 'foo^baz~bar'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ require "simple_hl7"
2
+
3
+ module SimpleHL7
4
+ describe Message do
5
+ describe "#to_hl7" do
6
+ it "generates an hl7 message" do
7
+ msg = Message.new
8
+ msg.msh[6] = "accountid"
9
+ msg.pid[5] = "User"
10
+ msg.pid[5][2] = "Test"
11
+ msg.to_hl7.should == "MSH|^~\\&||||accountid\rPID|||||User^Test"
12
+ end
13
+ end
14
+
15
+ describe "#add_segment" do
16
+ it "adds segments properly" do
17
+ msg = Message.new
18
+ obx_1 = msg.add_segment('OBX')
19
+ obx_1[1] = "1"
20
+ obx_2 = msg.add_segment('OBX')
21
+ obx_2[1] = "2"
22
+ msg.segment('OBX', 1)[1].to_s.should == "1"
23
+ msg.segment('OBX', 2)[1].to_s.should == "2"
24
+ end
25
+ end
26
+
27
+ describe "#parse" do
28
+ it "properly parses a hl7 string" do
29
+ msg = Message.parse("MSH|^~\\&||||accountid\rPID|||||User^Test~Repeat")
30
+ msg.msh[6].to_s.should == "accountid"
31
+ msg.pid[5].to_s.should == "User"
32
+ msg.pid[5][2].to_s.should == "Test"
33
+ msg.pid[5].r(2)[1].to_s.should == "Repeat"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ require "simple_hl7"
2
+
3
+ module SimpleHL7
4
+ describe MSHSegment do
5
+ describe "#parse" do
6
+ it "parses a hl7 string correctly" do
7
+ msh = MSHSegment.parse('MSH|^~\\&|||test')
8
+ msh.separator_chars.field.should == '|'
9
+ msh[5].to_s.should == 'test'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ require "pry"
2
+ require "simple_hl7"
3
+
4
+ module SimpleHL7
5
+ describe Segment do
6
+ describe "#to_hl7" do
7
+ it "generates a message using the specified separator chars" do
8
+ sep_chars = SeparatorCharacters.defaults
9
+ seg = Segment.new('PID')
10
+ seg[5] = 'test'
11
+ seg.to_hl7(sep_chars).should == 'PID|||||test'
12
+ end
13
+ end
14
+
15
+ describe "#parse" do
16
+ it "parses a hl7 string correctly" do
17
+ sep_chars = SeparatorCharacters.defaults
18
+ seg = Segment.parse('PID|||||test', sep_chars)
19
+ seg[5].to_s.should == 'test'
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ require "simple_hl7"
2
+
3
+ module SimpleHL7
4
+ describe Subcomponent do
5
+ describe "#to_hl7" do
6
+ it "returns the value" do
7
+ subf = Subcomponent.new('test')
8
+ subf.to_hl7(SeparatorCharacters.defaults).should == 'test'
9
+ end
10
+
11
+ it "escapes special characters in a string" do
12
+ subc = Subcomponent.new('peas&carrots')
13
+ subc.to_hl7(SeparatorCharacters.defaults).should == 'peas\T\carrots'
14
+ end
15
+
16
+ it "escapes all special characters" do
17
+ subc = Subcomponent.new('\\&^~|')
18
+ default_chars = SeparatorCharacters.defaults
19
+ subc.to_hl7(default_chars).should == "\\E\\\\T\\\\S\\\\R\\\\F\\"
20
+ end
21
+ end
22
+
23
+ describe "#parse" do
24
+ it "should unescape the special characters" do
25
+ str = "\\E\\\\T\\\\S\\\\R\\\\F\\"
26
+ default_chars = SeparatorCharacters.defaults
27
+ parsed = Subcomponent.parse(str, default_chars)
28
+ parsed.to_s.should == '\\&^~|'
29
+ end
30
+ end
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_hl7
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rome Portlock
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: pry
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.9'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '0.9'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.14'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.14'
46
+ description: Parse and generate hl7 messages for interfacing with health care systems
47
+ email:
48
+ - rome@alivecor.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE
56
+ - README.md
57
+ - Rakefile
58
+ - lib/simple_hl7.rb
59
+ - lib/simple_hl7/component.rb
60
+ - lib/simple_hl7/component_container.rb
61
+ - lib/simple_hl7/composite.rb
62
+ - lib/simple_hl7/field.rb
63
+ - lib/simple_hl7/message.rb
64
+ - lib/simple_hl7/msh_segment.rb
65
+ - lib/simple_hl7/segment.rb
66
+ - lib/simple_hl7/separator_characters.rb
67
+ - lib/simple_hl7/subcomponent.rb
68
+ - lib/simple_hl7/version.rb
69
+ - simple_hl7.gemspec
70
+ - spec/simple_hl7/component_container_spec.rb
71
+ - spec/simple_hl7/component_spec.rb
72
+ - spec/simple_hl7/composite_spec.rb
73
+ - spec/simple_hl7/field_spec.rb
74
+ - spec/simple_hl7/message_spec.rb
75
+ - spec/simple_hl7/msh_segment_spec.rb
76
+ - spec/simple_hl7/segment_spec.rb
77
+ - spec/simple_hl7/subcomponent_spec.rb
78
+ homepage: https://github.com/alivecor/simple_hl7
79
+ licenses: []
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.24
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Parse and generate hl7 messages
102
+ test_files:
103
+ - spec/simple_hl7/component_container_spec.rb
104
+ - spec/simple_hl7/component_spec.rb
105
+ - spec/simple_hl7/composite_spec.rb
106
+ - spec/simple_hl7/field_spec.rb
107
+ - spec/simple_hl7/message_spec.rb
108
+ - spec/simple_hl7/msh_segment_spec.rb
109
+ - spec/simple_hl7/segment_spec.rb
110
+ - spec/simple_hl7/subcomponent_spec.rb