arel_converter 0.0.1

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