ki_middleman 0.0.13 → 1.0.0

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/.rspec CHANGED
@@ -1,2 +1,2 @@
1
1
  --color
2
- --format progress
2
+ --format nested
@@ -8,12 +8,14 @@ module KiMiddleman
8
8
  include Methadone::Main
9
9
  include Methadone::CLILogging
10
10
 
11
+ DEFAULT_TRANSFORMS_FILE = 'default_transforms.rb'
12
+ TRANSFORMS_FILE = 'transforms.rb'
13
+
11
14
  def self.init
12
15
  config_dir = Kiseru::ConfigDir.new
13
16
  assets_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'assets'))
14
- assets_file = File.join(assets_dir, 'default_transforms.rb')
15
- # TODO - duplicated file name here!
16
- new_file = config_dir.file('transforms.rb')
17
+ assets_file = File.join(assets_dir, DEFAULT_TRANSFORMS_FILE)
18
+ new_file = config_dir.file(TRANSFORMS_FILE)
17
19
  if File.exists?(new_file)
18
20
  $stdout.puts "Cannot write #{new_file}. File already exists."
19
21
  else
@@ -28,14 +30,14 @@ module KiMiddleman
28
30
  if options[:init]
29
31
  init
30
32
  elsif options[:list]
31
- config = KiMiddleman::Config.from_file(Kiseru::ConfigDir.new.file('transforms.rb'))
33
+ config = KiMiddleman::Config.from_file(Kiseru::ConfigDir.new.file(TRANSFORMS_FILE))
32
34
  $stdout.puts(config.textual_mapping)
33
35
  elsif options[:to]
34
36
  begin
35
37
  pretty = true
36
38
 
37
39
  output_type = options[:to]
38
- config = KiMiddleman::Config.from_file(Kiseru::ConfigDir.new.file('transforms.rb'))
40
+ config = KiMiddleman::Config.from_file(Kiseru::ConfigDir.new.file(TRANSFORMS_FILE))
39
41
  if options[:file]
40
42
  input = MultiJson.load(File.read(options[:file]))
41
43
  else
@@ -8,5 +8,6 @@ autoload :Kiseru, 'ki_middleman/kiseru'
8
8
  module KiMiddleman
9
9
 
10
10
  autoload :Config, 'ki_middleman/config'
11
+ autoload :TransformationsRenderer, 'ki_middleman/transformations_renderer'
11
12
 
12
13
  end
@@ -4,33 +4,21 @@ module KiMiddleman
4
4
 
5
5
  class Config
6
6
 
7
+ FROM_BLOCK_KEY = :outer_blocks
8
+
7
9
  def self.from_file(path)
8
10
  code = File.read(path)
9
11
  parse(code)
10
12
  end
11
13
 
12
- def textual_mapping
13
- output = ""
14
- @mapping.each do |key, sub_hash|
15
- subkeys = sub_hash.keys.reject { |x| x.to_s=="outer_block"}
16
- subkeys.each_with_index do |sub_key, i|
17
- case i
18
- when 0
19
- output << "#{key} +-> #{sub_key}\n"
20
- when subkeys.length - 1
21
- output << "#{' '*key.length} \\-> #{sub_key}\n"
22
- else
23
- output << "#{' '*key.length} |-> #{sub_key}\n"
24
- end
25
- end
26
- end
27
- output
28
- end
29
-
30
14
  def self.parse(code)
31
15
  Config.new(code)
32
16
  end
33
17
 
18
+ def textual_mapping
19
+ TransformationsRenderer.render(simple_mapping)
20
+ end
21
+
34
22
  def detect_from_format(data)
35
23
  @from_format = data['ki_type']
36
24
  raise ConfigError, "Cannot convert from unknown type. Include 'ki_type' in JSON" if @from_format.nil?
@@ -44,7 +32,7 @@ module KiMiddleman
44
32
  @parsing = false
45
33
  end
46
34
 
47
- def convert_data_to_format(data, format, constants)
35
+ def convert_data_to_format(data, format, constants='')
48
36
  self.detect_from_format(data)
49
37
 
50
38
  raise ConfigError, "No transform from '#{@from_format}' found." unless @mapping.has_key?(@from_format.to_sym)
@@ -56,12 +44,18 @@ module KiMiddleman
56
44
  end
57
45
 
58
46
  @format_to_evaluate = best_to_format
47
+
59
48
  self.set_evaluation_context
