mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
Add support for Nobrainer (RethinkDB)
* Add persistence for NoBrainer * Add tests for NoBrainer * Show the ORM version when running the tests * Add a Dockerfile and a docker-compose.yml file allowing to run from anywhere very easily the test suite with `docker-compose run --rm aasm\' * Moves the Mongoid database name definition in the gem loader (avoiding code repetition) * Update the CHANGELOG.md and the README.md files * Add Rails generator for NoBrainer
This commit is contained in:
parent
f75f03b0db
commit
27b73c0632
31 changed files with 1037 additions and 40 deletions
|
@ -11,12 +11,17 @@ services:
|
||||||
- mongodb
|
- mongodb
|
||||||
- redis-server
|
- redis-server
|
||||||
|
|
||||||
|
addons:
|
||||||
|
rethinkdb: '2.3.6'
|
||||||
|
|
||||||
gemfile:
|
gemfile:
|
||||||
- gemfiles/rails_3.2.gemfile
|
- gemfiles/rails_3.2.gemfile
|
||||||
- gemfiles/rails_4.0.gemfile
|
- gemfiles/rails_4.0.gemfile
|
||||||
- gemfiles/rails_4.2.gemfile
|
- gemfiles/rails_4.2.gemfile
|
||||||
- gemfiles/rails_4.2_mongoid_5.gemfile
|
- gemfiles/rails_4.2_mongoid_5.gemfile
|
||||||
|
- gemfiles/rails_4.2_nobrainer.gemfile
|
||||||
- gemfiles/rails_5.0.gemfile
|
- gemfiles/rails_5.0.gemfile
|
||||||
|
- gemfiles/rails_5.0_nobrainer.gemfile
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- mkdir /tmp/dynamodb
|
- mkdir /tmp/dynamodb
|
||||||
|
|
53
Appraisals
53
Appraisals
|
@ -1,47 +1,58 @@
|
||||||
appraise 'rails_3.2' do
|
appraise 'rails_3.2' do
|
||||||
gem 'rails', '~>3.2.22'
|
gem 'rails', '~> 3.2.22'
|
||||||
gem 'mongoid', '~>3.1'
|
gem 'mongoid', '~> 3.1'
|
||||||
gem 'sequel'
|
gem 'sequel'
|
||||||
gem 'bson_ext', :platforms => :ruby
|
gem 'bson_ext', platforms: :ruby
|
||||||
gem 'test-unit', '~> 3.0'
|
gem 'test-unit', '~> 3.0'
|
||||||
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', :platforms => :jruby
|
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', platforms: :jruby
|
||||||
end
|
end
|
||||||
|
|
||||||
appraise 'rails_4.0' do
|
appraise 'rails_4.0' do
|
||||||
gem 'mime-types', '~> 2', :platforms => [:ruby_19, :jruby]
|
gem 'mime-types', '~> 2', platforms: %i[ruby_19 jruby]
|
||||||
gem 'rails', '4.0.13'
|
gem 'rails', '4.0.13'
|
||||||
gem 'mongoid', '~>4.0'
|
gem 'mongoid', '~> 4.0'
|
||||||
gem 'sequel'
|
gem 'sequel'
|
||||||
gem 'dynamoid', '~> 1', :platforms => :ruby
|
gem 'dynamoid', '~> 1', platforms: :ruby
|
||||||
gem 'aws-sdk', '~>2', :platforms => :ruby
|
gem 'aws-sdk', '~> 2', platforms: :ruby
|
||||||
gem 'redis-objects'
|
gem 'redis-objects'
|
||||||
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', :platforms => :jruby
|
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', platforms: :jruby
|
||||||
end
|
end
|
||||||
|
|
||||||
appraise 'rails_4.2' do
|
appraise 'rails_4.2' do
|
||||||
gem 'nokogiri', '1.6.8.1', :platforms => [:ruby_19]
|
gem 'nokogiri', '1.6.8.1', platforms: %i[ruby_19]
|
||||||
gem 'mime-types', '~> 2', :platforms => [:ruby_19, :jruby]
|
gem 'mime-types', '~> 2', platforms: %i[ruby_19 jruby]
|
||||||
gem 'rails', '4.2.5'
|
gem 'rails', '4.2.5'
|
||||||
gem 'mongoid', '~>4.0'
|
gem 'mongoid', '~> 4.0'
|
||||||
gem 'sequel'
|
gem 'sequel'
|
||||||
gem 'dynamoid', '~> 1', :platforms => :ruby
|
gem 'dynamoid', '~> 1', platforms: :ruby
|
||||||
gem 'aws-sdk', '~>2', :platforms => :ruby
|
gem 'aws-sdk', '~> 2', platforms: :ruby
|
||||||
gem 'redis-objects'
|
gem 'redis-objects'
|
||||||
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', :platforms => :jruby
|
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', platforms: :jruby
|
||||||
|
end
|
||||||
|
|
||||||
|
appraise 'rails_4.2_nobrainer' do
|
||||||
|
gem 'rails', '4.2.5'
|
||||||
|
gem 'nobrainer', '~> 0.33.0'
|
||||||
|
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', platforms: :jruby
|
||||||
end
|
end
|
||||||
|
|
||||||
appraise 'rails_4.2_mongoid_5' do
|
appraise 'rails_4.2_mongoid_5' do
|
||||||
gem 'mime-types', '~> 2', :platforms => [:ruby_19, :jruby]
|
gem 'mime-types', '~> 2', platforms: %i[ruby_19 jruby]
|
||||||
gem 'rails', '4.2.5'
|
gem 'rails', '4.2.5'
|
||||||
gem 'mongoid', '~>5.0'
|
gem 'mongoid', '~> 5.0'
|
||||||
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', :platforms => :jruby
|
gem 'activerecord-jdbcsqlite3-adapter', '1.3.24', platforms: :jruby
|
||||||
end
|
end
|
||||||
|
|
||||||
appraise 'rails_5.0' do
|
appraise 'rails_5.0' do
|
||||||
gem 'rails', '5.0.0'
|
gem 'rails', '5.0.0'
|
||||||
gem 'mongoid', '~>6.0'
|
gem 'mongoid', '~> 6.0'
|
||||||
gem 'sequel'
|
gem 'sequel'
|
||||||
gem 'dynamoid', '~> 1', :platforms => :ruby
|
gem 'dynamoid', '~> 1', platforms: :ruby
|
||||||
gem 'aws-sdk', '~>2', :platforms => :ruby
|
gem 'aws-sdk', '~> 2', platforms: :ruby
|
||||||
gem 'redis-objects'
|
gem 'redis-objects'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
appraise 'rails_5.0_nobrainer' do
|
||||||
|
gem 'rails', '5.0.0'
|
||||||
|
gem 'nobrainer', '~> 0.33.0'
|
||||||
|
end
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
## unreleased
|
## unreleased
|
||||||
|
|
||||||
|
* Add support for Nobrainer (RethinkDB)
|
||||||
|
|
||||||
## 4.12.3
|
## 4.12.3
|
||||||
|
|
||||||
* Add to AASM fire(event) and fire!(event) methods [#494](https://github.com/aasm/aasm/pull/494), thanks to [slayer](https://github.com/slayer)
|
* Add to AASM fire(event) and fire!(event) methods [#494](https://github.com/aasm/aasm/pull/494), thanks to [slayer](https://github.com/slayer)
|
||||||
|
|
44
Dockerfile
Normal file
44
Dockerfile
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
FROM ruby:2.3.4-slim
|
||||||
|
|
||||||
|
LABEL maintainer="AASM"
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
# ~~~~ System locales ~~~~
|
||||||
|
RUN apt-get update && apt-get install -y locales && \
|
||||||
|
dpkg-reconfigure locales && \
|
||||||
|
locale-gen C.UTF-8 && \
|
||||||
|
/usr/sbin/update-locale LANG=C.UTF-8 && \
|
||||||
|
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen && \
|
||||||
|
locale-gen
|
||||||
|
|
||||||
|
# Set default locale for the environment
|
||||||
|
ENV LC_ALL C.UTF-8
|
||||||
|
ENV LANG en_US.UTF-8
|
||||||
|
ENV LANGUAGE en_US.UTF-8
|
||||||
|
ENV APP_HOME /application
|
||||||
|
|
||||||
|
# ~~~~ Application dependencies ~~~~
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y libsqlite3-dev \
|
||||||
|
build-essential \
|
||||||
|
git
|
||||||
|
|
||||||
|
# ~~~~ Bundler ~~~~
|
||||||
|
RUN gem install bundler
|
||||||
|
|
||||||
|
WORKDIR $APP_HOME
|
||||||
|
RUN mkdir -p $APP_HOME/lib/aasm/
|
||||||
|
|
||||||
|
COPY Gemfile* $APP_HOME/
|
||||||
|
COPY *.gemspec $APP_HOME/
|
||||||
|
COPY lib/aasm/version.rb $APP_HOME/lib/aasm/
|
||||||
|
|
||||||
|
ENV BUNDLE_GEMFILE=$APP_HOME/Gemfile \
|
||||||
|
BUNDLE_JOBS=8 \
|
||||||
|
BUNDLE_PATH=/bundle
|
||||||
|
|
||||||
|
RUN bundle install
|
||||||
|
|
||||||
|
# ~~~~ Import application ~~~~
|
||||||
|
COPY . $APP_HOME
|
24
README.md
24
README.md
|
@ -24,6 +24,7 @@
|
||||||
- [Sequel](#sequel)
|
- [Sequel](#sequel)
|
||||||
- [Dynamoid](#dynamoid)
|
- [Dynamoid](#dynamoid)
|
||||||
- [Mongoid](#mongoid)
|
- [Mongoid](#mongoid)
|
||||||
|
- [Nobrainer](#nobrainer)
|
||||||
- [Redis](#redis)
|
- [Redis](#redis)
|
||||||
- [Automatic Scopes](#automatic-scopes)
|
- [Automatic Scopes](#automatic-scopes)
|
||||||
- [Transaction support](#transaction-support)
|
- [Transaction support](#transaction-support)
|
||||||
|
@ -52,10 +53,8 @@
|
||||||
This package contains AASM, a library for adding finite state machines to Ruby classes.
|
This package contains AASM, a library for adding finite state machines to Ruby classes.
|
||||||
|
|
||||||
AASM started as the *acts_as_state_machine* plugin but has evolved into a more generic library
|
AASM started as the *acts_as_state_machine* plugin but has evolved into a more generic library
|
||||||
that no longer targets only ActiveRecord models. It currently provides adapters for
|
that no longer targets only ActiveRecord models. It currently provides adapters for many
|
||||||
[ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html),
|
ORMs but it can be used for any Ruby class, no matter what parent class it has (if any).
|
||||||
and [Mongoid](http://mongoid.org/) but it can be used for any Ruby class, no matter what
|
|
||||||
parent class it has (if any).
|
|
||||||
|
|
||||||
## Upgrade from version 3 to 4
|
## Upgrade from version 3 to 4
|
||||||
|
|
||||||
|
@ -825,6 +824,23 @@ class Job
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### NoBrainer
|
||||||
|
|
||||||
|
AASM also supports persistence to [RethinkDB](https://www.rethinkdb.com/)
|
||||||
|
if you're using [Nobrainer](http://nobrainer.io/).
|
||||||
|
Make sure to include NoBrainer::Document before you include AASM.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class Job
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
field :aasm_state
|
||||||
|
aasm do
|
||||||
|
...
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
### Redis
|
### Redis
|
||||||
|
|
||||||
AASM also supports persistence in Redis via
|
AASM also supports persistence in Redis via
|
||||||
|
|
40
docker-compose.yml
Normal file
40
docker-compose.yml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
version: "2"
|
||||||
|
|
||||||
|
services:
|
||||||
|
aasm:
|
||||||
|
image: aasm/aasm
|
||||||
|
build: .
|
||||||
|
command: bash -c 'bundle exec appraisal install && bundle exec appraisal rspec'
|
||||||
|
environment:
|
||||||
|
- DYNAMODB_HOST=dynamodb
|
||||||
|
- DYNAMODB_PORT=8000
|
||||||
|
- MONGODB_HOST=mongo
|
||||||
|
- MONGODB_PORT=27017
|
||||||
|
- RAILS_ENV=development
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- REDIS_PORT=6379
|
||||||
|
- RETHINKDB_DB=rethinkdb_test
|
||||||
|
- RETHINKDB_HOST=rethinkdb
|
||||||
|
- RETHINKDB_PORT=28015
|
||||||
|
depends_on:
|
||||||
|
- dynamodb
|
||||||
|
- mongo
|
||||||
|
- redis
|
||||||
|
- rethinkdb
|
||||||
|
volumes:
|
||||||
|
- .:/application
|
||||||
|
volumes_from:
|
||||||
|
- bundle
|
||||||
|
bundle:
|
||||||
|
image: aasm/aasm
|
||||||
|
command: echo Bundler data container
|
||||||
|
volumes:
|
||||||
|
- /bundle
|
||||||
|
dynamodb:
|
||||||
|
image: cnadiminti/dynamodb-local:2017-02-16
|
||||||
|
mongo:
|
||||||
|
image: mongo:3.6.1
|
||||||
|
redis:
|
||||||
|
image: redis:4.0.6-alpine
|
||||||
|
rethinkdb:
|
||||||
|
image: rethinkdb:2.3.6
|
9
gemfiles/rails_4.2_nobrainer.gemfile
Normal file
9
gemfiles/rails_4.2_nobrainer.gemfile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# This file was generated by Appraisal
|
||||||
|
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "sqlite3", platforms: :ruby
|
||||||
|
gem "rails", "5.1.3"
|
||||||
|
gem "nobrainer", "~>0.33.0"
|
||||||
|
|
||||||
|
gemspec path: "../"
|
9
gemfiles/rails_5.0_nobrainer.gemfile
Normal file
9
gemfiles/rails_5.0_nobrainer.gemfile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# This file was generated by Appraisal
|
||||||
|
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "sqlite3", platforms: :ruby
|
||||||
|
gem "rails", "5.1.3"
|
||||||
|
gem "nobrainer", "~>0.33.0"
|
||||||
|
|
||||||
|
gemspec path: "../"
|
|
@ -12,6 +12,9 @@ module AASM
|
||||||
elsif hierarchy.include?("Mongoid::Document")
|
elsif hierarchy.include?("Mongoid::Document")
|
||||||
require_persistence :mongoid
|
require_persistence :mongoid
|
||||||
include_persistence base, :mongoid
|
include_persistence base, :mongoid
|
||||||
|
elsif hierarchy.include?("NoBrainer::Document")
|
||||||
|
require_persistence :no_brainer
|
||||||
|
include_persistence base, :no_brainer
|
||||||
elsif hierarchy.include?("Sequel::Model")
|
elsif hierarchy.include?("Sequel::Model")
|
||||||
require_persistence :sequel
|
require_persistence :sequel
|
||||||
include_persistence base, :sequel
|
include_persistence base, :sequel
|
||||||
|
|
105
lib/aasm/persistence/no_brainer_persistence.rb
Normal file
105
lib/aasm/persistence/no_brainer_persistence.rb
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
require 'aasm/persistence/orm'
|
||||||
|
module AASM
|
||||||
|
module Persistence
|
||||||
|
module NoBrainerPersistence
|
||||||
|
# This method:
|
||||||
|
#
|
||||||
|
# * extends the model with ClassMethods
|
||||||
|
# * includes InstanceMethods
|
||||||
|
#
|
||||||
|
# Adds
|
||||||
|
#
|
||||||
|
# before_validation :aasm_ensure_initial_state
|
||||||
|
#
|
||||||
|
# As a result, it doesn't matter when you define your methods - the following 2 are equivalent
|
||||||
|
#
|
||||||
|
# class Foo
|
||||||
|
# include NoBrainer::Document
|
||||||
|
# def aasm_write_state(state)
|
||||||
|
# "bar"
|
||||||
|
# end
|
||||||
|
# include AASM
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# class Foo
|
||||||
|
# include NoBrainer::Document
|
||||||
|
# include AASM
|
||||||
|
# def aasm_write_state(state)
|
||||||
|
# "bar"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
def self.included(base)
|
||||||
|
base.send(:include, AASM::Persistence::Base)
|
||||||
|
base.send(:include, AASM::Persistence::ORM)
|
||||||
|
base.send(:include, AASM::Persistence::NoBrainerPersistence::InstanceMethods)
|
||||||
|
base.extend AASM::Persistence::NoBrainerPersistence::ClassMethods
|
||||||
|
|
||||||
|
base.after_initialize :aasm_ensure_initial_state
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def aasm_create_scope(state_machine_name, scope_name)
|
||||||
|
scope_options = lambda {
|
||||||
|
where(aasm(state_machine_name).attribute_name.to_sym => scope_name.to_s)
|
||||||
|
}
|
||||||
|
send(:scope, scope_name, scope_options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module InstanceMethods
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def aasm_save
|
||||||
|
self.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def aasm_raise_invalid_record
|
||||||
|
raise NoBrainer::Error::DocumentInvalid.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def aasm_supports_transactions?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def aasm_update_column(attribute_name, value)
|
||||||
|
write_attribute(attribute_name, value)
|
||||||
|
save(validate: false)
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def aasm_read_attribute(name)
|
||||||
|
read_attribute(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def aasm_write_attribute(name, value)
|
||||||
|
write_attribute(name, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Ensures that if the aasm_state column is nil and the record is new
|
||||||
|
# that the initial state gets populated before validation on create
|
||||||
|
#
|
||||||
|
# foo = Foo.new
|
||||||
|
# foo.aasm_state # => nil
|
||||||
|
# foo.valid?
|
||||||
|
# foo.aasm_state # => "open" (where :open is the initial state)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# foo = Foo.find(:first)
|
||||||
|
# foo.aasm_state # => 1
|
||||||
|
# foo.aasm_state = nil
|
||||||
|
# foo.valid?
|
||||||
|
# foo.aasm_state # => nil
|
||||||
|
#
|
||||||
|
def aasm_ensure_initial_state
|
||||||
|
AASM::StateMachineStore.fetch(self.class, true).machine_names.each do |name|
|
||||||
|
aasm_column = self.class.aasm(name).attribute_name
|
||||||
|
aasm(name).enter_initial_state if read_attribute(aasm_column).blank?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end # InstanceMethods
|
||||||
|
end
|
||||||
|
end # Persistence
|
||||||
|
end # AASM
|
28
lib/generators/nobrainer/aasm_generator.rb
Normal file
28
lib/generators/nobrainer/aasm_generator.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
require 'rails/generators/named_base'
|
||||||
|
require 'generators/aasm/orm_helpers'
|
||||||
|
|
||||||
|
module NoBrainer
|
||||||
|
module Generators
|
||||||
|
class AASMGenerator < Rails::Generators::NamedBase
|
||||||
|
include AASM::Generators::OrmHelpers
|
||||||
|
namespace 'nobrainer:aasm'
|
||||||
|
argument :column_name, type: :string, default: 'aasm_state'
|
||||||
|
|
||||||
|
def generate_model
|
||||||
|
invoke 'nobrainer:model', [name] unless model_exists?
|
||||||
|
end
|
||||||
|
|
||||||
|
def inject_aasm_content
|
||||||
|
inject_into_file model_path, model_contents, after: "include NoBrainer::Document::Timestamps\n" if model_exists?
|
||||||
|
end
|
||||||
|
|
||||||
|
def inject_field_types
|
||||||
|
inject_into_file model_path, migration_data, after: "include NoBrainer::Document::Timestamps\n" if model_exists?
|
||||||
|
end
|
||||||
|
|
||||||
|
def migration_data
|
||||||
|
" field :#{column_name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,6 +16,7 @@ exclude_files = [
|
||||||
'aasm/persistence/active_record_persistence.rb',
|
'aasm/persistence/active_record_persistence.rb',
|
||||||
'aasm/persistence/dynamoid_persistence.rb',
|
'aasm/persistence/dynamoid_persistence.rb',
|
||||||
'aasm/persistence/mongoid_persistence.rb',
|
'aasm/persistence/mongoid_persistence.rb',
|
||||||
|
'aasm/persistence/no_brainer_persistence.rb',
|
||||||
'aasm/persistence/sequel_persistence.rb',
|
'aasm/persistence/sequel_persistence.rb',
|
||||||
'aasm/persistence/redis_persistence.rb'
|
'aasm/persistence/redis_persistence.rb'
|
||||||
]
|
]
|
||||||
|
|
29
spec/generators/no_brainer_generator_spec.rb
Normal file
29
spec/generators/no_brainer_generator_spec.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
if defined?(NoBrainer::Document)
|
||||||
|
require 'generator_spec'
|
||||||
|
require 'generators/nobrainer/aasm_generator'
|
||||||
|
|
||||||
|
describe NoBrainer::Generators::AASMGenerator, type: :generator do
|
||||||
|
destination File.expand_path('../../../tmp', __FILE__)
|
||||||
|
|
||||||
|
before(:all) do
|
||||||
|
prepare_destination
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates model with aasm block for default column_name' do
|
||||||
|
run_generator %w[user]
|
||||||
|
assert_file 'app/models/user.rb', /include AASM\n\n aasm do\n end\n/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates model with aasm block for custom column_name' do
|
||||||
|
run_generator %w[user state]
|
||||||
|
assert_file 'app/models/user.rb', /aasm :column => 'state' do\n end\n/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates model with aasm block for namespaced model' do
|
||||||
|
run_generator %w[Admin::User state]
|
||||||
|
assert_file 'app/models/admin/user.rb', /aasm :column => 'state' do\n end\n/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
36
spec/models/nobrainer/complex_no_brainer_example.rb
Normal file
36
spec/models/nobrainer/complex_no_brainer_example.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
class ComplexNoBrainerExample
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :left, type: String
|
||||||
|
field :right, type: String
|
||||||
|
|
||||||
|
aasm :left, column: 'left' do
|
||||||
|
state :one, initial: true
|
||||||
|
state :two
|
||||||
|
state :three
|
||||||
|
|
||||||
|
event :increment do
|
||||||
|
transitions from: :one, to: :two
|
||||||
|
transitions from: :two, to: :three
|
||||||
|
end
|
||||||
|
event :reset do
|
||||||
|
transitions from: :three, to: :one
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
aasm :right, column: 'right' do
|
||||||
|
state :alpha, initial: true
|
||||||
|
state :beta
|
||||||
|
state :gamma
|
||||||
|
|
||||||
|
event :level_up do
|
||||||
|
transitions from: :alpha, to: :beta
|
||||||
|
transitions from: :beta, to: :gamma
|
||||||
|
end
|
||||||
|
event :level_down do
|
||||||
|
transitions from: :gamma, to: :beta
|
||||||
|
transitions from: :beta, to: :alpha
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
39
spec/models/nobrainer/invalid_persistor_no_brainer.rb
Normal file
39
spec/models/nobrainer/invalid_persistor_no_brainer.rb
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
class InvalidPersistorNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :name
|
||||||
|
field :status
|
||||||
|
|
||||||
|
aasm :left, column: :status, skip_validation_on_save: true do
|
||||||
|
state :sleeping, initial: true
|
||||||
|
state :running
|
||||||
|
event :run do
|
||||||
|
transitions to: :running, from: :sleeping
|
||||||
|
end
|
||||||
|
event :sleep do
|
||||||
|
transitions to: :sleeping, from: :running
|
||||||
|
end
|
||||||
|
end
|
||||||
|
validates_presence_of :name
|
||||||
|
end
|
||||||
|
|
||||||
|
class MultipleInvalidPersistorNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :name
|
||||||
|
field :status
|
||||||
|
|
||||||
|
aasm :left, column: :status, skip_validation_on_save: true do
|
||||||
|
state :sleeping, initial: true
|
||||||
|
state :running
|
||||||
|
event :run do
|
||||||
|
transitions to: :running, from: :sleeping
|
||||||
|
end
|
||||||
|
event :sleep do
|
||||||
|
transitions to: :sleeping, from: :running
|
||||||
|
end
|
||||||
|
end
|
||||||
|
validates_presence_of :name
|
||||||
|
end
|
21
spec/models/nobrainer/no_scope_no_brainer.rb
Normal file
21
spec/models/nobrainer/no_scope_no_brainer.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
class NoScopeNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
|
||||||
|
aasm create_scopes: false, column: :status do
|
||||||
|
state :ignored_scope
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class NoScopeNoBrainerMultiple
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
|
||||||
|
aasm :left, create_scopes: false, column: :status do
|
||||||
|
state :ignored_scope
|
||||||
|
end
|
||||||
|
end
|
25
spec/models/nobrainer/nobrainer_relationships.rb
Normal file
25
spec/models/nobrainer/nobrainer_relationships.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
class Parent
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
has_many :childs
|
||||||
|
|
||||||
|
aasm column: :status do
|
||||||
|
state :unknown_scope
|
||||||
|
state :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Child
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
belongs_to :parent
|
||||||
|
|
||||||
|
aasm column: :status do
|
||||||
|
state :unknown_scope
|
||||||
|
state :new
|
||||||
|
end
|
||||||
|
end
|
39
spec/models/nobrainer/silent_persistor_no_brainer.rb
Normal file
39
spec/models/nobrainer/silent_persistor_no_brainer.rb
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
class SilentPersistorNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :name
|
||||||
|
field :status
|
||||||
|
|
||||||
|
aasm :left, column: :status, whiny_persistence: false do
|
||||||
|
state :sleeping, initial: true
|
||||||
|
state :running
|
||||||
|
event :run do
|
||||||
|
transitions to: :running, from: :sleeping
|
||||||
|
end
|
||||||
|
event :sleep do
|
||||||
|
transitions to: :sleeping, from: :running
|
||||||
|
end
|
||||||
|
end
|
||||||
|
validates_presence_of :name
|
||||||
|
end
|
||||||
|
|
||||||
|
class MultipleSilentPersistorNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :name
|
||||||
|
field :status
|
||||||
|
|
||||||
|
aasm :left, column: :status, whiny_persistence: false do
|
||||||
|
state :sleeping, initial: true
|
||||||
|
state :running
|
||||||
|
event :run do
|
||||||
|
transitions to: :running, from: :sleeping
|
||||||
|
end
|
||||||
|
event :sleep do
|
||||||
|
transitions to: :sleeping, from: :running
|
||||||
|
end
|
||||||
|
end
|
||||||
|
validates_presence_of :name
|
||||||
|
end
|
25
spec/models/nobrainer/simple_new_dsl_nobrainer.rb
Normal file
25
spec/models/nobrainer/simple_new_dsl_nobrainer.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
class SimpleNewDslNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
|
||||||
|
aasm column: :status
|
||||||
|
aasm do
|
||||||
|
state :unknown_scope, initial: true
|
||||||
|
state :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class SimpleNewDslNoBrainerMultiple
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
|
||||||
|
aasm :left, column: :status
|
||||||
|
aasm :left do
|
||||||
|
state :unknown_scope, initial: true
|
||||||
|
state :new
|
||||||
|
end
|
||||||
|
end
|
23
spec/models/nobrainer/simple_no_brainer.rb
Normal file
23
spec/models/nobrainer/simple_no_brainer.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
class SimpleNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
|
||||||
|
aasm column: :status do
|
||||||
|
state :unknown_scope, :another_unknown_scope
|
||||||
|
state :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class SimpleNoBrainerMultiple
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :status, type: String
|
||||||
|
|
||||||
|
aasm :left, column: :status do
|
||||||
|
state :unknown_scope, :another_unknown_scope
|
||||||
|
state :new
|
||||||
|
end
|
||||||
|
end
|
98
spec/models/nobrainer/validator_no_brainer.rb
Normal file
98
spec/models/nobrainer/validator_no_brainer.rb
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
class ValidatorNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :name
|
||||||
|
field :status
|
||||||
|
|
||||||
|
attr_accessor :invalid
|
||||||
|
|
||||||
|
validate do |_|
|
||||||
|
errors.add(:validator, 'invalid') if invalid
|
||||||
|
end
|
||||||
|
|
||||||
|
aasm column: :status, whiny_persistence: true do
|
||||||
|
before_all_transactions :before_all_transactions
|
||||||
|
after_all_transactions :after_all_transactions
|
||||||
|
|
||||||
|
state :sleeping, initial: true
|
||||||
|
state :running
|
||||||
|
state :failed, after_enter: :fail
|
||||||
|
|
||||||
|
event :run, after_commit: :change_name! do
|
||||||
|
transitions to: :running, from: :sleeping
|
||||||
|
end
|
||||||
|
|
||||||
|
event :sleep do
|
||||||
|
after_commit do |name|
|
||||||
|
change_name_on_sleep name
|
||||||
|
end
|
||||||
|
transitions to: :sleeping, from: :running
|
||||||
|
end
|
||||||
|
|
||||||
|
event :fail do
|
||||||
|
transitions to: :failed, from: %i[sleeping running]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
validates_presence_of :name
|
||||||
|
|
||||||
|
def change_name!
|
||||||
|
self.name = 'name changed'
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_name_on_sleep(name)
|
||||||
|
self.name = name
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
|
||||||
|
def fail
|
||||||
|
raise StandardError, 'failed on purpose'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class MultipleValidatorNoBrainer
|
||||||
|
include NoBrainer::Document
|
||||||
|
include AASM
|
||||||
|
|
||||||
|
field :name
|
||||||
|
field :status
|
||||||
|
|
||||||
|
attr_accessor :invalid
|
||||||
|
|
||||||
|
aasm :left, column: :status, whiny_persistence: true do
|
||||||
|
state :sleeping, initial: true
|
||||||
|
state :running
|
||||||
|
state :failed, after_enter: :fail
|
||||||
|
|
||||||
|
event :run, after_commit: :change_name! do
|
||||||
|
transitions to: :running, from: :sleeping
|
||||||
|
end
|
||||||
|
event :sleep do
|
||||||
|
after_commit do |name|
|
||||||
|
change_name_on_sleep name
|
||||||
|
end
|
||||||
|
transitions to: :sleeping, from: :running
|
||||||
|
end
|
||||||
|
event :fail do
|
||||||
|
transitions to: :failed, from: %i[sleeping running]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
validates_presence_of :name
|
||||||
|
|
||||||
|
def change_name!
|
||||||
|
self.name = 'name changed'
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_name_on_sleep(name)
|
||||||
|
self.name = name
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
|
||||||
|
def fail
|
||||||
|
raise StandardError, 'failed on purpose'
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,7 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
begin
|
begin
|
||||||
require 'active_record'
|
require 'active_record'
|
||||||
|
|
||||||
puts "active_record gem found, running ActiveRecord specs \e[32m#{'✔'}\e[0m"
|
puts "active_record gem found, running ActiveRecord specs \e[32m#{'✔'}\e[0m"
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
puts "active_record gem not found, not running ActiveRecord specs \e[31m#{'✖'}\e[0m"
|
puts "active_record gem not found, not running ActiveRecord specs \e[31m#{'✖'}\e[0m"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
begin
|
begin
|
||||||
require 'dynamoid'
|
require 'dynamoid'
|
||||||
require 'aws-sdk-resources'
|
require 'aws-sdk-resources'
|
||||||
|
@ -7,14 +8,15 @@ begin
|
||||||
ENV['ACCESS_KEY'] ||= 'abcd'
|
ENV['ACCESS_KEY'] ||= 'abcd'
|
||||||
ENV['SECRET_KEY'] ||= '1234'
|
ENV['SECRET_KEY'] ||= '1234'
|
||||||
|
|
||||||
Aws.config.update({
|
Aws.config.update(
|
||||||
region: 'us-west-2',
|
region: 'us-west-2',
|
||||||
credentials: Aws::Credentials.new(ENV['ACCESS_KEY'], ENV['SECRET_KEY'])
|
credentials: Aws::Credentials.new(ENV['ACCESS_KEY'], ENV['SECRET_KEY'])
|
||||||
})
|
)
|
||||||
|
|
||||||
Dynamoid.configure do |config|
|
Dynamoid.configure do |config|
|
||||||
config.namespace = "dynamoid_tests"
|
config.namespace = 'dynamoid_tests'
|
||||||
config.endpoint = 'http://127.0.0.1:30180'
|
config.endpoint = "http://#{ENV['DYNAMODB_HOST'] || '127.0.0.1'}:" \
|
||||||
|
"#{ENV['DYNAMODB_PORT'] || 30180}"
|
||||||
config.warn_on_scan = false
|
config.warn_on_scan = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,26 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
begin
|
begin
|
||||||
require 'mongoid'
|
require 'mongoid'
|
||||||
puts "mongoid gem found, running mongoid specs \e[32m#{'✔'}\e[0m"
|
puts "mongoid gem found, running mongoid specs \e[32m#{'✔'}\e[0m"
|
||||||
|
|
||||||
|
if Mongoid::VERSION.to_f <= 5
|
||||||
|
Mongoid::Config.sessions = {
|
||||||
|
default: {
|
||||||
|
database: "mongoid_#{Process.pid}",
|
||||||
|
hosts: ["#{ENV['MONGODB_HOST'] || 'localhost'}:" \
|
||||||
|
"#{ENV['MONGODB_PORT'] || 27017}"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Mongoid::Config.send(:clients=, {
|
||||||
|
default: {
|
||||||
|
database: "mongoid_#{Process.pid}",
|
||||||
|
hosts: ["#{ENV['MONGODB_HOST'] || 'localhost'}:" \
|
||||||
|
"#{ENV['MONGODB_PORT'] || 27017}"]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
puts "mongoid gem not found, not running mongoid specs \e[31m#{'✖'}\e[0m"
|
puts "mongoid gem not found, not running mongoid specs \e[31m#{'✖'}\e[0m"
|
||||||
end
|
end
|
||||||
|
|
15
spec/spec_helpers/nobrainer.rb
Normal file
15
spec/spec_helpers/nobrainer.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
begin
|
||||||
|
require 'nobrainer'
|
||||||
|
|
||||||
|
NoBrainer.configure do |config|
|
||||||
|
config.app_name = :aasm
|
||||||
|
config.environment = :test
|
||||||
|
config.warn_on_active_record = false
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "nobrainer #{Gem.loaded_specs['nobrainer'].version} gem found, running nobrainer specs \e[32m#{'✔'}\e[0m"
|
||||||
|
rescue LoadError
|
||||||
|
puts "nobrainer gem not found, not running nobrainer specs \e[31m#{'✖'}\e[0m"
|
||||||
|
end
|
|
@ -1,9 +1,12 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
begin
|
begin
|
||||||
require 'redis-objects'
|
require 'redis-objects'
|
||||||
|
require 'redis/objects/version'
|
||||||
puts "redis-objects gem found, running Redis specs \e[32m#{'✔'}\e[0m"
|
puts "redis-objects gem found, running Redis specs \e[32m#{'✔'}\e[0m"
|
||||||
|
|
||||||
Redis.current = Redis.new(host: '127.0.0.1', port: 6379)
|
Redis.current = Redis.new(host: (ENV['REDIS_HOST'] || '127.0.0.1'),
|
||||||
|
port: (ENV['REDIS_PORT'] || 6379))
|
||||||
|
|
||||||
RSpec.configure do |c|
|
RSpec.configure do |c|
|
||||||
c.before(:each) do
|
c.before(:each) do
|
||||||
|
|
|
@ -10,10 +10,6 @@ if defined?(Mongoid::Document)
|
||||||
before(:all) do
|
before(:all) do
|
||||||
# if you want to see the statements while running the spec enable the following line
|
# if you want to see the statements while running the spec enable the following line
|
||||||
# Mongoid.logger = Logger.new(STDERR)
|
# Mongoid.logger = Logger.new(STDERR)
|
||||||
|
|
||||||
Mongoid.configure do |config|
|
|
||||||
config.connect_to "mongoid_#{Process.pid}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
|
|
|
@ -10,10 +10,6 @@ if defined?(Mongoid::Document)
|
||||||
before(:all) do
|
before(:all) do
|
||||||
# if you want to see the statements while running the spec enable the following line
|
# if you want to see the statements while running the spec enable the following line
|
||||||
# Mongoid.logger = Logger.new(STDERR)
|
# Mongoid.logger = Logger.new(STDERR)
|
||||||
|
|
||||||
Mongoid.configure do |config|
|
|
||||||
config.connect_to "mongoid_#{Process.pid}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
|
|
198
spec/unit/persistence/no_brainer_persistence_multiple_spec.rb
Normal file
198
spec/unit/persistence/no_brainer_persistence_multiple_spec.rb
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
if defined?(NoBrainer::Document)
|
||||||
|
describe 'nobrainer' do
|
||||||
|
Dir[File.dirname(__FILE__) + '/../../models/nobrainer/*.rb'].sort.each do |f|
|
||||||
|
require File.expand_path(f)
|
||||||
|
end
|
||||||
|
|
||||||
|
before(:all) do
|
||||||
|
# if you want to see the statements while running the spec enable the
|
||||||
|
# following line
|
||||||
|
# NoBrainer.configure do |config|
|
||||||
|
# config.logger = Logger.new(STDERR)
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
NoBrainer.purge!
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'named scopes with the old DSL' do
|
||||||
|
context 'Does not already respond_to? the scope name' do
|
||||||
|
it 'should add a scope for each state' do
|
||||||
|
expect(SimpleNoBrainerMultiple).to respond_to(:unknown_scope)
|
||||||
|
expect(SimpleNoBrainerMultiple).to respond_to(:another_unknown_scope)
|
||||||
|
|
||||||
|
expect(SimpleNoBrainerMultiple.unknown_scope.class).to eq(NoBrainer::Criteria)
|
||||||
|
expect(SimpleNoBrainerMultiple.another_unknown_scope.class).to eq(NoBrainer::Criteria)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Already respond_to? the scope name' do
|
||||||
|
it 'should not add a scope' do
|
||||||
|
expect(SimpleNoBrainerMultiple).to respond_to(:new)
|
||||||
|
expect(SimpleNoBrainerMultiple.new.class).to eq(SimpleNoBrainerMultiple)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'named scopes with the new DSL' do
|
||||||
|
context 'Does not already respond_to? the scope name' do
|
||||||
|
it 'should add a scope' do
|
||||||
|
expect(SimpleNewDslNoBrainerMultiple).to respond_to(:unknown_scope)
|
||||||
|
expect(SimpleNewDslNoBrainerMultiple.unknown_scope.class).to eq(NoBrainer::Criteria)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Already respond_to? the scope name' do
|
||||||
|
it 'should not add a scope' do
|
||||||
|
expect(SimpleNewDslNoBrainerMultiple).to respond_to(:new)
|
||||||
|
expect(SimpleNewDslNoBrainerMultiple.new.class).to eq(SimpleNewDslNoBrainerMultiple)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not create scopes if requested' do
|
||||||
|
expect(NoScopeNoBrainerMultiple).not_to respond_to(:ignored_scope)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'instance methods' do
|
||||||
|
let(:simple) { SimpleNewDslNoBrainerMultiple.new }
|
||||||
|
|
||||||
|
it 'should initialize the aasm state on instantiation' do
|
||||||
|
expect(SimpleNewDslNoBrainerMultiple.new.status).to eql 'unknown_scope'
|
||||||
|
expect(SimpleNewDslNoBrainerMultiple.new.aasm(:left).current_state).to eql :unknown_scope
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'transitions with persistence' do
|
||||||
|
it 'should work for valid models' do
|
||||||
|
valid_object = MultipleValidatorNoBrainer.create(name: 'name')
|
||||||
|
expect(valid_object).to be_sleeping
|
||||||
|
valid_object.status = :running
|
||||||
|
expect(valid_object).to be_running
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not store states for invalid models' do
|
||||||
|
validator = MultipleValidatorNoBrainer.create(name: 'name')
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = nil
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect { validator.run! }.to raise_error(NoBrainer::Error::DocumentInvalid)
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).not_to be_running
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = 'another name'
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator.run!).to be_truthy
|
||||||
|
expect(validator).to be_running
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).to be_running
|
||||||
|
expect(validator).not_to be_sleeping
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not store states for invalid models silently if configured' do
|
||||||
|
validator = MultipleSilentPersistorNoBrainer.create(name: 'name')
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = nil
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect(validator.run!).to be_falsey
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).not_to be_running
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = 'another name'
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator.run!).to be_truthy
|
||||||
|
expect(validator).to be_running
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).to be_running
|
||||||
|
expect(validator).not_to be_sleeping
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should store states for invalid models if configured' do
|
||||||
|
persistor = MultipleInvalidPersistorNoBrainer.create(name: 'name')
|
||||||
|
expect(persistor).to be_valid
|
||||||
|
expect(persistor).to be_sleeping
|
||||||
|
|
||||||
|
persistor.name = nil
|
||||||
|
expect(persistor).not_to be_valid
|
||||||
|
expect(persistor.run!).to be_truthy
|
||||||
|
expect(persistor).to be_running
|
||||||
|
|
||||||
|
persistor = MultipleInvalidPersistorNoBrainer.find(persistor.id)
|
||||||
|
persistor.valid?
|
||||||
|
expect(persistor).to be_valid
|
||||||
|
expect(persistor).to be_running
|
||||||
|
expect(persistor).not_to be_sleeping
|
||||||
|
|
||||||
|
persistor.reload
|
||||||
|
expect(persistor).to be_running
|
||||||
|
expect(persistor).not_to be_sleeping
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'complex example' do
|
||||||
|
it 'works' do
|
||||||
|
record = ComplexNoBrainerExample.new
|
||||||
|
expect_aasm_states record, :one, :alpha
|
||||||
|
|
||||||
|
record.save!
|
||||||
|
expect_aasm_states record, :one, :alpha
|
||||||
|
record.reload
|
||||||
|
expect_aasm_states record, :one, :alpha
|
||||||
|
|
||||||
|
record.increment!
|
||||||
|
expect_aasm_states record, :two, :alpha
|
||||||
|
record.reload
|
||||||
|
expect_aasm_states record, :two, :alpha
|
||||||
|
|
||||||
|
record.level_up!
|
||||||
|
expect_aasm_states record, :two, :beta
|
||||||
|
record.reload
|
||||||
|
expect_aasm_states record, :two, :beta
|
||||||
|
|
||||||
|
record.increment!
|
||||||
|
expect { record.increment! }.to raise_error(AASM::InvalidTransition)
|
||||||
|
expect_aasm_states record, :three, :beta
|
||||||
|
record.reload
|
||||||
|
expect_aasm_states record, :three, :beta
|
||||||
|
|
||||||
|
record.level_up!
|
||||||
|
expect_aasm_states record, :three, :gamma
|
||||||
|
record.reload
|
||||||
|
expect_aasm_states record, :three, :gamma
|
||||||
|
|
||||||
|
record.level_down # without saving
|
||||||
|
expect_aasm_states record, :three, :beta
|
||||||
|
record.reload
|
||||||
|
expect_aasm_states record, :three, :gamma
|
||||||
|
|
||||||
|
record.level_down # without saving
|
||||||
|
expect_aasm_states record, :three, :beta
|
||||||
|
record.reset!
|
||||||
|
expect_aasm_states record, :one, :beta
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_aasm_states(record, left_state, right_state)
|
||||||
|
expect(record.aasm(:left).current_state).to eql left_state.to_sym
|
||||||
|
expect(record.left).to eql left_state.to_s
|
||||||
|
expect(record.aasm(:right).current_state).to eql right_state.to_sym
|
||||||
|
expect(record.right).to eql right_state.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
158
spec/unit/persistence/no_brainer_persistence_spec.rb
Normal file
158
spec/unit/persistence/no_brainer_persistence_spec.rb
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
if defined?(NoBrainer::Document)
|
||||||
|
describe 'nobrainer' do
|
||||||
|
Dir[File.dirname(__FILE__) + '/../../models/nobrainer/*.rb'].sort.each do |f|
|
||||||
|
require File.expand_path(f)
|
||||||
|
end
|
||||||
|
|
||||||
|
before(:all) do
|
||||||
|
# if you want to see the statements while running the spec enable the
|
||||||
|
# following line
|
||||||
|
# NoBrainer.configure do |config|
|
||||||
|
# config.logger = Logger.new(STDERR)
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
NoBrainer.purge!
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'named scopes with the old DSL' do
|
||||||
|
context 'Does not already respond_to? the scope name' do
|
||||||
|
it 'should add a scope for each state' do
|
||||||
|
expect(SimpleNoBrainer).to respond_to(:unknown_scope)
|
||||||
|
expect(SimpleNoBrainer).to respond_to(:another_unknown_scope)
|
||||||
|
|
||||||
|
expect(SimpleNoBrainer.unknown_scope.class).to eq(NoBrainer::Criteria)
|
||||||
|
expect(SimpleNoBrainer.another_unknown_scope.class).to eq(NoBrainer::Criteria)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Already respond_to? the scope name' do
|
||||||
|
it 'should not add a scope' do
|
||||||
|
expect(SimpleNoBrainer).to respond_to(:new)
|
||||||
|
expect(SimpleNoBrainer.new.class).to eq(SimpleNoBrainer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'named scopes with the new DSL' do
|
||||||
|
context 'Does not already respond_to? the scope name' do
|
||||||
|
it 'should add a scope' do
|
||||||
|
expect(SimpleNewDslNoBrainer).to respond_to(:unknown_scope)
|
||||||
|
expect(SimpleNewDslNoBrainer.unknown_scope.class).to eq(NoBrainer::Criteria)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Already respond_to? the scope name' do
|
||||||
|
it 'should not add a scope' do
|
||||||
|
expect(SimpleNewDslNoBrainer).to respond_to(:new)
|
||||||
|
expect(SimpleNewDslNoBrainer.new.class).to eq(SimpleNewDslNoBrainer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not create scopes if requested' do
|
||||||
|
expect(NoScopeNoBrainer).not_to respond_to(:ignored_scope)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'instance methods' do
|
||||||
|
let(:simple) { SimpleNewDslNoBrainer.new }
|
||||||
|
|
||||||
|
it 'should initialize the aasm state on instantiation' do
|
||||||
|
expect(SimpleNewDslNoBrainer.new.status).to eql 'unknown_scope'
|
||||||
|
expect(SimpleNewDslNoBrainer.new.aasm.current_state).to eql :unknown_scope
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'relations object' do
|
||||||
|
it 'should load relations object ids' do
|
||||||
|
parent = Parent.create
|
||||||
|
child_1 = Child.create(parent_id: parent.id)
|
||||||
|
child_2 = Child.create(parent_id: parent.id)
|
||||||
|
expect(parent.childs.pluck(:id, :status).map(&:id)).to eql [child_1.id, child_2.id]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'transitions with persistence' do
|
||||||
|
it 'should work for valid models' do
|
||||||
|
valid_object = ValidatorNoBrainer.create(name: 'name')
|
||||||
|
expect(valid_object).to be_sleeping
|
||||||
|
valid_object.status = :running
|
||||||
|
expect(valid_object).to be_running
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not store states for invalid models' do
|
||||||
|
validator = ValidatorNoBrainer.create(name: 'name')
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = nil
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect { validator.run! }.to raise_error(NoBrainer::Error::DocumentInvalid)
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).not_to be_running
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = 'another name'
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator.run!).to be_truthy
|
||||||
|
expect(validator).to be_running
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).to be_running
|
||||||
|
expect(validator).not_to be_sleeping
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not store states for invalid models silently if configured' do
|
||||||
|
validator = SilentPersistorNoBrainer.create(name: 'name')
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = nil
|
||||||
|
expect(validator).not_to be_valid
|
||||||
|
expect(validator.run!).to be_falsey
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).not_to be_running
|
||||||
|
expect(validator).to be_sleeping
|
||||||
|
|
||||||
|
validator.name = 'another name'
|
||||||
|
expect(validator).to be_valid
|
||||||
|
expect(validator.run!).to be_truthy
|
||||||
|
expect(validator).to be_running
|
||||||
|
|
||||||
|
validator.reload
|
||||||
|
expect(validator).to be_running
|
||||||
|
expect(validator).not_to be_sleeping
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should store states for invalid models if configured' do
|
||||||
|
persistor = InvalidPersistorNoBrainer.create(name: 'name')
|
||||||
|
expect(persistor).to be_valid
|
||||||
|
expect(persistor).to be_sleeping
|
||||||
|
|
||||||
|
persistor.name = nil
|
||||||
|
|
||||||
|
expect(persistor).not_to be_valid
|
||||||
|
expect(persistor.run!).to be_truthy
|
||||||
|
expect(persistor).to be_running
|
||||||
|
|
||||||
|
persistor = InvalidPersistorNoBrainer.find(persistor.id)
|
||||||
|
|
||||||
|
persistor.valid?
|
||||||
|
expect(persistor).to be_valid
|
||||||
|
expect(persistor).to be_running
|
||||||
|
expect(persistor).not_to be_sleeping
|
||||||
|
|
||||||
|
persistor.reload
|
||||||
|
expect(persistor).to be_running
|
||||||
|
expect(persistor).not_to be_sleeping
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -34,8 +34,8 @@ begin
|
||||||
})
|
})
|
||||||
|
|
||||||
Dynamoid.configure do |config|
|
Dynamoid.configure do |config|
|
||||||
config.namespace = "dynamoid_tests"
|
config.namespace = 'dynamoid_tests'
|
||||||
config.endpoint = 'http://127.0.0.1:30180'
|
config.endpoint = "http://#{ENV['DYNAMODB_HOST'] || '127.0.0.1'}:30180"
|
||||||
config.warn_on_scan = false
|
config.warn_on_scan = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue