ki_middleman 0.0.13 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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