Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
aovertus committed Sep 15, 2017
2 parents bf9c0a4 + 25d5a9e commit 3064ad5
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/Gemfile.lock
11 changes: 10 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in simple_enum-scopes.gemspec

# Specify your gem's dependencies in simple_enum-persistence.gemspec
gemspec

group :test do
gem 'pry'
end

# some development deps
gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
gem 'sqlite3', platform: :ruby
gem 'bson_ext', platform: :ruby
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ It'll avoid to write a bunch of scopes doing basically the same job.
## Usage

```ruby
class User
as_enum :states, [:very_bad, :bad, :good, :very_good]
class Object
as_enum :state, [:very_bad, :bad, :good, :very_good]
end


User.status_as(:bad, :very_good)
# User.where(status_cd: [User.bad, User.very_good])
Object.states_as(:bad, :very_good)
# Object.where(state_cd: [Object.states[:bad], Object.states[:very_good]])


User.status_between(:bad, :very_good)
# User.where(status_cd: User.bad..User.very_good)
Object.state_between(:bad, :very_good)
# Object.where(state_cd: Object.states[:bad]..Object.states[:very_good])
```

## License
Expand Down
9 changes: 1 addition & 8 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
require "bundler/gem_tasks"

desc 'Default: run all unit tests for both ActiveRecord & Mongoid.'
desc 'Default: run all unit tests for ActiveRecord.'
task :default => :spec

desc 'Run rspec test suite'
task :spec do
sh 'bundle exec rspec spec/'
end

# Mongodb
directory "tmp/mongodb.data"
desc 'Run mongodb in tmp/'
task :mongodb => [:'tmp/mongodb.data'] do |t|
system "mongod", "--dbpath", "tmp/mongodb.data"
end
3 changes: 2 additions & 1 deletion lib/simple_enum/scopes.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'simple_enum/multiple/version'
require 'simple_enum/scopes/extension'
require 'simple_enum/scopes/version'

SimpleEnum.register_generator :scopes, SimpleEnum::Scopes::Extension
16 changes: 8 additions & 8 deletions lib/simple_enum/scopes/extension.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
module SimpleEnum
module Scope
module Scopes
module Extension
def generate_enum_scopes_extension_for enum, accessor
define_range_scopes(enum, accessor)
define_multiple_values_scope(enum_accessor)
define_range_scope_method(enum, accessor)
define_multiple_values_scope_method(enum, accessor)
end

private

def define_range_scope_methods(enum, accessor)
def define_range_scope_method(enum, accessor)
singleton_class.send(:define_method, "#{accessor.name}_between") do |min_val, max_val|
where(accessor.source => singleton_class.public_send(min_val)..singleton_class.public_send(max_val))
where(accessor.source => enum[min_val]..enum[max_val])
end
end

def define_multiple_values_scope_method(enum, accessor)
# arr can be an array of values or a single value
singleton_class.send(:define_method, "#{accessor.name}_as") do |*arr|
targeted_values = arr & enum.keys
where(accessor.source => targeted_values)
singleton_class.send(:define_method, "#{accessor.name.pluralize}_as") do |arr|
targeted_values = Array(arr).map(&:to_s) & enum.keys
where(accessor.source => targeted_values.map{ |value| enum[value] })
end
end
end
Expand Down
1 change: 0 additions & 1 deletion simple_enum-scopes.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,5 @@ Gem::Specification.new do |spec|

spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'activerecord', '>= 4.0.0'
spec.add_development_dependency 'mongoid', '>= 4.0.0'
spec.add_development_dependency 'rspec', '~> 2.14'
end
56 changes: 56 additions & 0 deletions spec/simple_enum/scopes/active_record_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'spec_helper'

describe SimpleEnum::Scopes, active_record: true do

fake_active_record(:klass) do
as_enum :state, [:very_bad, :bad, :good, :very_good]
end

context 'generate_enum_scopes_extension_for' do
context 'define_range_scope_method' do
context 'gem query' do
context 'objects are in range' do
let!(:bad) { klass.create(state: :bad) }
let!(:good) { klass.create(state: :good) }

