Permalink
Browse files

Updated named_scope converter to use ArelConverter (and tests)

  • Loading branch information...
1 parent 1b767c8 commit 01ef0b3ac379e9768eb1a17a7ca1e03de7be913e Peer Allan committed with Oct 29, 2010
Showing with 108 additions and 25 deletions.
  1. +44 −25 lib/named_scope_converter.rb
  2. +64 −0 test/named_scope_converter_test.rb
@@ -1,5 +1,6 @@
$:.unshift(File.dirname(__FILE__) + "/../../lib")
require 'converter_base'
+require 'arel_converter'
module Rails
module Converter
@@ -27,12 +28,8 @@ def parse_file(file)
new_scopes = named_scopes.map do |scope|
scope.strip!
if scope =~ /^[\s#]*named/
- new_scope = scope.split(",").first.gsub('named_scope','scope')
- matches = lambda_regex.match(scope.strip)
-
begin
- params = matches ? parse_lambda(matches) : parse_normal(scope)
- "#{new_scope}, #{params}"
+ [scope, process_line(scope)]
rescue SyntaxError => e
failures << "SyntaxError when evaluatiing options for #{scope}"
nil
@@ -45,30 +42,52 @@ def parse_file(file)
alert(file, new_scopes, failures) unless (new_scopes.nil? || new_scopes.empty?) && failures.empty?
end
- def parse_lambda(matches)
+ def process_line(line)
case
- when conditions = /:conditions =>\s?\[(.*?)\](,|\})?/.match(matches[2]),
- conditions = /:conditions =>\s?\{(.*?)\}/.match(matches[2]),
- conditions = /:conditions =>\s?(.*?)\}/.match(matches[2])
- where = conditions[1]
+ when line.include?('lambda')
+ new_line = convert_lambda(line)
else
- raise RuntimeError, "Can't find :conditions in #{matches[0]}"
- where = nil
- end
-
- hash = matches[2].gsub(conditions[0],'').strip.gsub(/,$/, '')
- options = {}
- options = eval("{#{hash}}") if hash
- options[:where] = where if where
- options
-
- "lambda { |#{matches[1]}| #{contruct_for_arel(options).join('.')}}"
+ new_line = convert_arguments(line)
+ end
+ new_line.gsub('named_scope', 'scope')
+ end
+
+
+ def convert_lambda(line)
+ full_method, arguments = extract_method(line)
+ clean_arguments = arguments.gsub(/\|.*?\|/, '').strip
+ line.gsub(clean_arguments, ArelConverter.translate(clean_arguments))
end
- def parse_normal(scope)
- options = %Q{#{scope.gsub(/^.*?,/, '').strip}}
- options = %Q{{#{options}}} unless options =~ /^\{.*\}$/
- contruct_for_arel(eval(options)).join('.')
+ def convert_arguments(line)
+ options = %Q{#{line.gsub(/^.*?,/, '').strip}}
+ clean_arguments = %Q{{#{options}}} unless options =~ /^\{.*\}$/
+ line.gsub(options, ArelConverter.translate(clean_arguments))
+ end
+
+ def extract_method(line)
+ i = line.index('lambda')
+ braces = 0
+ full_method = ''
+ args = ''
+
+ while i < line.length
+ char = line[i].chr
+ full_method << char
+ args << char if braces > 0
+ case char
+ when '{'
+ braces += 1
+ when '}'
+ braces -= 1
+ if braces == 0
+ args.chop!
+ break
+ end
+ end
+ i += 1
+ end
+ braces == 0 ? [full_method, args] : [nil,nil]
end
end
@@ -0,0 +1,64 @@
+require 'test_helper'
+require 'named_scope_converter'
+require 'fileutils'
+
+tmp_dir = "#{File.dirname(__FILE__)}/fixtures/tmp"
+
+if defined? BASE_ROOT
+ BASE_ROOT.replace tmp_dir
+else
+ BASE_ROOT = tmp_dir
+end
+FileUtils.mkdir_p BASE_ROOT
+
+# Stub out methods on converter class
+module Rails
+ module Converter
+ class Base
+ attr_reader :alerts
+
+ def alert(title, text, more_info_url, culprits)
+ @alerts[title] = [text, more_info_url, culprits]
+ end
+ end
+ end
+end
+
+class NamedScopeTest < ActiveSupport::TestCase
+ def setup
+ @converter = Rails::Converter::NamedScope.new
+ @old_dir = Dir.pwd
+
+ Dir.chdir(BASE_ROOT)
+ end
+
+ def test_convert_lambda
+ converted = @converter.process_line('named_scope :for_brokers, lambda{|brokers| {:conditions => ["broker_id IN (?)", brokers.map(&:id)]}}')
+
+ assert_equal converted, 'scope :for_brokers, lambda{|brokers| where(["broker_id IN (?)", brokers.map(&:id)])}'
+ end
+
+ def test_convert_normal
+ converted = @converter.process_line("named_scope :imported, :conditions => 'momex_user_id IS NOT NULL'")
+
+ assert_equal converted, 'scope :imported, where("momex_user_id IS NOT NULL")'
+ end
+
+
+ def teardown
+ clear_files
+
+ Dir.chdir(@old_dir)
+ end
+
+ def make_file(where, name=nil, contents=nil)
+ FileUtils.mkdir_p "#{BASE_ROOT}/#{where}"
+ File.open("#{BASE_ROOT}/#{where}/#{name}", "w+") do |f|
+ f.write(contents)
+ end if name
+ end
+
+ def clear_files
+ FileUtils.rm_rf(Dir.glob("#{BASE_ROOT}/*"))
+ end
+end

0 comments on commit 01ef0b3

Please sign in to comment.