perimeter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7ef4dd2cb1aa452485b1643f29cd3ed48d5b059a
4
+ data.tar.gz: e6956c254e3832098d8fe242b3c74c3f9b0e6b47
5
+ SHA512:
6
+ metadata.gz: 70a3f7b3a24b0b710cbc7b7ddbe22ccc07e6d82746a8e33fdd1d6957332e54f385bae794cef063d0b62eeec1bbad17c5ce9c4c751c77b4c4a0cf9a6e406a1538
7
+ data.tar.gz: 670ea4272c6daf5f5eaf06eb61874dbe794c9c773e0a83e6c83e58b3607a3d01ad0975ed7aa1ece0cdf56b762858d147a88a9123ce0df213d9b7480fe87bee67
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ *.DS_Store
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ tags
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,31 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :bundler do
5
+ watch('Gemfile')
6
+ # Uncomment next line if your Gemfile contains the `gemspec' command.
7
+ # watch(/^.+\.gemspec/)
8
+ end
9
+
10
+ guard :rspec, cmd: 'rspec --fail-fast' do
11
+ watch(%r{^spec/.+_spec\.rb$})
12
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
+ watch('spec/spec_helper.rb') { "spec" }
14
+
15
+ # Rails example
16
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
17
+ watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
18
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
19
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
20
+ watch('config/routes.rb') { "spec/routing" }
21
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
22
+
23
+ # Capybara features specs
24
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
25
+
26
+ # Turnip features and steps
27
+ watch(%r{^spec/acceptance/(.+)\.feature$})
28
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
29
+ end
30
+
31
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Bukowskis
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Perimeter
2
+
3
+ > **[perimeter](https://en.wikipedia.org/wiki/Perimeter) |pəˈrɪmɪtə| noun** - the continuous line forming the boundary of a closed geometrical figure, alt. the outermost parts or boundary of an area or object: *the perimeter of the garden*.
4
+
5
+ As developers we are used to draw strict lines in our code, such as with MVC and ORM. There is much buzz about the repository pattern and this gem is an attempt to introduce an implementation convention for it across our applications.
6
+
7
+ Consider this file structure:
8
+
9
+ ```bash
10
+ models
11
+ |- product.rb # Entity
12
+ |- products.rb # Repository
13
+ \- products
14
+ |- backend.rb # Persistence Backend
15
+ \- calculator.rb # (Here you can put any other related class)
16
+ ```
17
+
18
+ ## Entity
19
+
20
+ This is where your business logic lives. Here you have [Virtus](https://github.com/solnic/virtus) and [ActiveModel Validations](http://api.rubyonrails.org/classes/ActiveModel/Validations.html) at your fingertips.
21
+
22
+ ```ruby
23
+ class Product
24
+ attriute, :name
25
+
26
+ validate :name, presence: true
27
+ end
28
+ ```
29
+
30
+ ## Repository
31
+
32
+ This is where you run CRUD operations for your Entities. The repository is the only one who may interact with your persistence backend.
33
+
34
+ ```ruby
35
+ module Products
36
+ def self.find(id)
37
+ # ...
38
+ end
39
+
40
+ def self.destroy(id)
41
+ # ...
42
+ end
43
+ end
44
+ ```
45
+
46
+ Every method of the repository always returns an [Operation](http://rubygems.org/gems/operation) instance. You can, however, use the bang version (e.g. '#find!') so that the operation will raise an Exception if it was not successful. Again, what is a "successful" operation is defined [here](https://github.com/bukowskis/perimeter/blob/master/lib/perimeter/repository/adapters/abstract.rb) and not neccessarily that which you know from ActiveRecord. A few methods are *inspired* by the ActiveRecord API, such as find, destroy,... (see them [here](https://github.com/bukowskis/perimeter/blob/master/lib/perimeter/repository/adapters/abstract.rb)). But not more than that, because the repository is supposed to facilitate different kinds of backends (SQL, ElasticSearch,...).
47
+
48
+ The returned Operation instances usually hold metadata, such as Entities, or [Leaflet](http://rubygems.org/gems/leaflet) Collections of Entties. They never expose Backend instances, however.
49
+
50
+ By default, perimeter looks for the persistence backend class in [REPOSITORY]::Backend, e.g. `Products::Backend`. If you change the location, you can specify it manually. Likewise, the Entity is derived from the singular name of the repository by default and can be overriden.
51
+
52
+ ```ruby
53
+ module Products
54
+ entity_class MyPersonalEntity
55
+ backend_class SomeWhereElse::MyCustomBackend
56
+ end
57
+ ```
58
+
59
+ Because it is so common, there is an [ActiveRecord adapter](https://github.com/bukowskis/perimeter/tree/master/lib/perimeter/repository/adapters) included which you can kickstart your repository with:
60
+
61
+ ```ruby
62
+ require 'perimeter/repository/adapters/active_record'
63
+
64
+ module UserTags
65
+ include Perimeter::Repository::Adapters::ActiveRecord
66
+ end
67
+ ```
68
+
69
+ ## Backend
70
+
71
+ The persistence backend is tucked away in a directory and may look like the following code. You are not supposed to interact with the backend at all in your code.
72
+
73
+ ```ruby
74
+ module Products
75
+ class Backend < ActiveRecord::Base
76
+ end
77
+ end
78
+ ```
79
+
80
+ Again there is an adapter which does some initial configuration for you, such as specifying the custom table name of the class. Note that you need to specify the backend classes of associations manually:
81
+
82
+ ```ruby
83
+ require 'perimeter/backend/adapters/active_record'
84
+
85
+ module Products
86
+ class Backend < ActiveRecord::Base
87
+
88
+ include Perimeter::Backend::Adapters::ActiveRecord
89
+
90
+ has_many :tags, dependent: :destroy, class_name: '::Tags::Backend', foreign_key: 'tag_id'
91
+ end
92
+ end
93
+ ```
94
+
95
+ # License
96
+
97
+ See `MIT-LICENSE` for details.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,8 @@
1
+ module Perimeter
2
+ module Backend
3
+ module Adapters
4
+ module Abstract
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,38 @@
1
+ # ActiveModel is not defined as gem dependency but we still depend on it (for now).
2
+ # With this technique we can use Perimeter in Rails 2 applications by backporting activemodel manually into the vendor directory.
3
+ require 'active_model'
4
+
5
+ require 'active_support/core_ext/module'
6
+ require 'active_support/concern'
7
+ require 'virtus'
8
+
9
+ module Perimeter
10
+ module Entity
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ include Virtus.model
15
+
16
+ extend ActiveModel::Naming
17
+ include ActiveModel::Conversion
18
+ include ActiveModel::Validations
19
+ include ActiveModel::Validations::Callbacks
20
+
21
+ attribute :id
22
+ end
23
+
24
+ def to_param
25
+ return if id.blank?
26
+ id.to_s
27
+ end
28
+
29
+ def persisted? # Rails 3+
30
+ id.present?
31
+ end
32
+
33
+ def new_record? # Rails 2
34
+ !persisted?
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,73 @@
1
+ require 'active_support/concern'
2
+ require 'trouble'
3
+ require 'perimeter/repository/error'
4
+
5
+ module Perimeter
6
+ module Repository
7
+ module Adapters
8
+ module Abstract
9
+ extend ActiveSupport::Concern
10
+
11
+ module ClassMethods
12
+
13
+ # Returns an Operation instance that MUST hold an Entity as object.
14
+ # Success is defined as "the record could be found", everything else is a failure.
15
+ # If the record does not exist, there is *no* Trouble. Any other StandardError notifies Trouble.
16
+ #
17
+ def find(id)
18
+ raise NotImplementedError
19
+ end
20
+
21
+ # Returns an Operation instance that MUST hold an Entity as object.
22
+ # Success is defined as "there was no record and now there is one", everything else is a failure.
23
+ # Validations are run on the Record.
24
+ #
25
+ def create(attributes)
26
+ raise NotImplementedError
27
+ end
28
+
29
+ # Returns an Operation instance that MAY hold an Entity as object.
30
+ # Success is defined as "there was a record and now some/all attributes have been updated", everything else is a failure.
31
+ # NOTE: Whether validations are run on the Record first is backend specific.
32
+ #
33
+ def update(id, attributes)
34
+ raise NotImplementedError
35
+ end
36
+
37
+ # Returns an Operation instance that SHOULD hold the destroyed Entity as object.
38
+ # Success is defined as "after this operation the record is or already was gone", everything else is a failure.
39
+ #
40
+ def destroy(id)
41
+ raise NotImplementedError
42
+ end
43
+
44
+ # Returns an Entity or raises a FindingError.
45
+ #
46
+ def find!(id)
47
+ operation = find id
48
+ raise ::Perimeter::Repository::FindingError, operation.meta.exception if operation.failure?
49
+ operation.object
50
+ end
51
+
52
+ # Returns an Entity or raises a CreationError.
53
+ #
54
+ def create!(id)
55
+ operation = create id
56
+ raise ::Perimeter::Repository::CreationError, operation.meta.exception if operation.failure?
57
+ operation.object
58
+ end
59
+
60
+ # Returns true or raises a DestructionError.
61
+ #
62
+ def destory!(id)
63
+ operation = destroy id
64
+ raise ::Perimeter::Repository::DestructionError, operation.meta.exception if operation.failure?
65
+ true
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,11 @@
1
+ module Perimeter
2
+ module Repository
3
+
4
+ Error = Class.new StandardError
5
+
6
+ FindingError = Class.new ::Perimeter::Repository::Error
7
+ CreationError = Class.new ::Perimeter::Repository::Error
8
+ DestructionError = Class.new ::Perimeter::Repository::Error
9
+
10
+ end
11
+ end
@@ -0,0 +1,117 @@
1
+ require 'hooks'
2
+ require 'active_support/concern'
3
+ require 'active_support/core_ext'
4
+
5
+ module Perimeter
6
+ module Repository
7
+ extend ActiveSupport::Concern
8
+
9
+ OperationError = Class.new StandardError
10
+
11
+ included do
12
+ include ::Hooks
13
+ define_hook :after_conversion
14
+ end
15
+
16
+ module ClassMethods
17
+
18
+ # ––––––––––––––––––––––
19
+ # Class name definitions
20
+ # ––––––––––––––––––––––
21
+
22
+ def backend_class(*args)
23
+ @backend_class = args.first unless args.empty?
24
+ @backend_class || default_backend_class
25
+ end
26
+
27
+ def entity_class(*args)
28
+ @entity_class = args.first unless args.empty?
29
+ @entity_class || default_entity_class
30
+ end
31
+
32
+ # Convenience Wrapper
33
+ def backend
34
+ backend_class
35
+ end
36
+
37
+ private
38
+
39
+ # –––––––––––––––––––
40
+ # Default Class names
41
+ # –––––––––––––––––––
42
+
43
+ def default_backend_class
44
+ backend_class_name = name + '::Backend'
45
+ backend_class_name.constantize
46
+
47
+ rescue NameError => exception
48
+ if exception.message.to_s == "uninitialized constant #{backend_class_name}"
49
+ raise NameError, %{Repository "#{name}" expects the Backend "#{backend_class_name}" to be defined.}
50
+ else
51
+ raise exception
52
+ end
53
+ end
54
+
55
+ def default_entity_class
56
+ entity_class_name = name.singularize
57
+ entity_class_name.constantize
58
+
59
+ rescue NameError => exception
60
+ if exception.message.to_s == "uninitialized constant #{entity_class_name}"
61
+ raise NameError, %{Repository "#{name}" expects the Entity "#{entity_class_name}" to be defined.}
62
+ else
63
+ raise exception
64
+ end
65
+ end
66
+
67
+ # ––––––––––
68
+ # Conversion
69
+ # ––––––––––
70
+
71
+ def attributes_to_record(attributes, options = {})
72
+ options.symbolize_keys!
73
+ if id = options[:add_id]
74
+ attributes[:id] = id
75
+ end
76
+ entity = entity_class.new attributes
77
+ entity_to_record entity
78
+ end
79
+
80
+ def entity_to_record(entity, options = {})
81
+ options.symbolize_keys!
82
+ attributes = entity.attributes
83
+ if options[:strip_id]
84
+ attributes.delete :id
85
+ attributes.delete 'id'
86
+ end
87
+ backend.new attributes
88
+ end
89
+
90
+ def records_to_entities(records)
91
+ return [] if records.blank?
92
+ Array(records).map { |record| record_to_entity(record) }
93
+ end
94
+
95
+ def record_to_entity(record)
96
+ return if record.blank?
97
+
98
+ begin
99
+ entity = entity_class.new record.attributes
100
+ rescue ArgumentError => exception
101
+ if exception.message.to_s == 'wrong number of arguments(1 for 0)'
102
+ raise ArgumentError, %{The Class "#{entity_class}" appears not to be an Entity, because the initializer does not accept one argument. Did you "include Perimeter::Entity"?}
103
+ else
104
+ raise exception
105
+ end
106
+ end
107
+
108
+ record.errors.each { |attribute, message| entity.errors.add attribute, message }
109
+
110
+ entity.id = record.id
111
+ entity
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,3 @@
1
+ module Perimeter
2
+ VERSION = '0.0.1'
3
+ end
data/lib/perimeter.rb ADDED
@@ -0,0 +1,8 @@
1
+
2
+ #require 'leaflet'
3
+ #require 'hashie/mash'
4
+
5
+
6
+
7
+ #require 'perimeter/repository'
8
+ #require 'perimeter/entity'
data/perimeter.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'perimeter/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'perimeter'
7
+ spec.version = Perimeter::VERSION
8
+ spec.authors = %w{ perimeter }
9
+ spec.description = %q{Repository/Entity pattern conventions.}
10
+ spec.summary = %q{Repository/Entity pattern conventions.}
11
+ spec.homepage = 'https://github.com/bukowskis/perimeter'
12
+ spec.license = 'MIT'
13
+
14
+ spec.files = `git ls-files`.split($/) - ['.travis.yml']
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = %w{ lib }
18
+
19
+ spec.add_dependency 'virtus'
20
+ spec.add_dependency 'activesupport'
21
+ spec.add_dependency 'hooks'
22
+ spec.add_dependency 'operation'
23
+ spec.add_dependency 'trouble'
24
+ #spec.add_dependency 'activemodel' # Not compatible with Rails 2, backport it if neccessary
25
+
26
+ spec.add_development_dependency 'activemodel'
27
+ spec.add_development_dependency 'activerecord'
28
+ spec.add_development_dependency 'sqlite3'
29
+
30
+ spec.add_development_dependency 'rspec'
31
+ spec.add_development_dependency 'guard-rspec'
32
+ spec.add_development_dependency 'guard-bundler'
33
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ require 'cities'
4
+ require 'admin/countries'
5
+ require 'admin/cars'
6
+
7
+ describe Perimeter::Repository do
8
+
9
+ describe '.backend_class' do
10
+ context 'in the root namespace' do
11
+ it 'follows the Backend convention' do
12
+ expect( Cities.backend_class ).to be Cities::Backend
13
+ end
14
+ end
15
+
16
+ context 'in a custom namespace' do
17
+ it 'follows the Backend convention' do
18
+ expect( Admin::Countries.backend_class ).to be Admin::Countries::Backend
19
+ end
20
+ end
21
+
22
+ context 'with custom backend class definitions' do
23
+ it 'finds the right classe' do
24
+ expect( Admin::Cars.backend_class ).to be Admin::Vehicles::Backend
25
+ end
26
+ end
27
+ end
28
+
29
+ describe '.backend' do
30
+ it 'is a (read-only) shortcut to #backend_class' do
31
+ Cities.stub(:backend_class).and_return 'backend_class says hello'
32
+ expect( Cities.backend ).to eq 'backend_class says hello'
33
+ end
34
+
35
+ it 'refuses to take arguments' do
36
+ expect { Cities.backend 'something custom' }.to raise_error(ArgumentError)
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path('../support/models', __FILE__)
2
+
3
+ require 'perimeter'
@@ -0,0 +1,6 @@
1
+ module Admin
2
+ class Auto
3
+ include Perimeter::Entity
4
+
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+ require 'admin/vehicles/backend'
2
+ require 'admin/auto'
3
+
4
+ module Admin
5
+ module Cars
6
+ include Perimeter::Repository
7
+
8
+ backend_class Vehicles::Backend
9
+ entity_class Auto
10
+
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module Admin
2
+ module Countries
3
+ class Backend
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ require 'admin/countries/backend'
2
+
3
+ module Admin
4
+ module Countries
5
+ include Perimeter::Repository
6
+
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module Admin
2
+ class Country
3
+ include Perimeter::Entity
4
+
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module Admin
2
+ module Vehicles
3
+ class Backend
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Cities
2
+ class Backend
3
+ include Virtus.model
4
+
5
+ attribute :name, String
6
+
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'city'
2
+ require 'perimeter/repository'
3
+ require 'cities/backend'
4
+
5
+ module Cities
6
+ include Perimeter::Repository
7
+
8
+ end
@@ -0,0 +1,7 @@
1
+ require 'perimeter/entity'
2
+
3
+ class City
4
+ include Perimeter::Entity
5
+
6
+ attribute :name, String
7
+ end
metadata ADDED
@@ -0,0 +1,234 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: perimeter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - perimeter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: virtus
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
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: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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: hooks
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: operation
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
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: trouble
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activemodel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activerecord
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: sqlite3
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: guard-bundler
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description: Repository/Entity pattern conventions.
168
+ email:
169
+ executables: []
170
+ extensions: []
171
+ extra_rdoc_files: []
172
+ files:
173
+ - ".gitignore"
174
+ - ".rspec"
175
+ - Gemfile
176
+ - Guardfile
177
+ - LICENSE.txt
178
+ - README.md
179
+ - Rakefile
180
+ - lib/perimeter.rb
181
+ - lib/perimeter/backend/adapters/abstract.rb
182
+ - lib/perimeter/entity.rb
183
+ - lib/perimeter/repository.rb
184
+ - lib/perimeter/repository/adapters/abstract.rb
185
+ - lib/perimeter/repository/error.rb
186
+ - lib/perimeter/version.rb
187
+ - perimeter.gemspec
188
+ - spec/lib/perimeter/repository_spec.rb
189
+ - spec/spec_helper.rb
190
+ - spec/support/models/admin/auto.rb
191
+ - spec/support/models/admin/cars.rb
192
+ - spec/support/models/admin/countries.rb
193
+ - spec/support/models/admin/countries/backend.rb
194
+ - spec/support/models/admin/country.rb
195
+ - spec/support/models/admin/vehicles/backend.rb
196
+ - spec/support/models/cities.rb
197
+ - spec/support/models/cities/backend.rb
198
+ - spec/support/models/city.rb
199
+ homepage: https://github.com/bukowskis/perimeter
200
+ licenses:
201
+ - MIT
202
+ metadata: {}
203
+ post_install_message:
204
+ rdoc_options: []
205
+ require_paths:
206
+ - lib
207
+ required_ruby_version: !ruby/object:Gem::Requirement
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ version: '0'
212
+ required_rubygems_version: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ requirements: []
218
+ rubyforge_project:
219
+ rubygems_version: 2.2.2
220
+ signing_key:
221
+ specification_version: 4
222
+ summary: Repository/Entity pattern conventions.
223
+ test_files:
224
+ - spec/lib/perimeter/repository_spec.rb
225
+ - spec/spec_helper.rb
226
+ - spec/support/models/admin/auto.rb
227
+ - spec/support/models/admin/cars.rb
228
+ - spec/support/models/admin/countries.rb
229
+ - spec/support/models/admin/countries/backend.rb
230
+ - spec/support/models/admin/country.rb
231
+ - spec/support/models/admin/vehicles/backend.rb
232
+ - spec/support/models/cities.rb
233
+ - spec/support/models/cities/backend.rb
234
+ - spec/support/models/city.rb