transformator 0.1.4 → 1.0.0.pre1

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -2
  3. data/Rakefile +0 -43
  4. data/bin/transformator +4 -0
  5. data/lib/transformator.rb +13 -29
  6. data/lib/transformator/cli.rb +42 -0
  7. data/lib/transformator/dispatcher.rb +43 -0
  8. data/lib/transformator/filesystem_pattern_evaluator.rb +14 -0
  9. data/lib/transformator/gzip_reader.rb +0 -0
  10. data/lib/transformator/gzip_writer.rb +0 -0
  11. data/lib/transformator/null_processor.rb +9 -0
  12. data/lib/transformator/oga_xml_dumper.rb +10 -0
  13. data/lib/transformator/oga_xml_parser.rb +10 -0
  14. data/lib/transformator/ox_xml_dumper.rb +10 -0
  15. data/lib/transformator/ox_xml_parser.rb +10 -0
  16. data/lib/transformator/parallel_processor.rb +39 -0
  17. data/lib/transformator/processor.rb +4 -0
  18. data/lib/transformator/tar_reader.rb +51 -0
  19. data/lib/transformator/tar_reader/patched_rubygems_tar_reader.rb +41 -0
  20. data/lib/transformator/tar_writer.rb +0 -0
  21. data/lib/transformator/version.rb +1 -1
  22. data/spec/spec_helper.rb +0 -1
  23. data/spec/transformator_spec.rb +0 -8
  24. data/transformator.gemspec +7 -6
  25. data/ubpb.yml.erb +25 -0
  26. metadata +49 -67
  27. data/assets/primo_search_response.xml +0 -2878
  28. data/assets/primo_search_response_1.xml +0 -2467
  29. data/examples/primo_search_response_transformation.rb +0 -123
  30. data/examples/search_request_transformation.rb +0 -89
  31. data/lib/transformator/dsl.rb +0 -93
  32. data/lib/transformator/format_converter.rb +0 -27
  33. data/lib/transformator/format_converter/document_from_hash.rb +0 -13
  34. data/lib/transformator/format_converter/document_from_object.rb +0 -20
  35. data/lib/transformator/format_converter/document_from_xml.rb +0 -28
  36. data/lib/transformator/format_converter/hash_from_document.rb +0 -61
  37. data/lib/transformator/format_converter/xml_from_document.rb +0 -7
  38. data/lib/transformator/transformation.rb +0 -91
  39. data/spec/examples/primo_search_response_transformation_spec.rb +0 -19
  40. data/spec/examples/search_request_transformation_spec.rb +0 -48
  41. data/spec/transformator/dsl_spec.rb +0 -187
  42. data/spec/transformator/format_converter/hash_from_document_spec.rb +0 -42
  43. data/spec/transformator/transformation_spec.rb +0 -112