60
- evaluation_context = @mapping[@from_format.to_sym][:outer_block]
49
+ evaluation_contexts = @mapping[@from_format.to_sym][FROM_BLOCK_KEY]
61
50
  instance_eval constants
62
- converted_data = evaluation_context.call Map.new(data)
51
+ converted_data = nil
52
+ evaluation_contexts.each do |evaluation_context|
53
+ converted_data = evaluation_context.call(Map.new(data))
54
+ break if converted_data
55
+ end
63
56
  converted_data['ki_type'] = best_to_format
64
57
 
58
+ @evaluation = nil
65
59
  converted_data
66
60
  end
67
61
 
@@ -69,10 +63,13 @@ module KiMiddleman
69
63
  keys = @mapping[from_format].keys.map(&:to_s)
70
64
  matching = keys.select { |key| key.include?(format.to_s) }
71
65
 
72
- if matching.length == 1
66
+ case matching.length
67
+ when 0
68
+ raise "Cannot convert '#{from_format}' to '#{format}'. No matching transformations."
69
+ when 1
73
70
  match = matching.first
74
71
  else
75
- format
72
+ raise "Cannot pick a transformation for '#{from_format}' to '#{format}'.\nPossible options are #{matching.map{|x| %Q{'#{x}'} }.join(', ')}."
76
73
  end
77
74
  end
78
75
 
@@ -84,9 +81,10 @@ module KiMiddleman
84
81
 
85
82
  def from(from_format, &block)
86
83
  @current_from = from_format
