encore 0.0.2

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b6425ceec678f308c80da211bf16946506b2c704
4
+ data.tar.gz: 481ae8d7b56757c499fa9cebae51f6eb635052e5
5
+ SHA512:
6
+ metadata.gz: e7c056d64a6c7d8341fa8728255b1c37da9156e9f3800245911069c345a6a2250fbf91aa3a531417c4c7f7e668e08b4579448e393582f980d9e04434ae148bc0
7
+ data.tar.gz: 717a8560dee3c08e3bf6cbf3e05b5239dcd5273e16c2df82b99eb93ab36d2357f1a80a61bc155c14b7473f6302d0ddb99d2bfe87fc75dcfa682cdade62ce9fe6
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2013, Mirego
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ - Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ - Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ - Neither the name of the Mirego nor the names of its contributors may
13
+ be used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Encore
2
+
3
+ Encore is a framework built on top of ActiveRecord to manage entities.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'encore'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ $ gem install encore
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```ruby
28
+ # app/entities/user_entity.rb
29
+ class UserEntity
30
+ include Encore::Entity
31
+
32
+ expose :name
33
+ expose :email
34
+ expose :created_at, readonly: true
35
+ expose :updated_at, readonly: true
36
+ end
37
+
38
+ # app/controllers/users_controller.rb
39
+ class UsersController < ApplicationController
40
+ # POST /users
41
+ def create
42
+ @user = UserEntity.new
43
+ @user.assign_attributes(params[:user], context: :create)
44
+
45
+ if @user.save
46
+ render json: @user, status: 201
47
+ else
48
+ render json: { errors: @user.errors }, status: 422
49
+ end
50
+ end
51
+
52
+ # PUT /users/:id
53
+ def update
54
+ @user = UserEntity.new User.find(params[:id])
55
+ @user.assign_attributes(params[:user], context: :update)
56
+
57
+ if @user.save
58
+ render json: @user
59
+ else
60
+ render json: { errors: @user.errors }, status: 422
61
+ end
62
+ end
63
+
64
+ # PATCH /users/:id
65
+ def partial_update
66
+ @user = UserEntity.find User.find(params[:id])
67
+ @user.assign_attributes(params[:user], context: :partial_update)
68
+
69
+ if @user.save
70
+ render json: @user
71
+ else
72
+ render json: { errors: @user.errors }, status: 422
73
+ end
74
+ end
75
+ end
76
+ ```
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ require 'rake'
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ task default: :spec
7
+
8
+ desc 'Run all specs'
9
+ RSpec::Core::RakeTask.new(:spec) do |task|
10
+ task.pattern = 'spec/**/*_spec.rb'
11
+ end
data/encore.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'encore/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'encore'
8
+ spec.version = Encore::VERSION
9
+ spec.authors = ['Rémi Prévost']
10
+ spec.email = ['rprevost@mirego.com']
11
+ spec.description = 'Encore is a framework built on top of ActiveRecord to manage entities.'
12
+ spec.summary = spec.description
13
+ spec.homepage = 'https://github.com/remiprev/encore'
14
+ spec.license = "BSD 3-Clause"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec'
24
+ spec.add_development_dependency 'sqlite3'
25
+
26
+ spec.add_dependency 'activerecord', '>= 3.0.0'
27
+ spec.add_dependency 'activesupport', '>= 3.0.0'
28
+ end
@@ -0,0 +1,39 @@
1
+ module Encore
2
+ class Attribute
3
+ attr_reader :attribute, :klass
4
+
5
+ def initialize(klass, attribute, opts = {})
6
+ @klass = klass
7
+ @attribute = attribute
8
+ @opts = opts
9
+ end
10
+
11
+ def self.map_attributes(klass, params)
12
+ params.inject({}) do |memo, (attribute, value)|
13
+ memo.merge Attribute.new(klass, attribute.to_sym) => value
14
+ end
15
+ end
16
+
17
+ def ==(other_attribute)
18
+ hash == other_attribute.hash
19
+ end
20
+
21
+ def eql?(other)
22
+ self == other
23
+ end
24
+
25
+ # Generate a hash for comparisons
26
+ def hash
27
+ [@attribute, @klass].hash
28
+ end
29
+
30
+ # Return whether the attribute is read-only
31
+ def readonly?
32
+ !!@opts[:readonly]
33
+ end
34
+
35
+ def to_s
36
+ "#<Encore::Attribute #{@klass}@#{@attribute}>"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ module Encore
2
+ module Entity
3
+ module Input
4
+ class ProtectedAttributeError < StandardError
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,37 @@
1
+ module Encore
2
+ module Entity
3
+ module Input
4
+ module ExposedAttributes
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ # Declare a new exposed attribute
9
+ def expose(attribute, opts = {})
10
+ @exposed_attributes ||= []
11
+ @exposed_attributes << Encore::Attribute.new(self, attribute.to_sym, opts)
12
+ end
13
+
14
+ # Return only the attribute keys for each exposed attribute
15
+ def exposed_attributes_list
16
+ @exposed_attributes.map(&:attribute)
17
+ end
18
+
19
+ # Return whether an attribute is exposed by the entity
20
+ def exposed_attribute?(attribute)
21
+ @exposed_attributes.detect { |a| attribute == a }
22
+ end
23
+
24
+ # Return whether an attribute is exposed by the entity
25
+ def modifiable_attribute?(attribute)
26
+ modifiable_attributes.include?(attribute)
27
+ end
28
+
29
+ # Return a list of all attributes that can be modified
30
+ def modifiable_attributes
31
+ @exposed_attributes.reject(&:readonly?)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,54 @@
1
+ require 'encore/entity/input/errors'
2
+ require 'encore/entity/input/exposed_attributes'
3
+
4
+ module Encore
5
+ module Entity
6
+ module Input
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ include Encore::Entity::Input::ExposedAttributes
11
+
12
+ # Expose ID as a readonly attribute
13
+ expose :id, readonly: true
14
+ end
15
+
16
+ # Assign specific attribute to the object
17
+ def assign_attributes(attributes = {}, opts = nil)
18
+ # Find the right context
19
+ unless context = opts.try(:delete, :context)
20
+ context = @object.persisted? ? :create : :partial_update
21
+ end
22
+
23
+ # Convert attribute keys to Attribute objects
24
+ attributes = Encore::Attribute.map_attributes(self.class, attributes)
25
+
26
+ # Loop through every passed attribute and set it
27
+ assign_provided_attributes(attributes, context)
28
+
29
+ # If we're doing an update, for any exposed attribute that wasn't passed, set it to nil
30
+ reset_forgotten_attributes(attributes, context)
31
+ end
32
+
33
+ protected
34
+
35
+ def assign_provided_attributes(attributes, context)
36
+ attributes.each_pair do |attribute, value|
37
+ if self.class.modifiable_attribute?(attribute)
38
+ send :"#{attribute.attribute}=", value
39
+ else
40
+ raise Encore::Entity::Input::ProtectedAttributeError.new("The #{attribute} attribute is not exposed.")
41
+ end
42
+ end
43
+ end
44
+
45
+ def reset_forgotten_attributes(attributes, context)
46
+ if context == :update
47
+ (self.class.modifiable_attributes - attributes.keys).each do |attribute|
48
+ send :"#{attribute.attribute}=", nil
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ module Encore
2
+ module Entity
3
+ module Output
4
+ extend ActiveSupport::Concern
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ require 'encore/entity/input'
2
+ require 'encore/entity/output'
3
+
4
+ module Encore
5
+ module Entity
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include Input
10
+ include Output
11
+
12
+ # Make `object` accessible for others
13
+ attr_accessor :object
14
+ end
15
+
16
+ # Initialize a new entity, linked to an ActiveRecord object
17
+ # If no object is passed, let's try to build a new one
18
+ def initialize(object = nil)
19
+ @object = object || self.class.linked_class.new
20
+ end
21
+
22
+ # Delegate everything to the object
23
+ def method_missing(method, *args, &blk)
24
+ @object.send(method, *args, &blk)
25
+ end
26
+
27
+ module ClassMethods
28
+ # Return the object class. If no object is present, try to
29
+ # guess the class with our own class name (`UserEntity` would be `User`)
30
+ def linked_class
31
+ @object ? @object.class : self.name.split(/Entity$/).first.constantize
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Encore
2
+ VERSION = '0.0.2'
3
+ end
data/lib/encore.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'encore/version'
2
+
3
+ # ActiveSupport
4
+ require 'active_support'
5
+
6
+ # ActiveRecord
7
+ require 'active_record'
8
+
9
+ # Encore
10
+ require 'encore/entity'
11
+ require 'encore/attribute'
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe Encore::Entity do
4
+ before do
5
+ spawn_model :User
6
+
7
+ spawn_entity :UserEntity do
8
+ expose :name
9
+ expose :email
10
+ expose :created_at, readonly: true
11
+ expose :updated_at, readonly: true
12
+ end
13
+
14
+ run_migration do
15
+ create_table(:users, force: true) do |t|
16
+ t.string :email
17
+ t.string :name
18
+ t.timestamps
19
+ end
20
+ end
21
+ end
22
+
23
+ describe :InstanceMethods do
24
+ describe :assign_attributes do
25
+ let(:assign_attributes!) { entity.assign_attributes attributes, context: context }
26
+
27
+ context 'with :create context' do
28
+ let(:entity) { UserEntity.new }
29
+ let(:attributes) { { email: 'remi@example.com' } }
30
+ let(:context) { :create }
31
+
32
+ before { assign_attributes! }
33
+
34
+ it { expect(entity.object.email).to eql 'remi@example.com' }
35
+ it { expect(entity.object.name).to be_blank }
36
+ it { expect(entity.object.created_at).to be_blank }
37
+ it { expect(entity.object.updated_at).to be_blank }
38
+ end
39
+
40
+ context 'with :update context', focus: true do
41
+ let(:entity) { UserEntity.new(User.first) }
42
+ let(:context) { :update }
43
+ let(:create_user!) { User.create(email: 'remi@example.com', name: 'Rémi Prévost') }
44
+
45
+ before { create_user! }
46
+
47
+ context 'when updating valid attributes' do
48
+ let(:attributes) { { email: 'remi+test@example.com' } }
49
+ before { assign_attributes! }
50
+
51
+ it { expect(entity.object.email).to eql 'remi+test@example.com' }
52
+ it { expect(entity.object.name).to be_blank }
53
+ it { expect(entity.object.created_at).to_not be_blank }
54
+ it { expect(entity.object.updated_at).to_not be_blank }
55
+ end
56
+
57
+ context 'when updating a protected attribute' do
58
+ let(:attributes) { { email: 'remi+test@example.com', created_at: '2013-08-29 21:22:44' } }
59
+
60
+ it { expect { assign_attributes! }.to raise_error(Encore::Entity::Input::ProtectedAttributeError) }
61
+ end
62
+ end
63
+
64
+ context 'with :partial_update context' do
65
+ let(:entity) { UserEntity.new(User.first) }
66
+ let(:attributes) { { email: 'remi+test@example.com' } }
67
+ let(:context) { :partial_update }
68
+ let(:create_user!) { User.create(email: 'remi@example.com', name: 'Rémi Prévost') }
69
+
70
+ before do
71
+ create_user!
72
+ assign_attributes!
73
+ end
74
+
75
+ it { expect(entity.object.email).to eql 'remi+test@example.com' }
76
+ it { expect(entity.object.name).to eql 'Rémi Prévost' }
77
+ it { expect(entity.object.created_at).to_not be_blank }
78
+ it { expect(entity.object.updated_at).to_not be_blank }
79
+ end
80
+
81
+ context 'with overriden setter method' do
82
+ before do
83
+ class UserEntity
84
+ def name=(name)
85
+ object.name = name.upcase
86
+ end
87
+ end
88
+ end
89
+
90
+ let(:entity) { UserEntity.new(User.first) }
91
+ let(:attributes) { { name: 'Art Vandelay' } }
92
+ let(:context) { :partial_update }
93
+ let(:create_user!) { User.create }
94
+
95
+ before do
96
+ create_user!
97
+ assign_attributes!
98
+ end
99
+
100
+ it { expect(entity.object.name).to eql 'ART VANDELAY' }
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift File.expand_path('../lib', __FILE__)
2
+
3
+ require 'rspec'
4
+ require 'sqlite3'
5
+
6
+ require 'encore'
7
+
8
+ # Require our macros and extensions
9
+ Dir[File.expand_path('../../spec/support/macros/*.rb', __FILE__)].map(&method(:require))
10
+
11
+ RSpec.configure do |config|
12
+ # Include our macros
13
+ config.include DatabaseMacros
14
+ config.include ModelMacros
15
+
16
+ config.before(:each) do
17
+ # Create the SQLite database
18
+ setup_database
19
+ end
20
+
21
+ config.after(:each) do
22
+ # Make sure we remove our test database file
23
+ cleanup_database
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ module DatabaseMacros
2
+ # Run migrations in the test database
3
+ def run_migration(&block)
4
+ # Create a new migration class
5
+ klass = Class.new(ActiveRecord::Migration)
6
+
7
+ # Create a new `up` that executes the argument
8
+ klass.send(:define_method, :up) { self.instance_exec(&block) }
9
+
10
+ # Create a new instance of it and execute its `up` method
11
+ klass.new.up
12
+ end
13
+
14
+ def self.database_file
15
+ @database_file || File.expand_path('../test.db', __FILE__)
16
+ end
17
+
18
+ def setup_database
19
+ # Make sure the test database file is gone
20
+ cleanup_database
21
+
22
+ # Establish the connection
23
+ SQLite3::Database.new FileUtils.touch(DatabaseMacros.database_file).first
24
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: DatabaseMacros.database_file)
25
+
26
+ # Silence everything
27
+ ActiveRecord::Base.logger = ActiveRecord::Migration.verbose = false
28
+ end
29
+
30
+ def cleanup_database
31
+ FileUtils.rm(DatabaseMacros.database_file) if File.exists?(DatabaseMacros.database_file)
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ module ModelMacros
2
+ # Create a new Encore entity
3
+ def spawn_entity(klass_name, &block)
4
+ spawn_klass klass_name, Object do
5
+ include Encore::Entity
6
+ instance_exec(&block) if block
7
+ end
8
+ end
9
+
10
+ # Create a new ActiveRecord model
11
+ def spawn_model(klass_name, &block)
12
+ spawn_klass klass_name, ActiveRecord::Base do
13
+ instance_exec(&block) if block
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ # Create a new class
20
+ def spawn_klass(klass_name, parent_klass, &block)
21
+ Object.instance_eval { remove_const klass_name } if Object.const_defined?(klass_name)
22
+ Object.const_set(klass_name, Class.new(parent_klass))
23
+ Object.const_get(klass_name).class_eval(&block) if block_given?
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: encore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Rémi Prévost
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
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: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
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: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activerecord
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: 3.0.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: 3.0.0
97
+ description: Encore is a framework built on top of ActiveRecord to manage entities.
98
+ email:
99
+ - rprevost@mirego.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - Gemfile
107
+ - LICENSE.md
108
+ - README.md
109
+ - Rakefile
110
+ - encore.gemspec
111
+ - lib/encore.rb
112
+ - lib/encore/attribute.rb
113
+ - lib/encore/entity.rb
114
+ - lib/encore/entity/input.rb
115
+ - lib/encore/entity/input/errors.rb
116
+ - lib/encore/entity/input/exposed_attributes.rb
117
+ - lib/encore/entity/output.rb
118
+ - lib/encore/version.rb
119
+ - spec/poutine/entity_spec.rb
120
+ - spec/spec_helper.rb
121
+ - spec/support/macros/database_macros.rb
122
+ - spec/support/macros/model_macros.rb
123
+ homepage: https://github.com/remiprev/encore
124
+ licenses:
125
+ - BSD 3-Clause
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.0.2
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Encore is a framework built on top of ActiveRecord to manage entities.
147
+ test_files:
148
+ - spec/poutine/entity_spec.rb
149
+ - spec/spec_helper.rb
150
+ - spec/support/macros/database_macros.rb
151
+ - spec/support/macros/model_macros.rb