@@ -1,7 +0,0 @@
1
- require "ox"
2
-
3
- module Transformator::FormatConverter::XmlFromDocument
4
- def xml_from_document(document, options = {})
5
- Ox.dump(document, { }.merge(options))
6
- end
7
- end
@@ -1,91 +0,0 @@
1
- require "ox"
2
- require "transformator/dsl"
3
-
4
- class Transformator::Transformation
5
- def initialize(options = {}, &block)
6
- # make it possible to initialize a transformation with external data
7
- options.each_pair do |key, value|
8
- instance_variable_set "@#{key}".to_sym, value
9
- end
10
-
11
- @rules = []
12
- self.instance_eval(&block) if block
13
- end
14
-
15
- #
16
- public
17
- #
18
- def apply(options = {})
19
- source = Transformator.document_from_object(options[:source] ||= options[:to])
20
- target = Transformator.document_from_object(options[:target])
21
-
22
- @rules.each do |rule|
23
- block = rule[:callable]
24
- path = rule[:path]
25
- type = rule[:type]
26
-
27
- # allow user to set source/target freely
28
- _source =
29
- if (source_callable = rule[:source]).respond_to?(:call)
30
- source_callable.call
31
- else
32
- source
33
- end
34
-
35
- _target =
36
- if (target_callable = rule[:target]).respond_to?(:call)
37
- target_callable.call
38
- else
39
- target
40
- end
41
-
42
- if type == :process
43
- if path.is_a?(Array)
44
- block.call(
45
- path.map do |_path| { _path => find_all(_source, _path) } end,
46
- _target
47
- )
48
- elsif path.is_a?(String)
49
- find_all(_source, path).each do |element_to_process|
50
- block.call(element_to_process, _target)
51
- end
52
- elsif path.is_a?(Symbol)
53
- if path == :document
54
- block.call(_source, _target)
55
- elsif path == :none
56
- block.call
57
- elsif path == :source
58
- block.call(source, _target)
59
- elsif path == :target
60
- block.call(target, _target)
61
- end
62
- end
63
- end
64
- end
65
-
66
- case options[:output_format] || @output_format || Transformator.determine_format(options[:source])
67
- when :hash then Transformator.hash_from_document(target)
68
- when :ox_document then target
69
- when :xml then Ox.dump(target, with_xml: true)
70
- else raise "Unknown output format!"
71
- end
72
- end
73
-
74
- #
75
- private
76
- #
77
- include Transformator::Dsl
78
-
79
- def before_apply(options = {}, &block)
80
- @rules.unshift({ callable: block, path: :none, type: :process}.merge(options))
81
- end
82
-
83
- def output_format(format)
84
- @output_format = format.to_sym
85
- end
86
-
87
- def process(path, options = {}, &block)
88
- @rules.push({ callable: block, path: path, type: :process}.merge(options))
89
- self
90
- end
91
- end
@@ -1,19 +0,0 @@
1
- require_relative "../../examples/primo_search_response_transformation"
2
-
3
- describe "Examples" do
4
- let(:primo_search_response) do
5
- File.read(
6
- File.expand_path(
7
- File.join(
8
- File.dirname(__FILE__), "../../assets/primo_search_response_1.xml"
9
- )
10
- )
11
- )
12
- end
13
-
14
- it "transforms primo search response" do
15
- Transformator::Examples::PrimoSearchResponseTransformation.apply(to: primo_search_response, output_format: :hash).tap do |w|
16
- # binding.pry
17
- end
18
- end
19
- end
@@ -1,48 +0,0 @@
1
- require_relative "../../examples/search_request_transformation"
2
-
3
- describe "Examples" do
4
- let(:search_request_hash) do
5
- {
6
- from: 0,
7
- size: 20,
8
- query: {
9
- bool: {
10
- must: [
11
- {
12
- query_string: {
13
- query: "linux",
14
- default_operator: "AND",
15
- fields: [
16
- "title^2",
17
- "_all"
18
- ]
19
- }
20
- },
21
- {
22
- query_string: {
23
- query: "kofler",
24
- default_operator: "AND",
25
- fields: [
26
- "creator"
27
- ]
28
- }
29
- },
30
- {
31
- range: {
32
- lsr09: {
33
- gte: 20140101
34
- }
35
- }
36
- }
37
- ]
38
- }
39
- },
40
- }
41
- end
42
-
43
- it "transforms search request to primo soap body" do
44
- Transformator::Examples::SearchRequestTransformation.apply(to: search_request_hash, output_format: :xml).tap do |w|
45
- # binding.pry
46
- end
47
- end
48
- end
@@ -1,187 +0,0 @@
1
- describe Transformator::Dsl do
2
- let(:dsl) do
3
- Module.new.extend(described_class)
4
- end
5
-
6
- #
7
- # array
8
- #
9
- describe "#array" do
10
- it "creates a new element with attribute \"type\" == \"array\"" do
11
- expect(dsl.array(:foo)["type"]).to eq("array")
12
- end
13
-
14
- context "when called with a block" do
15
- describe "passes an array accumulator to the block" do
16
- it "allows appending elements to the array so that it's activesupport Hash.from_xml compatble" do
17
- array_with_one_element = dsl.array(:foo) do |arr|
18
- arr << dsl.element(:bar)
19
- end
20
-
21
- expect(dsl.find(array_with_one_element, "foo/bar")).not_to be_nil
22
- end
23
- end
24
- end
25
- end
26
-
27
- #
28
- # element
29
- #
30
- describe "#element" do
31
- it "creates a new element with the given name" do
32
- expect(dsl.element(:foo).value).to eq("foo")
33
- end
34
-
35
- context "when called with an \"attributes\" option" do
36
- it "sets the attributes of the newly created element accordingly" do
37
- attributes = { attr1: 1, attr2: "2", "attr3" => true }
38
- expect(dsl.element(:foo, attributes: attributes).attributes).to eq({
39
- "attr1" => "1",
40
- "attr2" => "2",
41
- "attr3" => "true"
42
- })
43
- end
44
- end
45
-
46
- context "when called with a \"text\" option" do
47
- it "adds a text node to the newly created element" do
48
- expect(dsl.element(:foo, text: "bar").text).to eq("bar")
49
- end
50
- end
51
-
52
- context "when called with a \"type\" option" do
53
- it "adds an attribute named \"type\" with the given value" do
54
- expect(dsl.element(:foo, text: 1, type: :integer).attributes).to include({"type" => "integer"})
55
- end
56
- end
57
- end
58
-
59
- #
60
- # elements_from_hash
61
- #
62
- describe "#elements_from_hash" do
63
- let(:hash) do
64
- {
65
- key1: "value1",
66
- key2: [
67
- {
68
- subkey: "subvalue"
69
- }
70
- ]
71
- }
72
- end
73
-
74
- it "creates elements from the given hash" do
75
- elements = dsl.elements_from_hash(hash)
76
- expect(elements[0].value).to eq("key1")
77
- expect(dsl.find(elements[1], "key2/subkey").text).to eq("subvalue") # key2 ist found due to the additional array element encoding
78
- end
79
- end
80
-
81
- #
82
- # elements_from_xml
83
- #
84
- describe "#elements_from_xml" do
85
- let(:xml) do
86
- <<-xml.strip_heredoc
87
- <key1>value1</key1>
88
- <key2>
89
- <subkey>subvalue</subkey>
90
- </key2>
91
- xml
92
- end
93
-
94
- it "creates elements from the given xml string" do
95
- elements = dsl.elements_from_xml(xml)
96
- expect(elements[0].value).to eq("key1")
97
- expect(dsl.find(elements[1], "subkey").text).to eq("subvalue")
98
- end
99
- end
100
-
101
- #
102
- # find
103
- #
104
- describe "#find" do
105
- let(:node) do
106
- dsl.element(:root) do |root|
107
- root << dsl.element(:foo, text: "1")
108
- root << dsl.element(:foo, text: "2")
109
- end
110
- end
111
-
112
- describe "is a shortcut for find_all(..)[0]" do
113
- context "when there are elements matching the given path" do
114
- it "returns the first element found" do
115
- expect(dsl.find(node, "foo").text).to eq("1")
116
- end
117
- end
118
-
119
- context "when there are no elements matching the given path" do
120
- it "returns nil" do
121
- expect(dsl.find(node, "nope")).to be_nil
122
- end
123
- end
124
- end
125
- end
126
-
127
- #
128
- # find_all
129
- #
130
- describe "#find_all" do
131
- let(:node) do
132
- dsl.element(:root) do |root|
133
- root << dsl.element(:foo, text: "1")
134
- root << dsl.element(:foo, text: "2")
135
- root << dsl.element(:bar) do |bar|
136
- bar << dsl.element(:muff) do |muff|
137
- muff << dsl.element(:key, text: "value")
138
- end
139
- end
140
- end
141
- end
142
-
143
- it "understands xpath like path expressions" do
144
- expect(dsl.find_all(node, "//key")).not_to be_nil
145
- end
146
-
147
- describe "finds all elements by the given path" do
148
- context "when there are elements matching the given path" do
149
- it "returns all elements found" do
150
- expect(dsl.find_all(node, "foo").map(&:text)).to eq(["1", "2"])
151
- end
152
- end
153
-
154
- context "when there are no elements matching the given path" do
155
- it "returns an empty array" do
156
- expect(dsl.find_all(node, "nope")).to eq([])
157
- end
158
- end
159
- end
160
-
161
- context "when called with a block" do
162
- context "when there are elements matching the given path" do
163
- it "calls the block with resulting array" do
164
- variable_changed_inside_block = false
165
-
166
- dsl.find_all(node, "foo") do |result|
167
- variable_changed_inside_block = true if result.length == 2
168
- end
169
-
170
- expect(variable_changed_inside_block).to be(true)
171
- end
172
- end
173
-
174
- context "when there are no elements matching the given path" do
175
- it "the block is not called" do
176
- variable_changed_inside_block = false
177
-
178
- dsl.find_all(node, "nope") do |foo|
179
- variable_changed_inside_block = true
180
- end
181
-
182
- expect(variable_changed_inside_block).to be(false)
183
- end
184
- end
185
- end
186
- end
187
- end
@@ -1,42 +0,0 @@
1
- describe Transformator::FormatConverter::HashFromDocument do
2
- let(:transformator) do
3
- Module.new.tap do |mod|
4
- mod.extend Transformator::FormatConverter::HashFromDocument
5
- mod.extend Transformator::FormatConverter::DocumentFromHash
6
- end
7
- end
8
-
9
- let(:hash) do
10
- {
11
- "key1" => "value1",
12
- "key2" => 1,
13
- "key3" => 1.5,
14
- "key4" => true,
15
- "key5" => nil,
16
- "key6" => {
17
- "key6_1" => "value6_1"
18
- },
19
- "key7" => [
20
- "1",
21
- 2,
22
- true,
23
- {
24
- "key_arr_obj1" => [
25
- "nested_element1",
26
- {
27
- "nested_key" => "nested_value"
28
- }
29
- ]
30
- }
31
- ]
32
- }
33
- end
34
-
35
- let(:document) do
36
- transformator.document_from_hash(hash)
37
- end
38
-
39
- it "converts a document to its corresponding hash" do
40
- expect(transformator.hash_from_document(document)).to eq(hash)
41
- end
42
- end
@@ -1,112 +0,0 @@
1
- describe Transformator::Transformation do
2
- let(:source_xml) do
3
- <<-xml.strip_heredoc
4
- <?xml version="1.0" encoding="UTF-8"?>
5
- <foo>
6
- <bar>muff</bar>
7
- </foo>
8
- xml
9
- end
10
-
11
- let(:transformed_xml) do
12
- <<-xml.strip_heredoc
13
- <?xml version="1.0" encoding="UTF-8"?>
14
- <muff>muff</muff>
15
- xml
16
- end
17
-
18
- describe ".new" do
19
- context "when called with an options hash" do
20
- let(:transformed_xml) do
21
- <<-xml.strip_heredoc
22
- <?xml version="1.0" encoding="UTF-8"?>
23
- <muff>value1</muff>
24
- xml
25
- end
26
-
27
- it "provides each key as an instance variable inside the transformation" do
28
- transformation = described_class.new(option1: "value1") do
29
- process "foo/bar" do |element, target|
30
- target << element("muff", text: @option1)
31
- end
32
- end
33
-
34
- expect(transformation.apply(to: source_xml)).to eq(transformed_xml)
35
- end
36
- end
37
-
38
- it "can be called with a block, containing the mapping described by the dsl" do
39
- transformation = described_class.new do
40
- process "foo/bar" do |element, target|
41
- target << element("muff", nodes: element.nodes)
42
- end
43
- end
44
-
45
- expect(transformation.apply(to: source_xml)).to eq(transformed_xml)
46
- end
47
- end
48
-
49
- describe "#before_apply" do
50
- let(:transformation) do
51
- described_class.new(data: "some_data") do
52
- process :target do |target|
53
- target << element("data", text: @foo)
54
- end
55
-
56
- # usually rules are executed in order as the are defined, but this one comes first
57
- before_apply do
58
- @foo = @data
59
- end
60
- end
61
- end
62
-
63
- it "executes the given block before applying the transformation" do
64
- transformed_document = transformation.apply(to: nil, output_format: :ox_document)
65
- expect(transformed_document.locate("data").first.text).to eq("some_data")
66
- end
67
- end
68
-
69
- describe "#output_format" do
70
- let(:transformation) do
71
- described_class.new do
72
- output_format :xml
73
- end
74
- end
75
-
76
- it "sets the default output format for the transformation" do
77
- expect(transformation.apply(to: {})).to start_with("<?xml")
78
- end
79
- end
80
-
81
- describe "#process" do
82
- context "when source responds to call" do
83
- let(:transformation) do
84
- described_class.new do
85
- process :none do
86
- @foo = element("foo") << element("bar", text: "muff")
87
- end
88
-
89
- process "*", source: -> { @foo } do |element, target|
90
- target << element
91
- end
92
- end
93
- end
94
-
95
- it "executes the rule with the callable result as the source" do
96
- expect(transformation.apply(to: nil, output_format: :ox_document).locate("bar").first.text).to eq("muff")
97
- end
98
- end
99
-
100
- context "when called with the special path :document" do
101
- it "provides the whole input document to the block" do
102
- transformation = described_class.new do
103
- process :document do |document, target|
104
- target << element("muff", nodes: ["muff"]) if document.nodes.empty?
105
- end
106
- end
107
-
108
- expect(transformation.apply(to: nil, output_format: :xml)).to eq(transformed_xml)
109
- end
110
- end
111
- end
112
- end