87
- @mapping[@current_from] = {
88
- :outer_block => block
84
+ @mapping[@current_from] ||= {
89
85
  }
86
+ @mapping[@current_from][FROM_BLOCK_KEY] ||= []
87
+ @mapping[@current_from][FROM_BLOCK_KEY] << block
90
88
  yield
91
89
  end
92
90
 
@@ -96,12 +94,28 @@ module KiMiddleman
96
94
  if @parsing
97
95
  @mapping[@current_from][to_format] = block
98
96
  else
97
+ #return @evaluation if @evaluation
99
98
  if @format_to_evaluate.to_s == to_format.to_s
100
- @evaluation = block.call
101
- @format_to_evaluate = nil
99
+ @evaluation = block.call
100
+ @format_to_evaluate = nil
101
+ end
102
+ @evaluation
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def simple_mapping
109
+ map = {}
110
+ @mapping.each do |origin_format, data|
111
+ data.each do |key, value|
112
+ next if key.to_s == FROM_BLOCK_KEY.to_s
113
+ map[origin_format] ||= []
114
+ map[origin_format] << key
102
115
  end
103
- @evaluation
104
116
  end
117
+ map
105
118
  end
119
+
106
120
  end
107
121
  end
@@ -0,0 +1,44 @@
1
+ module KiMiddleman
2
+
3
+ class TransformationsRenderer
4
+
5
+ def self.render(transformations)
6
+ output = []
7
+ longest_origin_format_length = transformations.keys.map(&:length).max
8
+ transformations.each do |origin_format, destination_format_array|
9
+ last_index = destination_format_array.length - 1
10
+ destination_format_array.each_with_index do |destination_format, index|
11
+ output <<
12
+ "%-#{longest_origin_format_length}s %s %s" %
13
+ [render_origin_format(origin_format, index),
14
+ render_arrows(index, last_index),
15
+ destination_format]
16
+ end
17
+ end
18
+ output.map {|o| o + "\n"}.join
19
+ end
20
+
21
+ def self.render_arrows(index, last_index)
22
+ return "--->" if last_index == 0
23
+ case index
24
+ when 0
25
+ "-+->"
26
+ when last_index
27
+ " \\->"
28
+ else
29
+ " |->"
30
+ end
31
+ end
32
+
33
+ def self.render_origin_format(origin_format, index)
34
+ if index == 0
35
+ origin_format
36
+ else
37
+ ""
38
+ end
39
+ end
40
+ private_class_method :render_origin_format
41
+
42
+ end
43
+
44
+ end
@@ -1,3 +1,3 @@
1
1
  module KiMiddleman
2
- VERSION = "0.0.13"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  include KiMiddleman
4
4
 
5
- describe "converting JSON" do
5
+ describe KiMiddleman::Config do
6
6
 
7
7
  it "converts to a base format" do
8
8
  config = KiMiddleman::Config.parse <<-RUBY
@@ -14,24 +14,37 @@ from(:bug) do |bug|
14
14
  end
15
15
  to(:something_else) do
16
16
  {
17
+ 'foo' => 'bar'
17
18
  }
18
19
  end
19
20
  end
20
21
  RUBY
21
- input_json =<<-JSON
22
- {
23
- "ki_type" : "bug",
24
- "name" : "Something broke",
25
- "id" : "123"
26
- }
27
- JSON
28
-
29
- input = MultiJson.load(input_json)
30
-
31
- output = config.convert_data_to_format(input, 'story', '')
22
+ input = {
23
+ "ki_type" => "bug",
24
+ "name" => "Something broke",
25
+ "id" => "123"
26
+ }
32
27
 
28
+ output = config.convert_data_to_format(input, 'story')
33
29
  output['ki_type'].should == 'story'
34
30
  output['summary'].should == "[123] Something broke"
31
+
32
+ output = config.convert_data_to_format(input, 'something_else')
33
+ output['foo'].should == "bar"
34
+ end
35
+
36
+ it "raises error if 'to' format cannot be found" do
37
+ config = KiMiddleman::Config.parse <<-RUBY
38
+ from(:bug) do |bug|
39
+ to(:story) do
40
+ {}
41
+ end
42
+ end
43
+ RUBY
44
+ input = { "ki_type" => "bug" }
45
+ expect {
46
+ output = config.convert_data_to_format(input, 'card')
47
+ }.to raise_error /Cannot convert 'bug' to 'card'\. No matching transformations/
35
48
  end
36
49
 
37
50
  it "can use . syntax" do
@@ -44,21 +57,39 @@ from(:bug) do |bug|
44
57
  end
45
58
  end
46
59
  RUBY
47
- input_json =<<-JSON
48
- {
49
- "ki_type" : "bug",
50
- "name" : "Hello"
51
- }
52
- JSON
53
-
54
- input = MultiJson.load(input_json)
60
+ input = {
61
+ "ki_type" => "bug",
62
+ "name" => "Hello"
63
+ }
55
64
 
56
- output = config.convert_data_to_format(input, 'story', '')
65
+ output = config.convert_data_to_format(input, 'story')
57
66
 
58
67
  output['summary'].should == "Hello"
59
68
  end
60
69
 
61
- it "can subsitute in constants" do
70
+ it "can define transforms in separate blocks" do
71
+ config = KiMiddleman::Config.parse <<-RUBY
72
+ from(:bug) do |bug|
73
+ to(:story) do
74
+ {
75
+ :name => 'story'
76
+ }
77
+ end
78
+ end
79
+ from(:bug) do |bug|
80
+ to(:card) do
81
+ {
82
+ :name => 'card'
83
+ }
84
+ end
85
+ end
86
+ RUBY
87
+ input = {'ki_type' => 'bug'}
88
+ config.convert_data_to_format(input, 'story')[:name].should == 'story'
89
+ config.convert_data_to_format(input, 'card')[:name].should == 'card'
90
+ end
91
+
92
+ it "can substitute in constants" do
62
93
  config = KiMiddleman::Config.parse <<-RUBY
63
94
  CONSTANT = "first"
64
95
  from(:bug) do |bug|
@@ -69,23 +100,89 @@ from(:bug) do |bug|
69
100
  end
70
101
  end
71
102
  RUBY
72
- input_json =<<-JSON
73
- {
74
- "ki_type" : "bug",
75
- "name" : "Hello"
76
- }
77
- JSON
78
-
79
- input = MultiJson.load(input_json)
103
+ input = {
104
+ "ki_type" => "bug",
105
+ "name" => "Hello"
106
+ }
80
107
 
81
- output = config.convert_data_to_format(input, 'story', '')
108
+ output = config.convert_data_to_format(input, 'story')
82
109
 
83
110
  output['summary'].should == "first"
84
111
 
85
- output = config.convert_data_to_format(input, 'story', 'CONSTANT = "second";')
112
+ capture_io do
113
+ output = config.convert_data_to_format(input, 'story', 'CONSTANT = "second";')
114
+ end
86
115
 
87
116
  output['summary'].should == "second"
88
117
 
89
118
  end
90
119
 
120
+ it "raises error if unique transformation cannot be found" do
121
+ config = KiMiddleman::Config.parse <<-RUBY
122
+ from(:bug) do |foo|
123
+ to(:card1) { {'message' => 'hi'} }
124
+ to(:card2) {}
125
+ end
126
+ RUBY
127
+ input = {
128
+ "ki_type" => "bug",
129
+ }
130
+
131
+ expect {
132
+ config.convert_data_to_format(input, "card")
133
+ }.to raise_error(/Cannot pick a transformation for/)
134
+
135
+ output = config.convert_data_to_format(input, "card1")
136
+ output['message'].should == 'hi'
137
+ end
138
+
139
+
140
+ it "can choose transformation with substring" do
141
+ config = KiMiddleman::Config.parse <<-RUBY
142
+ from(:bug) do |foo|
143
+ to(:foobar) { {'message' => 'hi'} }
144
+ end
145
+ RUBY
146
+ input = {
147
+ "ki_type" => "bug",
148
+ }
149
+
150
+ capture_io do
151
+ output = config.convert_data_to_format(input, "foo")
152
+ output['message'].should == 'hi'
153
+ output = config.convert_data_to_format(input, "bar")
154
+ output['message'].should == 'hi'
155
+ end
156
+ end
157
+
158
+ it "can list transitions" do
159
+ config = KiMiddleman::Config.parse <<-RUBY
160
+ from(:foo) do |foo|
161
+ to(:bar) {}
162
+ to(:baz) {}
163
+ end
164
+ from(:foo) do |foo|
165
+ to(:foobar) {}
166
+ end
167
+ from(:a) do
168
+ to(:d) {}
169
+ to(:c) {}
170
+ to(:b) {}
171
+ end
172
+ from(:x) do
173
+ to(:z) {}
174
+ end
175
+ RUBY
176
+ output = config.textual_mapping
177
+ output.should include("foo -+-> bar")
178
+ output.should include(" |-> baz")
179
+ output.should include(" \\-> foobar")
180
+
181
+ output.should include("a -+-> d")
182
+ output.should include(" |-> c")
183
+ output.should include(" \\-> b")
184
+
185
+ output.should include("x ---> z")
186
+ end
187
+
91
188
  end
@@ -17,6 +17,24 @@ RSpec.configure do |config|
17
17
  # the seed, which is printed after each run.
18
18
  # --seed 1234
19
19
  config.order = 'random'
20
+
21
+ def capture_io
22
+ require 'stringio'
23
+
24
+ captured_stdout, captured_stderr = StringIO.new, StringIO.new
25
+
26
+ orig_stdout, orig_stderr = $stdout, $stderr
27
+ $stdout, $stderr = captured_stdout, captured_stderr
28
+
29
+ begin
30
+ yield
31
+ ensure
32
+ $stdout = orig_stdout
33
+ $stderr = orig_stderr
34
+ end
35
+
36
+ return captured_stdout.string, captured_stderr.string
37
+ end
20
38
  end
21
39
 
22
40
  if ENV['COVERAGE']
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe KiMiddleman::TransformationsRenderer do
4
+
5
+ it "renders a single transformation" do
6
+ map = {
7
+ :a => [:b]
8
+ }
9
+ TransformationsRenderer.render(map).should == "a ---> b\n"
10
+ end
11
+
12
+ it "renders two transformations from the same format" do
13
+ map = {
14
+ :a => [:b, :c]
15
+ }
16
+ TransformationsRenderer.render(map).should == <<-EOS
17
+ a -+-> b
18
+ \\-> c
19
+ EOS
20
+ end
21
+
22
+ it "renders many transformations from the same format" do
23
+ map = {
24
+ :a => [:b, :c, :d, :e]
25
+ }
26
+ TransformationsRenderer.render(map).should == <<-EOS
27
+ a -+-> b
28
+ |-> c
29
+ |-> d
30
+ \\-> e
31
+ EOS
32
+ end
33
+
34
+ it "aligns all arrows" do
35
+ map = {
36
+ :a => [:b, :c],
37
+ :foobar => [:bar]
38
+ }
39
+ TransformationsRenderer.render(map).should == <<-EOS
40
+ a -+-> b
41
+ \\-> c
42
+ foobar ---> bar
43
+ EOS
44
+ end
45
+
46
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ki_middleman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-09-30 00:00:00.000000000Z
13
+ date: 2013-03-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: multi_json
17
- requirement: &70261199979280 !ruby/object:Gem::Requirement
17
+ requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,15 @@ dependencies:
22
22
  version: 1.3.6
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70261199979280
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 1.3.6
26
31
  - !ruby/object:Gem::Dependency
27
32
  name: methadone
28
- requirement: &70261199978560 !ruby/object:Gem::Requirement
33
+ requirement: !ruby/object:Gem::Requirement
29
34
  none: false
30
35
  requirements:
31
36
  - - ~>
@@ -33,10 +38,15 @@ dependencies:
33
38
  version: 1.2.1
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: *70261199978560
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 1.2.1
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: map
39
- requirement: &70261199977900 !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
40
50
  none: false
41
51
  requirements:
42
52
  - - ~>
@@ -44,10 +54,15 @@ dependencies:
44
54
  version: 4.6.1
45
55
  type: :runtime
46
56
  prerelease: false
47
- version_requirements: *70261199977900
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 4.6.1
48
63
  - !ruby/object:Gem::Dependency
49
64
  name: debugger
50
- requirement: &70261199977140 !ruby/object:Gem::Requirement
65
+ requirement: !ruby/object:Gem::Requirement
51
66
  none: false
52
67
  requirements:
53
68
  - - ~>
@@ -55,10 +70,15 @@ dependencies:
55
70
  version: 1.2.0
56
71
  type: :development
57
72
  prerelease: false
58
- version_requirements: *70261199977140
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 1.2.0
59
79
  - !ruby/object:Gem::Dependency
60
80
  name: rake
61
- requirement: &70261199976680 !ruby/object:Gem::Requirement
81
+ requirement: !ruby/object:Gem::Requirement
62
82
  none: false
63
83
  requirements:
64
84
  - - ~>
@@ -66,10 +86,15 @@ dependencies:
66
86
  version: 0.9.2
67
87
  type: :development
68
88
  prerelease: false
69
- version_requirements: *70261199976680
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: 0.9.2
70
95
  - !ruby/object:Gem::Dependency
71
96
  name: rspec
72
- requirement: &70261199975980 !ruby/object:Gem::Requirement
97
+ requirement: !ruby/object:Gem::Requirement
73
98
  none: false
74
99
  requirements:
75
100
  - - ~>
@@ -77,10 +102,15 @@ dependencies:
77
102
  version: 2.11.0
78
103
  type: :development
79
104
  prerelease: false
80
- version_requirements: *70261199975980
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 2.11.0
81
111
  - !ruby/object:Gem::Dependency
82
112
  name: simplecov
83
- requirement: &70261199975260 !ruby/object:Gem::Requirement
113
+ requirement: !ruby/object:Gem::Requirement
84
114
  none: false
85
115
  requirements:
86
116
  - - ~>
@@ -88,7 +118,12 @@ dependencies:
88
118
  version: 0.6.4
89
119
  type: :development
90
120
  prerelease: false
91
- version_requirements: *70261199975260
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ~>
125
+ - !ruby/object:Gem::Version
126
+ version: 0.6.4
92
127
  description: Transforms JSON into other JSON
93
128
  email:
94
129
  - ben@freeagent.com
@@ -110,9 +145,11 @@ files:
110
145
  - lib/ki_middleman.rb
111
146
  - lib/ki_middleman/config.rb
112
147
  - lib/ki_middleman/kiseru.rb
148
+ - lib/ki_middleman/transformations_renderer.rb
113
149
  - lib/ki_middleman/version.rb
114
150
  - spec/integration/convert_spec.rb
115
151
  - spec/spec_helper.rb
152
+ - spec/unit/transformation_renderer.rb
116
153
  homepage: ''
117
154
  licenses: []
118
155
  post_install_message:
@@ -125,18 +162,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
162
  - - ! '>='
126
163
  - !ruby/object:Gem::Version
127
164
  version: '0'
165
+ segments:
166
+ - 0
167
+ hash: -2635587134579891059
128
168
  required_rubygems_version: !ruby/object:Gem::Requirement
129
169
  none: false
130
170
  requirements:
131
171
  - - ! '>='
132
172
  - !ruby/object:Gem::Version
133
173
  version: '0'
174
+ segments:
175
+ - 0
176
+ hash: -2635587134579891059
134
177
  requirements: []
135
178
  rubyforge_project:
136
- rubygems_version: 1.8.10
179
+ rubygems_version: 1.8.24
137
180
  signing_key:
138
181
  specification_version: 3
139
182
  summary: Transforms JSON into other JSON
140
183
  test_files:
141
184
  - spec/integration/convert_spec.rb
142
185
  - spec/spec_helper.rb
186
+ - spec/unit/transformation_renderer.rb