sexy_scopes 0.5.0 → 0.5.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.
data/lib/sexy_scopes.rb CHANGED
@@ -1,7 +1,15 @@
1
+ require 'active_support/dependencies/autoload'
2
+
1
3
  module SexyScopes
2
4
  %w( Version VERSION ).each do |constant|
3
5
  autoload constant, 'sexy_scopes/version'
4
6
  end
7
+
8
+ extend ActiveSupport::Autoload
9
+
10
+ autoload :Wrappers
11
+ autoload :ExpressionWrappers
12
+ autoload :PredicateWrappers
5
13
  end
6
14
 
7
15
  if defined? Rails::Railtie
@@ -1,92 +1,6 @@
1
- require 'delegate'
2
1
  require 'active_record'
3
- require 'sexy_scopes/wrappers'
4
- require 'sexy_scopes/arel'
2
+ require 'sexy_scopes/active_record/class_methods'
3
+ require 'sexy_scopes/active_record/dynamic_methods'
5
4
 
6
- module SexyScopes
7
- module ActiveRecord
8
- include Wrappers
9
-
10
- # Creates and extends an Arel <tt>Attribute</tt> representing the table's column with
11
- # the given <tt>name</tt>.
12
- #
13
- # @param [String, Symbol] name The attribute name
14
- #
15
- # @note Please note that no exception is raised if no such column actually exists.
16
- #
17
- # @example
18
- # User.where(User.attribute(:score) > 1000)
19
- # # => SELECT "users".* FROM "users" WHERE ("users"."score" > 1000)
20
- #
21
- def attribute(name)
22
- attribute = arel_table[name]
23
- extend_expression(attribute)
24
- end
25
-
26
- # Creates and extends an Arel <tt>SqlLiteral</tt> instance for the given <tt>expression</tt>,
27
- # first converted to a string using <tt>to_s</tt>.
28
- #
29
- # @param [String, #to_s] expression Any SQL expression.
30
- #
31
- # @example
32
- # def Circle.with_perimeter_smaller_than(perimeter)
33
- # where sql(2 * Math::PI) * radius < perimeter
34
- # end
35
- #
36
- # Circle.with_perimeter_smaller_than(20)
37
- # # => SELECT "circles".* FROM "circles" WHERE (6.283185307179586 * "circles"."radius" < 20)
38
- #
39
- def sql_literal(expression)
40
- ::Arel.sql(expression.to_s).tap do |literal|
41
- extend_expression(literal)
42
- extend_predicate(literal)
43
- end
44
- end
45
- alias_method :sql, :sql_literal
46
-
47
- # @!visibility private
48
- def respond_to?(method_name, include_private = false) # :nodoc:
49
- super || column_names.include?(method_name.to_s)
50
- end
51
-
52
- private
53
- # Equivalent to calling {#attribute} with the missing method's <tt>name</tt> if the table
54
- # has a column with that name.
55
- #
56
- # Delegates to superclass implementation otherwise, eventually raising <tt>NoMethodError</tt>.
57
- #
58
- # @see #attribute
59
- #
60
- # @note Due to the way this works, be careful not to use this syntactic sugar with existing
61
- # <tt>ActiveRecord::Base</tt> methods (see last example).
62
- #
63
- # @raise [NoMethodError] if the table has no corresponding column
64
- #
65
- # @example
66
- # # Suppose the "users" table has an "email" column, then these are equivalent:
67
- # User.email
68
- # User.attribute(:email)
69
- #
70
- # @example
71
- # # Here is the previous example (from `attribute`) rewritten:
72
- # User.where(User.score > 1000)
73
- # # => SELECT "users".* FROM "users" WHERE ("users"."score" > 1000)
74
- #
75
- # @example
76
- # # Don't use it with existing `ActiveRecord::Base` methods, i.e. `name`:
77
- # User.name # => "User"
78
- # # In these cases you'll have to use `attribute` explicitely
79
- # User.attribute(:name)
80
- #
81
- def method_missing(name, *args)
82
- if column_names.include?(name.to_s)
83
- attribute(name)
84
- else
85
- super
86
- end
87
- end
88
- end
89
-
90
- # Add these methods to Active Record
91
- ::ActiveRecord::Base.extend SexyScopes::ActiveRecord
92
- end
5
+ ActiveRecord::Base.extend SexyScopes::ActiveRecord::ClassMethods
6
+ ActiveRecord::Base.extend SexyScopes::ActiveRecord::DynamicMethods
@@ -0,0 +1,47 @@
1
+ require 'sexy_scopes/arel'
2
+ require 'sexy_scopes/wrappers'
3
+
4
+ module SexyScopes
5
+ module ActiveRecord
6
+ module ClassMethods
7
+ include Wrappers
8
+
9
+ # Creates and extends an Arel <tt>Attribute</tt> representing the table's column with
10
+ # the given <tt>name</tt>.
11
+ #
12
+ # @param [String, Symbol] name The attribute name
13
+ #
14
+ # @note Please note that no exception is raised if no such column actually exists.
15
+ #
16
+ # @example
17
+ # User.where(User.attribute(:score) > 1000)
18
+ # # => SELECT "users".* FROM "users" WHERE ("users"."score" > 1000)
19
+ #
20
+ def attribute(name)
21
+ attribute = arel_table[name]
22
+ extend_expression(attribute)
23
+ end
24
+
25
+ # Creates and extends an Arel <tt>SqlLiteral</tt> instance for the given <tt>expression</tt>,
26
+ # first converted to a string using <tt>to_s</tt>.
27
+ #
28
+ # @param [String, #to_s] expression Any SQL expression.
29
+ #
30
+ # @example
31
+ # def Circle.with_perimeter_smaller_than(perimeter)
32
+ # where sql(2 * Math::PI) * radius < perimeter
33
+ # end
34
+ #
35
+ # Circle.with_perimeter_smaller_than(20)
36
+ # # => SELECT "circles".* FROM "circles" WHERE (6.283185307179586 * "circles"."radius" < 20)
37
+ #
38
+ def sql_literal(expression)
39
+ ::Arel.sql(expression.to_s).tap do |literal|
40
+ extend_expression(literal)
41
+ extend_predicate(literal)
42
+ end
43
+ end
44
+ alias_method :sql, :sql_literal
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,69 @@
1
+ module SexyScopes
2
+ module ActiveRecord
3
+ module DynamicMethods
4
+ # @!visibility private
5
+ def respond_to?(method_name, include_private = false) # :nodoc:
6
+ super || respond_to_missing?(method_name, include_private)
7
+ end
8
+
9
+ # # @!visibility private
10
+ def respond_to_missing?(method_name, include_private = false) # :nodoc:
11
+ Object.respond_to?(:respond_to_missing?) && super || sexy_scopes_has_attribute?(method_name)
12
+ end
13
+
14
+ private
15
+ # Equivalent to calling {#attribute} with the missing method's <tt>name</tt> if the table
16
+ # has a column with that name.
17
+ #
18
+ # Delegates to superclass implementation otherwise, eventually raising <tt>NoMethodError</tt>.
19
+ #
20
+ # @see #attribute
21
+ #
22
+ # @note Due to the way this works, be careful not to use this syntactic sugar with existing
23
+ # <tt>ActiveRecord::Base</tt> methods (see last example).
24
+ #
25
+ # @raise [NoMethodError] if the table has no corresponding column
26
+ #
27
+ # @example
28
+ # # Suppose the "users" table has an "email" column, then these are equivalent:
29
+ # User.email
30
+ # User.attribute(:email)
31
+ #
32
+ # @example
33
+ # # Here is the previous example (from `attribute`) rewritten:
34
+ # User.where(User.score > 1000)
35
+ # # => SELECT "users".* FROM "users" WHERE ("users"."score" > 1000)
36
+ #
37
+ # @example
38
+ # # Don't use it with existing `ActiveRecord::Base` methods, i.e. `name`:
39
+ # User.name # => "User"
40
+ # # In these cases you'll have to use `attribute` explicitely
41
+ # User.attribute(:name)
42
+ #
43
+ def method_missing(name, *args)
44
+ if sexy_scopes_has_attribute?(name)
45
+ sexy_scopes_define_attribute_method(name)
46
+ attribute(name)
47
+ else
48
+ super
49
+ end
50
+ end
51
+
52
+ def sexy_scopes_define_attribute_method(name)
53
+ class_eval <<-EVAL, __FILE__, __LINE__ + 1
54
+ def self.#{name} # def self.username
55
+ attribute(:#{name}) # attribute(:username)
56
+ end # end
57
+ EVAL
58
+ end
59
+
60
+ def sexy_scopes_has_attribute?(attribute_name)
61
+ if equal?(::ActiveRecord::Base) || abstract_class? || !table_exists?
62
+ false
63
+ else
64
+ column_names.include?(attribute_name.to_s)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -2,10 +2,9 @@ module SexyScopes
2
2
  module Arel
3
3
  extend ActiveSupport::Autoload
4
4
 
5
- autoload :ExpressionWrappers
6
- autoload :PredicateWrappers
7
- autoload :ExpressionMethods
5
+ autoload :MathMethods
8
6
  autoload :PredicateMethods
7
+ autoload :BooleanMethods
9
8
  end
10
9
  end
11
10
 
@@ -1,8 +1,6 @@
1
1
  module SexyScopes
2
2
  module Arel
3
- module PredicateWrappers
4
- include Wrappers
5
-
3
+ module BooleanMethods
6
4
  def not
7
5
  extend_predicate(super)
8
6
  end
@@ -1,6 +1,6 @@
1
1
  module SexyScopes
2
2
  module Arel
3
- module ExpressionMethods
3
+ module MathMethods
4
4
  def *(other)
5
5
  extend_expression(super)
6
6
  end
@@ -16,6 +16,10 @@ module SexyScopes
16
16
  def /(other)
17
17
  extend_expression(super)
18
18
  end
19
+
20
+ def coerce(other)
21
+ [extend_expression(::Arel.sql(other.to_s)), self]
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -0,0 +1,7 @@
1
+ module SexyScopes
2
+ module ExpressionWrappers
3
+ include Wrappers
4
+ include Arel::PredicateMethods
5
+ include Arel::MathMethods
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module SexyScopes
2
+ module PredicateWrappers
3
+ include Wrappers
4
+ include Arel::BooleanMethods
5
+ end
6
+ end
@@ -2,9 +2,17 @@ module SexyScopes
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 5
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
+
9
+ class << self
10
+ # Allows {Version} to display ({to_s}) and behave ({to_str}) as a string
11
+ def to_str
12
+ STRING
13
+ end
14
+ alias_method :to_s, :to_str
15
+ end
8
16
  end
9
17
 
10
18
  VERSION = Version::STRING
@@ -3,11 +3,11 @@ module SexyScopes
3
3
  module Wrappers # :nodoc:
4
4
  private
5
5
  def extend_expression(expression)
6
- expression.extend(Arel::ExpressionWrappers)
6
+ expression.extend(ExpressionWrappers)
7
7
  end
8
8
 
9
9
  def extend_predicate(predicate)
10
- predicate.extend(Arel::PredicateWrappers)
10
+ predicate.extend(PredicateWrappers)
11
11
  end
12
12
  end
13
13
  end
data/sexy_scopes.gemspec CHANGED
@@ -20,10 +20,12 @@ Gem::Specification.new do |gem|
20
20
  gem.add_dependency 'activerecord', '~> 3.0'
21
21
 
22
22
  gem.add_development_dependency 'bundler', '~> 1.0'
23
- gem.add_development_dependency 'rake'
23
+ gem.add_development_dependency 'rake', '~> 0.9'
24
24
  gem.add_development_dependency 'rails', '~> 3.0'
25
25
  gem.add_development_dependency 'rspec', '~> 2.0'
26
- gem.add_development_dependency 'sqlite3'
26
+ gem.add_development_dependency 'sqlite3', '~> 1.0'
27
+ gem.add_development_dependency 'redcarpet', '~> 2.2'
28
+ gem.add_development_dependency 'yard', '~> 0.8'
27
29
  if RUBY_VERSION >= '1.9'
28
30
  gem.add_development_dependency 'simplecov'
29
31
  else
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe SexyScopes::ActiveRecord::ClassMethods do
4
+ it "should extend ActiveRecord::Base" do
5
+ ActiveRecord::Base.should be_extended_by SexyScopes::ActiveRecord::ClassMethods
6
+ end
7
+
8
+ describe ".attribute(name)" do
9
+ subject { User.attribute(:username) }
10
+
11
+ it "should return an Arel attribute for the given name" do
12
+ subject.should eql User.arel_table[:username]
13
+ end
14
+
15
+ it { should be_extended_by SexyScopes::ExpressionWrappers }
16
+ end
17
+
18
+ describe ".sql_literal(expression)" do
19
+ subject { User.sql_literal('NOW()') }
20
+
21
+ it "should return an Arel literal for given expression" do
22
+ subject.should eql(::Arel.sql('NOW()'))
23
+ end
24
+
25
+ it "should be aliased as `sql`" do
26
+ SexyScopes::ActiveRecord::ClassMethods.instance_method(:sql).should ==
27
+ SexyScopes::ActiveRecord::ClassMethods.instance_method(:sql_literal)
28
+ end
29
+
30
+ it { should be_extended_by SexyScopes::ExpressionWrappers }
31
+
32
+ it { should be_extended_by SexyScopes::PredicateWrappers }
33
+ end
34
+ end
35
+
36
+ describe SexyScopes::ActiveRecord::DynamicMethods do
37
+ before do
38
+ ActiveRecord::Migration.create_table :temp_users
39
+ ActiveRecord::Migration.add_column :temp_users, :username, :string
40
+ class ::TempUser < ActiveRecord::Base; end
41
+ end
42
+
43
+ after do
44
+ Object.send(:remove_const, :TempUser)
45
+ ActiveRecord::Migration.drop_table :temp_users
46
+ end
47
+
48
+ it "should delegate to `attribute` when the method name is the name of an existing column" do
49
+ TempUser.should respond_to(:username)
50
+ TempUser.should_receive(:attribute).with(:username).once.and_return(:ok)
51
+ TempUser.username.should == :ok
52
+ end
53
+
54
+ it "should define an attribute method to avoid repeated `method_missing` calls" do
55
+ TempUser.username
56
+ TempUser.should_not_receive(:method_missing)
57
+ TempUser.username
58
+ end
59
+
60
+ ruby_19 do
61
+ it "should return a Method object for an existing column" do
62
+ expect { TempUser.method(:username) }.to_not raise_error
63
+ end
64
+ end
65
+
66
+ it "should raise NoMethodError for a non-existing column" do
67
+ TempUser.should_not respond_to(:foobar)
68
+ expect { TempUser.foobar }.to raise_error NoMethodError
69
+ end
70
+
71
+ it "should not raise error when table doesn't exist" do
72
+ TempUser.table_name = "inexistent_users"
73
+ expect { TempUser.respond_to?(:username) }.to_not raise_error
74
+ end
75
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe SexyScopes::Arel::BooleanMethods do
4
+ before do
5
+ @attribute = User.attribute(:score)
6
+ @predicate = @attribute < 1000
7
+ @predicate2 = @attribute >= 200
8
+ end
9
+
10
+ describe ".not" do
11
+ subject { @predicate.not }
12
+
13
+ it_behaves_like "a predicate method"
14
+
15
+ it { should convert_to_sql %{NOT ("users"."score" < 1000)} }
16
+
17
+ it "should be aliased as `~`" do
18
+ @predicate.method(:~).should == @predicate.method(:not)
19
+ end
20
+ end
21
+
22
+ describe ".and(predicate)" do
23
+ subject { @predicate.and(@predicate2) }
24
+
25
+ it_behaves_like "a predicate method"
26
+
27
+ it { should convert_to_sql %{"users"."score" < 1000 AND "users"."score" >= 200} }
28
+
29
+ it "should be aliased as `&`" do
30
+ @predicate.method(:&).should == @predicate.method(:and)
31
+ end
32
+ end
33
+
34
+ describe ".or(predicate)" do
35
+ subject { @predicate.or(@predicate2) }
36
+
37
+ it_behaves_like "a predicate method"
38
+
39
+ it { should convert_to_sql %{("users"."score" < 1000 OR "users"."score" >= 200)} }
40
+
41
+ it "should be aliased as `|`" do
42
+ @predicate.method(:|).should == @predicate.method(:or)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,9 @@
1
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
2
+
3
+ ActiveRecord::Schema.verbose = false
4
+ ActiveRecord::Schema.define do
5
+ create_table :users do |t|
6
+ t.string :username
7
+ t.integer :score
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ RSpec::Matchers.define :be_extended_by do |expected|
2
+ match do |actual|
3
+ extended_modules = actual.singleton_class.included_modules
4
+ extended_modules.include?(expected)
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ RSpec::Matchers.define :convert_to_sql do |expected|
2
+ match do |actual|
3
+ actual.to_sql == expected
4
+ end
5
+
6
+ description do
7
+ "convert to the following SQL: #{expected}"
8
+ end
9
+
10
+ failure_message_for_should do |actual|
11
+ "expected generated SQL to be \n #{expected}\ngot\n #{actual.to_sql}"
12
+ end
13
+ end
@@ -1,14 +1,14 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  shared_examples "an expression method" do
4
4
  it "should return an Arel node" do
5
5
  subject.class.name.should =~ /^Arel::/
6
6
  end
7
7
 
8
- it { should be_extended_by SexyScopes::Arel::ExpressionWrappers }
8
+ it { should be_extended_by SexyScopes::ExpressionWrappers }
9
9
  end
10
10
 
11
- describe SexyScopes::Arel::ExpressionMethods do
11
+ describe SexyScopes::Arel::MathMethods do
12
12
  before do
13
13
  @attribute = User.attribute(:score)
14
14
  end
@@ -44,4 +44,12 @@ describe SexyScopes::Arel::ExpressionMethods do
44
44
 
45
45
  it { should convert_to_sql %{"users"."score" / 42.0} }
46
46
  end
47
+
48
+ describe "type coercion" do
49
+ subject { 42.0 / @attribute }
50
+
51
+ it_behaves_like "an expression method"
52
+
53
+ it { should convert_to_sql %{42.0 / "users"."score"} }
54
+ end
47
55
  end
@@ -1,12 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- shared_examples "a predicate method" do
4
- it "should return an Arel node" do
5
- subject.class.name.should =~ /^Arel::/
6
- end
7
-
8
- it { should be_extended_by SexyScopes::Arel::PredicateWrappers }
9
- end
1
+ require 'spec_helper'
10
2
 
11
3
  describe SexyScopes::Arel::PredicateMethods do
12
4
  before do
data/spec/spec_helper.rb CHANGED
@@ -7,36 +7,22 @@ require 'rspec'
7
7
  require 'active_record'
8
8
  require 'sexy_scopes'
9
9
 
10
- RSpec::Matchers.define :be_extended_by do |expected|
11
- match do |actual|
12
- extended_modules = actual.singleton_class.included_modules
13
- extended_modules.include?(expected)
14
- end
10
+ RSpec.configure do |config|
11
+ config.extend Module.new {
12
+ def ruby_19
13
+ yield if RUBY_VERSION >= "1.9"
14
+ end
15
+ }
15
16
  end
16
17
 
17
- RSpec::Matchers.define :convert_to_sql do |expected|
18
- match do |actual|
19
- actual.to_sql == expected
20
- end
21
-
22
- description do
23
- "convert to the following SQL: #{expected}"
24
- end
25
-
26
- failure_message_for_should do |actual|
27
- "expected generated SQL to be \n #{expected}\ngot\n #{actual.to_sql}"
28
- end
18
+ Dir.glob(File.join(File.dirname(__FILE__), '{fixtures,matchers}', '*')) do |file|
19
+ require file
29
20
  end
30
21
 
31
- ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
32
-
33
- ActiveRecord::Schema.verbose = false
34
- ActiveRecord::Schema.define do
35
- create_table :users do |t|
36
- t.string :username
37
- t.integer :score
22
+ shared_examples "a predicate method" do
23
+ it "should return an Arel node" do
24
+ subject.class.name.should =~ /^Arel::/
38
25
  end
39
- end
40
-
41
- class User < ActiveRecord::Base
26
+
27
+ it { should be_extended_by SexyScopes::PredicateWrappers }
42
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sexy_scopes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-29 00:00:00.000000000 Z
12
+ date: 2013-01-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -48,17 +48,17 @@ dependencies:
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ! '>='
51
+ - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: '0'
53
+ version: '0.9'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ! '>='
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '0.9'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: rails
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -96,17 +96,49 @@ dependencies:
96
96
  requirement: !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
- - - ! '>='
99
+ - - ~>
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: '1.0'
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
- - - ! '>='
107
+ - - ~>
108
108
  - !ruby/object:Gem::Version
109
- version: '0'
109
+ version: '1.0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: redcarpet
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '2.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '2.2'
126
+ - !ruby/object:Gem::Dependency
127
+ name: yard
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '0.8'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '0.8'
110
142
  - !ruby/object:Gem::Dependency
111
143
  name: simplecov
112
144
  requirement: !ruby/object:Gem::Requirement
@@ -137,18 +169,26 @@ files:
137
169
  - Rakefile
138
170
  - lib/sexy_scopes.rb
139
171
  - lib/sexy_scopes/active_record.rb
172
+ - lib/sexy_scopes/active_record/class_methods.rb
173
+ - lib/sexy_scopes/active_record/dynamic_methods.rb
140
174
  - lib/sexy_scopes/arel.rb
141
- - lib/sexy_scopes/arel/expression_methods.rb
142
- - lib/sexy_scopes/arel/expression_wrappers.rb
175
+ - lib/sexy_scopes/arel/boolean_methods.rb
176
+ - lib/sexy_scopes/arel/math_methods.rb
143
177
  - lib/sexy_scopes/arel/predicate_methods.rb
144
- - lib/sexy_scopes/arel/predicate_wrappers.rb
178
+ - lib/sexy_scopes/expression_wrappers.rb
179
+ - lib/sexy_scopes/predicate_wrappers.rb
145
180
  - lib/sexy_scopes/railtie.rb
146
181
  - lib/sexy_scopes/version.rb
147
182
  - lib/sexy_scopes/wrappers.rb
148
183
  - sexy_scopes.gemspec
149
- - spec/expression_methods_spec.rb
184
+ - spec/active_record_spec.rb
185
+ - spec/boolean_methods_spec.rb
186
+ - spec/fixtures/models.rb
187
+ - spec/fixtures/schema.rb
188
+ - spec/matchers/be_extended_by.rb
189
+ - spec/matchers/convert_to_sql.rb
190
+ - spec/math_methods_spec.rb
150
191
  - spec/predicate_methods_spec.rb
151
- - spec/sexy_scopes_spec.rb
152
192
  - spec/spec_helper.rb
153
193
  homepage: https://github.com/samleb/sexy_scopes
154
194
  licenses:
@@ -163,18 +203,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
203
  - - ! '>='
164
204
  - !ruby/object:Gem::Version
165
205
  version: '0'
166
- segments:
167
- - 0
168
- hash: 953557397482339219
169
206
  required_rubygems_version: !ruby/object:Gem::Requirement
170
207
  none: false
171
208
  requirements:
172
209
  - - ! '>='
173
210
  - !ruby/object:Gem::Version
174
211
  version: '0'
175
- segments:
176
- - 0
177
- hash: 953557397482339219
178
212
  requirements: []
179
213
  rubyforge_project:
180
214
  rubygems_version: 1.8.23
@@ -182,7 +216,13 @@ signing_key:
182
216
  specification_version: 3
183
217
  summary: Write beautiful and expressive ActiveRecord scopes without SQL.
184
218
  test_files:
185
- - spec/expression_methods_spec.rb
219
+ - spec/active_record_spec.rb
220
+ - spec/boolean_methods_spec.rb
221
+ - spec/fixtures/models.rb
222
+ - spec/fixtures/schema.rb
223
+ - spec/matchers/be_extended_by.rb
224
+ - spec/matchers/convert_to_sql.rb
225
+ - spec/math_methods_spec.rb
186
226
  - spec/predicate_methods_spec.rb
187
- - spec/sexy_scopes_spec.rb
188
227
  - spec/spec_helper.rb
228
+ has_rdoc:
@@ -1,9 +0,0 @@
1
- module SexyScopes
2
- module Arel
3
- module ExpressionWrappers
4
- include Wrappers
5
- include PredicateMethods
6
- include ExpressionMethods
7
- end
8
- end
9
- end
@@ -1,47 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe SexyScopes::ActiveRecord do
4
- it "should extend ActiveRecord::Base" do
5
- ActiveRecord::Base.should be_extended_by SexyScopes::ActiveRecord
6
- end
7
-
8
- describe ".attribute(name)" do
9
- subject { User.attribute(:username) }
10
-
11
- it "should return an Arel attribute for the given name" do
12
- subject.should eql User.arel_table[:username]
13
- end
14
-
15
- it { should be_extended_by SexyScopes::Arel::ExpressionWrappers }
16
- end
17
-
18
- describe ".sql_literal(expression)" do
19
- subject { User.sql_literal('NOW()') }
20
-
21
- it "should return an Arel literal for given expression" do
22
- subject.should eql(::Arel.sql('NOW()'))
23
- end
24
-
25
- it "should be aliased as `sql`" do
26
- SexyScopes::ActiveRecord.instance_method(:sql).should ==
27
- SexyScopes::ActiveRecord.instance_method(:sql_literal)
28
- end
29
-
30
- it { should be_extended_by SexyScopes::Arel::ExpressionWrappers }
31
-
32
- it { should be_extended_by SexyScopes::Arel::PredicateWrappers }
33
- end
34
-
35
- context "dynamic method handling (method_missing/respond_to?)" do
36
- it "should delegate to `attribute` when the method name is the name of an existing column" do
37
- User.should respond_to(:username)
38
- User.should_receive(:attribute).with(:username).once.and_return(:ok)
39
- User.username.should == :ok
40
- end
41
-
42
- it "should raise NoMethodError otherwise" do
43
- User.should_not respond_to(:foobar)
44
- lambda { User.foobar }.should raise_error NoMethodError
45
- end
46
- end
47
- end