arel_converter 0.0.1

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 (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +124 -0
  7. data/Rakefile +8 -0
  8. data/TODO.md +6 -0
  9. data/arel_converter.gemspec +28 -0
  10. data/bin/arel_convert +7 -0
  11. data/lib/arel_converter.rb +25 -0
  12. data/lib/arel_converter/active_record_finder.rb +19 -0
  13. data/lib/arel_converter/association.rb +21 -0
  14. data/lib/arel_converter/base.rb +76 -0
  15. data/lib/arel_converter/command.rb +50 -0
  16. data/lib/arel_converter/formatter.rb +46 -0
  17. data/lib/arel_converter/replacement.rb +21 -0
  18. data/lib/arel_converter/scope.rb +22 -0
  19. data/lib/arel_converter/translators/association.rb +71 -0
  20. data/lib/arel_converter/translators/base.rb +49 -0
  21. data/lib/arel_converter/translators/finder.rb +28 -0
  22. data/lib/arel_converter/translators/options.rb +172 -0
  23. data/lib/arel_converter/translators/scope.rb +28 -0
  24. data/lib/arel_converter/version.rb +3 -0
  25. data/spec/fixtures/grep_matching.rb +38 -0
  26. data/spec/fixtures/my/base_fixture.rb +0 -0
  27. data/spec/fixtures/my/files/controller.rb +0 -0
  28. data/spec/fixtures/my/files/model.rb +0 -0
  29. data/spec/fixtures/my/files/not_source.txt +0 -0
  30. data/spec/fixtures/my/files/source.rb +0 -0
  31. data/spec/lib/arel_converter/active_record_finder_spec.rb +26 -0
  32. data/spec/lib/arel_converter/association_spec.rb +36 -0
  33. data/spec/lib/arel_converter/base_spec.rb +130 -0
  34. data/spec/lib/arel_converter/command_spec.rb +7 -0
  35. data/spec/lib/arel_converter/replacement_spec.rb +22 -0
  36. data/spec/lib/arel_converter/scope_spec.rb +40 -0
  37. data/spec/lib/arel_converter/translators/association_spec.rb +110 -0
  38. data/spec/lib/arel_converter/translators/finder_spec.rb +88 -0
  39. data/spec/lib/arel_converter/translators/options_spec.rb +104 -0
  40. data/spec/lib/arel_converter/translators/scope_spec.rb +130 -0
  41. data/spec/spec_helper.rb +20 -0
  42. metadata +186 -0
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArelConverter::Translator::Options do
4
+
5
+ context 'parsing ActiveRecord options' do
6
+
7
+ context 'as a S-Expression' do
8
+ it 'should work with the same results as a string' do
9
+ code_fragment = %Q{{:joins => :roles}}
10
+ sexp = RubyParser.new.process(code_fragment)
11
+ expect(ArelConverter::Translator::Options.translate(sexp)).to eq(ArelConverter::Translator::Options.translate(code_fragment))
12
+ end
13
+ end
14
+
15
+ context 'as a string' do
16
+
17
+ context 'with joins' do
18
+ it 'when it is a simple association' do
19
+ scope = %Q{{:joins => :roles}}
20
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{joins(:roles)})
21
+ end
22
+
23
+ it 'when it is an array of simple associations' do
24
+ scope = %Q{{:joins => [:roles, :users]}}
25
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{joins(:roles, :users)})
26
+ end
27
+
28
+ it 'when it is a SQL fragment' do
29
+ scope = %Q{{:joins => "LEFT JOIN `roles` ON roles.scope_id = scopes.id"}}
30
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{joins("LEFT JOIN `roles` ON roles.scope_id = scopes.id")})
31
+ end
32
+
33
+ it 'when it is a hash of associations' do
34
+ scope = %Q{{:joins => {:roles => :users}}}
35
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{joins( roles: :users )})
36
+ end
37
+ end
38
+
39
+ context 'with includes' do
40
+ it 'when it is a simple association' do
41
+ scope = %Q{{:include => :roles}}
42
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{includes(:roles)})
43
+ end
44
+
45
+ it 'when it is an array of simple associations' do
46
+ scope = %Q{{:include => [:roles, :users]}}
47
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{includes(:roles, :users)})
48
+ end
49
+
50
+ it 'when it is a hash of associations' do
51
+ scope = %Q{{:include => {:roles => :users}}}
52
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{includes( roles: :users )})
53
+ end
54
+ end
55
+
56
+ context 'with conditions' do
57
+ it 'when they are a string' do
58
+ scope = %Q{{:conditions => "active = 1"}}
59
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{where("active = 1")})
60
+ end
61
+
62
+ it 'when they are an array' do
63
+ scope = %Q{{:conditions => ["active = ?", true]}}
64
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{where("active = ?", true)})
65
+ end
66
+
67
+ it 'where they are a single hash' do
68
+ scope = %Q{{:conditions => {:active => 1}}}
69
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{where( active: 1 )})
70
+ end
71
+
72
+ it 'where they are a hash' do
73
+ scope = %Q{{:conditions => {:active => 1, :name => 'John'}}}
74
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{where( active: 1, name: "John" )})
75
+ end
76
+
77
+ it 'where there is a hash including an array' do
78
+ scope = %Q{{:conditions => {:state => ['confirmed', 'partially_received', 'ordered']}}}
79
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{where( state: ["confirmed", "partially_received", "ordered"] )})
80
+ end
81
+
82
+ it 'where there is a where and include' do
83
+ scope = %Q{{:include => :purchase_order, :conditions => ["purchase_orders.state NOT IN ('shopping', 'received', 'cancelled', 'closed')"]}}
84
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{includes(:purchase_order).where("purchase_orders.state NOT IN ('shopping', 'received', 'cancelled', 'closed')")})
85
+ end
86
+ end
87
+
88
+ context "with lambdas" do
89
+ it 'should stay on a single line' do
90
+ scope = %Q{lambda{|vendor| {:include => :vendor_purchase_order, :conditions => ["purchase_orders.vendor_id = ?", vendor.id]}}}
91
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{lambda { |vendor| includes(:vendor_purchase_order).where("purchase_orders.vendor_id = ?", vendor.id) }})
92
+ end
93
+ end
94
+
95
+ context "with multiple options" do
96
+ it 'should concatinate them correctly' do
97
+ scope = %Q{{:include => [:vendor], :conditions => "state IN ('confirmed','partially_received')"}}
98
+ expect(ArelConverter::Translator::Options.translate(scope)).to eq(%Q{includes(:vendor).where("state IN ('confirmed','partially_received')")})
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ describe ArelConverter::Translator::Scope do
4
+
5
+ context 'parsing scopes' do
6
+
7
+ context 'with joins' do
8
+ it 'when it is a simple association' do
9
+ scope = %Q{scope :my_scope, :joins => :roles}
10
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { joins(:roles) }})
11
+ end
12
+
13
+ it 'when it is an array of simple associations' do
14
+ scope = %Q{scope :my_scope, :joins => [:roles, :users]}
15
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { joins(:roles, :users) }})
16
+ end
17
+
18
+ it 'when it is a SQL fragment' do
19
+ scope = %Q{scope :my_scope, :joins => "LEFT JOIN `roles` ON roles.scope_id = scopes.id"}
20
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { joins("LEFT JOIN `roles` ON roles.scope_id = scopes.id") }})
21
+ end
22
+
23
+ it 'when it is a hash of associations' do
24
+ scope = %Q{scope :my_scope, :joins => {:roles => :users}}
25
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { joins( roles: :users ) }})
26
+ end
27
+ end
28
+
29
+ context 'with includes' do
30
+ it 'when it is a simple association' do
31
+ scope = %Q{scope :my_scope, :include => :roles}
32
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { includes(:roles) }})
33
+ end
34
+
35
+ it 'when it is an array of simple associations' do
36
+ scope = %Q{scope :my_scope, :include => [:roles, :users]}
37
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { includes(:roles, :users) }})
38
+ end
39
+
40
+ it 'when it is a hash of associations' do
41
+ scope = %Q{scope :my_scope, :include => {:roles => :users}}
42
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { includes( roles: :users ) }})
43
+ end
44
+
45
+ it 'when there is a nested hash of associations' do
46
+ scope = %Q{scope :my_scope, :include => [:author => {:roles => :users}]}
47
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { includes( author: { roles: :users } ) }})
48
+ end
49
+
50
+ it 'when there is an array of associations with a nested hash of' do
51
+ scope = %Q{scope :my_scope, :include => [ {:strengths => :unit}, :origin_country, :unit]}
52
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { includes({ strengths: :unit }, :origin_country, :unit) }})
53
+ end
54
+ end
55
+
56
+ context 'with conditions' do
57
+ it 'when they are a string' do
58
+ scope = %Q{scope :my_scope, :conditions => "active = 1"}
59
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { where("active = 1") }})
60
+ end
61
+
62
+ it 'when they are an array' do
63
+ scope = %Q{scope :my_scope, :conditions => ["active = ?", true]}
64
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { where("active = ?", true) }})
65
+ end
66
+
67
+ it 'where they are a single hash' do
68
+ scope = %Q{scope :my_scope, :conditions => {:active => 1}}
69
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { where( active: 1 ) }})
70
+ end
71
+
72
+ it 'where they are a hash' do
73
+ scope = %Q{scope :my_scope, :conditions => {:active => 1, :name => 'John'}}
74
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { where( active: 1, name: "John" ) }})
75
+ end
76
+
77
+ it 'where there is a hash including an array' do
78
+ scope = %Q{scope :my_scope, :conditions => {:state => ['confirmed', 'partially_received', 'ordered']}}
79
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { where( state: ["confirmed", "partially_received", "ordered"] ) }})
80
+ end
81
+
82
+ it 'where there is a where and include' do
83
+ scope = %Q{scope :my_scope, :include => :purchase_order, :conditions => ["purchase_orders.state NOT IN ('shopping', 'received', 'cancelled', 'closed')"]}
84
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { includes(:purchase_order).where("purchase_orders.state NOT IN ('shopping', 'received', 'cancelled', 'closed')") }})
85
+ end
86
+
87
+ it 'where there is a hash with string keys' do
88
+ scope = %Q{scope :my_scope, :conditions => {'products.generic' => true}}
89
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { where( "products.generic" => true ) }})
90
+ end
91
+ end
92
+
93
+ context "with lambdas" do
94
+ it 'should handle stubby lambdas' do
95
+ scope = %Q{scope :for_state, -> { where(:state => state.to_s.upcase) }}
96
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :for_state, -> { where(state: state.to_s.upcase) }})
97
+ end
98
+
99
+ it 'should not change an existing Arel call (very much)' do
100
+ scope = %Q{scope :for_state, lambda {|state| where(:state => state.to_s.upcase) }}
101
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :for_state, lambda { |state| where(state: state.to_s.upcase) }})
102
+ end
103
+ it 'should not change existing chained Arel calls (very much)' do
104
+ scope = %Q{scope :for_state, lambda {|state| where(:state => state.to_s.upcase).order(:name) }}
105
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :for_state, lambda { |state| where(state: state.to_s.upcase).order(:name) }})
106
+ end
107
+
108
+ it 'should stay on a single line' do
109
+ scope = %Q{scope :my_scope, lambda{|vendor| {:include => :vendor_purchase_order, :conditions => ["purchase_orders.vendor_id = ?", vendor.id]}}}
110
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, lambda { |vendor| includes(:vendor_purchase_order).where("purchase_orders.vendor_id = ?", vendor.id) }})
111
+ end
112
+
113
+ it 'should parse when a conditional is present' do
114
+ scope = %Q{scope :my_scope, lambda{|search_term| {:conditions => ["posts.name LIKE ?", "%\#{search_term}%"]} unless search_term.blank? }}
115
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, lambda { |search_term| where("posts.name LIKE ?", "%\#{search_term}%") unless search_term.blank? }})
116
+ end
117
+ end
118
+
119
+ context "with multiple options" do
120
+ it 'should concatinate them correctly' do
121
+ scope = %Q{scope :my_scope, {:include => [:vendor], :conditions => "state IN ('confirmed','partially_received')"}}
122
+ expect(ArelConverter::Translator::Scope.translate(scope)).to eq(%Q{scope :my_scope, -> { includes(:vendor).where("state IN ('confirmed','partially_received')") }})
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+
130
+
@@ -0,0 +1,20 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require 'arel_converter'
9
+
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arel_converter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Peer Allan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby2ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby_parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: logging
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Converts existing AR finder syntax to AREL
98
+ email:
99
+ - peer.allan@canadadrugs.com
100
+ executables:
101
+ - arel_convert
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - .rspec
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - TODO.md
112
+ - arel_converter.gemspec
113
+ - bin/arel_convert
114
+ - lib/arel_converter.rb
115
+ - lib/arel_converter/active_record_finder.rb
116
+ - lib/arel_converter/association.rb
117
+ - lib/arel_converter/base.rb
118
+ - lib/arel_converter/command.rb
119
+ - lib/arel_converter/formatter.rb
120
+ - lib/arel_converter/replacement.rb
121
+ - lib/arel_converter/scope.rb
122
+ - lib/arel_converter/translators/association.rb
123
+ - lib/arel_converter/translators/base.rb
124
+ - lib/arel_converter/translators/finder.rb
125
+ - lib/arel_converter/translators/options.rb
126
+ - lib/arel_converter/translators/scope.rb
127
+ - lib/arel_converter/version.rb
128
+ - spec/fixtures/grep_matching.rb
129
+ - spec/fixtures/my/base_fixture.rb
130
+ - spec/fixtures/my/files/controller.rb
131
+ - spec/fixtures/my/files/model.rb
132
+ - spec/fixtures/my/files/not_source.txt
133
+ - spec/fixtures/my/files/source.rb
134
+ - spec/lib/arel_converter/active_record_finder_spec.rb
135
+ - spec/lib/arel_converter/association_spec.rb
136
+ - spec/lib/arel_converter/base_spec.rb
137
+ - spec/lib/arel_converter/command_spec.rb
138
+ - spec/lib/arel_converter/replacement_spec.rb
139
+ - spec/lib/arel_converter/scope_spec.rb
140
+ - spec/lib/arel_converter/translators/association_spec.rb
141
+ - spec/lib/arel_converter/translators/finder_spec.rb
142
+ - spec/lib/arel_converter/translators/options_spec.rb
143
+ - spec/lib/arel_converter/translators/scope_spec.rb
144
+ - spec/spec_helper.rb
145
+ homepage: ''
146
+ licenses:
147
+ - MIT
148
+ metadata: {}
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubyforge_project:
165
+ rubygems_version: 2.0.3
166
+ signing_key:
167
+ specification_version: 4
168
+ summary: Converts AR finders, scopes and association arguments to AREL syntax
169
+ test_files:
170
+ - spec/fixtures/grep_matching.rb
171
+ - spec/fixtures/my/base_fixture.rb
172
+ - spec/fixtures/my/files/controller.rb
173
+ - spec/fixtures/my/files/model.rb
174
+ - spec/fixtures/my/files/not_source.txt
175
+ - spec/fixtures/my/files/source.rb
176
+ - spec/lib/arel_converter/active_record_finder_spec.rb
177
+ - spec/lib/arel_converter/association_spec.rb
178
+ - spec/lib/arel_converter/base_spec.rb
179
+ - spec/lib/arel_converter/command_spec.rb
180
+ - spec/lib/arel_converter/replacement_spec.rb
181
+ - spec/lib/arel_converter/scope_spec.rb
182
+ - spec/lib/arel_converter/translators/association_spec.rb
183
+ - spec/lib/arel_converter/translators/finder_spec.rb
184
+ - spec/lib/arel_converter/translators/options_spec.rb
185
+ - spec/lib/arel_converter/translators/scope_spec.rb
186
+ - spec/spec_helper.rb