it 'returns the object in range' do
objects = klass.state_between(:bad, :very_good)
expect(objects.count).to eq(2)
expect(objects.map(&:state)).to eq %i(bad good)
end
end

context 'object is out of range' do
let!(:very_good) { klass.create(state: :very_good) }

it 'returns no object' do
objects = klass.state_between(:very_bad, :good)
expect(objects).to be_empty
end
end
end
end

context 'define_multiple_values_scope_method' do
let!(:very_bad) { klass.create(state: :very_bad) }
let!(:bad) { klass.create(state: :bad) }
let!(:good) { klass.create(state: :good) }
let!(:very_good) { klass.create(state: :very_good) }

context 'gem query' do
it 'returns equivalent of ActiveRecord query' do
objects = klass.states_as(:bad)
expect(objects.count).to eq(1)
expect(objects.first).to be_bad
end

it 'returns equivalent of ActiveRecord query' do
statees = %i(very_bad bad)
objects = klass.states_as(statees)
expect(objects.count).to eq(2)
expect(objects.map(&:state)).to eq(statees)
end
end
end
end
end
20 changes: 20 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'rubygems'
require 'bundler/setup'
require 'pry'

require 'rspec'
require 'active_record'

require 'simple_enum'
require 'simple_enum/scopes'

require 'support/active_record_support'
require 'support/i18n_support'
require 'support/model_support'


RSpec.configure do |config|
config.include ModelSupport
config.include I18nSupport, i18n: true
config.include ActiveRecordSupport, active_record: true
end
19 changes: 19 additions & 0 deletions spec/support/active_record_support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module ActiveRecordSupport
def self.connection
@connection_pool ||= ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
ActiveRecord::Base.connection
end

def self.included(base)
base.before(:each) { self.reset_active_record }
end

def reset_active_record
ActiveRecordSupport.connection.create_table :dummies, :force => true do |t|
t.column :state_cd, :integer
end
end
end

# Behave like the railtie.rb
ActiveRecord::Base.send :extend, SimpleEnum::Attribute
12 changes: 12 additions & 0 deletions spec/support/i18n_support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module I18nSupport
def self.included(base)
base.let!(:i18n_previous_backend) { I18n.backend }
base.let(:i18n_backend) { I18n::Backend::Simple.new() }
base.before { I18n.backend = i18n_backend }
base.after { I18n.backend = i18n_previous_backend }
end

def store_translations(lang, translations)
i18n_backend.store_translations lang, translations
end
end
20 changes: 20 additions & 0 deletions spec/support/model_support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'active_record'
# require 'mongoid'

module ModelSupport
def self.included(base)
base.extend ClassMethods
end

module ClassMethods

def fake_active_record(name, &block)
let(name) {
Class.new(ActiveRecord::Base) do
self.table_name = 'dummies'
instance_eval &block
end
}
end
end
end
47 changes: 47 additions & 0 deletions spec/support/mongoid_support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'mongoid'

# Hack to disable auto-retries for Mongo::Client - unless running
# on Travis CI
if ENV['CI'] && Mongoid.respond_to?(:default_client)
require 'mongo'

module Mongo
class Cluster
def scan!
raise ArgumentError, 'no retries please.'
end
end
end
end

module MongoidSupport
def self.connection
@connection_config ||= begin
Mongoid.configure do |config|
config.connect_to("simple_enum_mongoid_test", max_retries: ENV['CI'] ? 5 : 0)
end

# Disable client errors
Moped.logger.level = Logger::ERROR if defined?(Moped)
Mongo::Logger.logger.level = Logger::ERROR if defined?(Mongo)

# Return instance
return Mongoid.default_client if Mongoid.respond_to?(:default_client)
Mongoid.default_session
end
end

def self.included(base)
base.before {
begin
MongoidSupport.connection.database_names
rescue => e
if ENV['CI']
raise e
else
skip "Start MongoDB server to run Mongoid integration tests..."
end
end
}
end
end

0 comments on commit 3064ad5

Please sign in to comment.