structural 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ea9e0a40c502402274176c463486b3ad8f40dbbd
4
+ data.tar.gz: da085f4a8a31ccbd7a031f198accfdcf7aa20351
5
+ SHA512:
6
+ metadata.gz: 15710f21370fcfb50d32b7f90b756534a41ab215c021083876d6ed8fb0698ba879a42cfd47549c0500091389efa4fd2850a956863a6f88db121ce52a205af40b
7
+ data.tar.gz: 2b386c4d70892fe5f6b699c32e9752c18a1b23b5ec2caaf6ed156cae29cc346269d0e309691982c9596715be1c4a4d2d26620b0e877401cb23bd51ea77645157
@@ -0,0 +1,25 @@
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
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ tags
24
+ coverage
25
+ .rspec
@@ -0,0 +1 @@
1
+ ree-1.8.7-2012.02
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - ree
@@ -0,0 +1,13 @@
1
+ ## Contributing
2
+
3
+ We love to get pull requests, here's how we like to work:
4
+
5
+ - Open a pull request. Before you start coding, let's make sure we're on the same page.
6
+ - Fork the repo.
7
+ - Run the tests. We only take pull requests with passing tests: `bundle && rake`
8
+ - Add a test for your change. Only refactoring and documentation changes require no new tests.
9
+ - Make the test pass, following the conventions you see used in the source already.
10
+ - If you have made a number of commits, squash them before pushing with.
11
+ - Push to your fork and update your pull request.
12
+ - We may suggest some changes or improvements or alternatives.
13
+
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ if RUBY_VERSION == '1.8.7'
4
+ gem 'money', '<= 4.0.2'
5
+ gem 'json'
6
+ gem 'activesupport', '<= 2.3.5'
7
+ gem 'redcarpet', '2.3.0'
8
+ end
9
+
10
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 On The Beach Ltd
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.
@@ -0,0 +1,55 @@
1
+ # Structural
2
+
3
+ `Structural` is a cut down fork of `Id`, designed to work with `Ruby >= 1.8.7` and
4
+ `Rails >= 2.3`.
5
+
6
+ #### Defining a model
7
+
8
+ class MyModel
9
+ include Structural::Model
10
+
11
+ field :foo
12
+ field :bar, default: 42
13
+ field :baz, key: 'barry'
14
+ end
15
+
16
+ my_model = MyModel.new(foo: 7, barry: 'hello')
17
+ my_model.foo # => 7
18
+ my_model.bar # => 42
19
+ my_model.baz # => 'hello'
20
+
21
+ Default values can be specified, as well as key aliases.
22
+
23
+ #### Associations
24
+
25
+ We can also specify `has_one` or `has_many` associations for nested documents:
26
+
27
+ class Zoo
28
+ include Structural::Model
29
+
30
+ has_many :lions
31
+ has_many :zebras
32
+ has_one :zookeeper, type: Person
33
+ end
34
+
35
+ zoo = Zoo.new(lions: [{name: 'Hetty'}],
36
+ zebras: [{name: 'Lisa'}],
37
+ zookeeper: {name: 'Russell'})
38
+
39
+ zoo.lions.first.class # => Lion
40
+ zoo.lions.first.name # => "Hetty"
41
+ zoo.zookeeper.class # => Person
42
+ zoo.zookeeper.name # => "Russell"
43
+
44
+ Types are inferred from the association name unless one is specified.
45
+
46
+ #### Designed for immutability
47
+
48
+ `structural` models provide accessor methods, but no mutator methods.
49
+ When changing the value of a field, a new copy of the object is created:
50
+
51
+ person = Person.new(name: 'Russell', job: 'programmer')
52
+ person.set(name: 'Radek')
53
+ # => returns a new Person whose name is Radek and whose job is 'programmer'
54
+ person.hat.set(colour: 'red')
55
+ # => returns a new person object with a new hat object with its colour set to red
@@ -0,0 +1,29 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ # encoding: utf-8
4
+
5
+ require 'rubygems'
6
+ require 'bundler'
7
+ begin
8
+ Bundler.setup(:default, :development)
9
+ rescue Bundler::BundlerError => e
10
+ $stderr.puts e.message
11
+ $stderr.puts "Run `bundle install` to install missing gems"
12
+ exit e.status_code
13
+ end
14
+ require 'rake'
15
+
16
+ require 'rspec/core'
17
+ require 'rspec/core/rake_task'
18
+ RSpec::Core::RakeTask.new(:spec) do |spec|
19
+ spec.pattern = FileList['spec/**/*_spec.rb']
20
+ end
21
+
22
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
23
+ ENV['COVERAGE'] = 'coverage'
24
+ end
25
+
26
+ task :default => :spec
27
+
28
+ require 'yard'
29
+ YARD::Rake::YardocTask.new
@@ -0,0 +1,15 @@
1
+ require 'active_support/all'
2
+ require 'money'
3
+
4
+ require 'structural/version'
5
+ require 'structural/missing_attribute_error'
6
+ require 'structural/hashifier'
7
+ require 'structural/model/definer'
8
+ require 'structural/model/descriptor'
9
+ require 'structural/model/type_casts'
10
+ require 'structural/model/field'
11
+ require 'structural/model/association'
12
+ require 'structural/model/has_one'
13
+ require 'structural/model/has_many'
14
+ require 'structural/model'
15
+ require 'structural/timestamps'
@@ -0,0 +1,27 @@
1
+ module Structural
2
+ class Hashifier
3
+ def self.hashify(data)
4
+ new(data).hashify
5
+ end
6
+
7
+ def initialize(data)
8
+ @data = data
9
+ end
10
+
11
+ def hashify
12
+ Hash[data.map { |k, v| [ k.to_s, as_data(v) ] }]
13
+ end
14
+
15
+ private
16
+
17
+ def as_data(v)
18
+ case v
19
+ when Structural::Model then v.data
20
+ when Array then v.first.is_a?(Structural::Model) ? v.map(&:data) : v
21
+ when Hash then Hashifier.hashify(v)
22
+ else v end
23
+ end
24
+
25
+ attr_reader :data
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ module Structural
2
+ class MissingAttributeError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,36 @@
1
+ module Structural
2
+ module Model
3
+ attr_reader :data
4
+
5
+ def initialize(data = {})
6
+ @data = Hashifier.hashify(data)
7
+ end
8
+
9
+ def set(values)
10
+ self.class.new(data.merge(Hashifier.hashify(values)))
11
+ end
12
+
13
+ def unset(*keys)
14
+ self.class.new(data.except(*keys.map(&:to_s)))
15
+ end
16
+
17
+ def eql? other
18
+ other.is_a?(Structural::Model) && other.data.eql?(self.data)
19
+ end
20
+ alias_method :==, :eql?
21
+
22
+ def hash
23
+ data.hash
24
+ end
25
+
26
+ private
27
+
28
+ def self.included(base)
29
+ base.extend(Descriptor)
30
+ end
31
+
32
+ def memoize(f, &b)
33
+ instance_variable_get("@#{f}") || instance_variable_set("@#{f}", b.call(data))
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,47 @@
1
+ module Structural
2
+ module Model
3
+ class Association < Field
4
+ def type
5
+ options.fetch(:type) { inferred_class }
6
+ end
7
+
8
+ def inferred_class
9
+ hierarchy.parent.const_get(inferred_class_name)
10
+ end
11
+
12
+ def inferred_class_name
13
+ @inferred_class_name ||= name.to_s.classify
14
+ end
15
+
16
+ def hierarchy
17
+ @hierarchy ||= Hierarchy.new(model.name, inferred_class_name)
18
+ end
19
+
20
+ class Hierarchy
21
+ def initialize(path, child)
22
+ @path = path
23
+ @child = child
24
+ end
25
+
26
+ def parent
27
+ @parent ||= constants.find do |c|
28
+ c.ancestors.find { |anc| anc.const_defined? child }
29
+ end
30
+ end
31
+
32
+ def constants
33
+ hierarchy.map(&:constantize)
34
+ end
35
+
36
+ private
37
+
38
+ def hierarchy(name=path)
39
+ name.match(/(.*)::.*$/)
40
+ $1 ? [name] + hierarchy($1) : [name]
41
+ end
42
+
43
+ attr_reader :path, :child
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,21 @@
1
+ module Structural
2
+ module Model
3
+ class Definer
4
+ def self.method_memoize(context, name, &value_block)
5
+ method(context, name) do |object|
6
+ object.instance_eval do
7
+ memoize(name, &value_block)
8
+ end
9
+ end
10
+ end
11
+
12
+ def self.method(context, name, &value_block)
13
+ context.instance_eval do
14
+ define_method name do
15
+ value_block.call(self)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Structural
2
+ module Model
3
+ module Descriptor
4
+ def field(f, options={})
5
+ Field.new(self, f, options).define
6
+ end
7
+
8
+ def has_one(f, options={})
9
+ HasOne.new(self, f, options).define
10
+ end
11
+
12
+ def has_many(f, options={})
13
+ HasMany.new(self, f, options).define
14
+ end
15
+
16
+ def to_proc
17
+ lambda { |data| new data }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,57 @@
1
+ module Structural
2
+ module Model
3
+ class Field
4
+ def initialize(model, name, options)
5
+ @model = model
6
+ @name = name
7
+ @options = options
8
+ end
9
+
10
+ def define
11
+ Definer.method_memoize(model, name) { |data| value_of(data) }
12
+ Definer.method(model, "#{name}?") { |obj| presence_of(obj.data) }
13
+ hook_define
14
+ end
15
+
16
+ def hook_define
17
+ end
18
+
19
+ def value_of(data)
20
+ value = data.fetch(key, &default_value)
21
+ cast(value)
22
+ end
23
+
24
+ def presence_of(data)
25
+ data.has_key?(key) && !data.fetch(key).nil?
26
+ end
27
+
28
+ def cast(value)
29
+ TypeCasts.cast(options.fetch(:type, false), value)
30
+ end
31
+
32
+ def key
33
+ options.fetch(:key, name).to_s
34
+ end
35
+
36
+ def default_value
37
+ proc do
38
+ if default?
39
+ default
40
+ else
41
+ raise MissingAttributeError, key
42
+ end
43
+ end
44
+ end
45
+
46
+ def default?
47
+ options.has_key?(:default)
48
+ end
49
+
50
+ def default
51
+ options.fetch(:default)
52
+ end
53
+
54
+ attr_reader :model, :name, :options
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,9 @@
1
+ module Structural
2
+ module Model
3
+ class HasMany < Association
4
+ def value_of(data)
5
+ data.fetch(key, []).map { |r| type.new(r) }
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Structural
2
+ module Model
3
+ class HasOne < Association
4
+ def value_of(data)
5
+ child = data.fetch(key) { raise MissingAttributeError, key }
6
+ type.new(child) unless child.nil?
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,89 @@
1
+ module Structural
2
+ module Model
3
+ module TypeCasts
4
+ def self.cast(type, value)
5
+ casts.fetch(type, Identity).new(value).cast
6
+ end
7
+
8
+ protected
9
+
10
+ def self.register(cast)
11
+ casts[cast.type] = cast
12
+ end
13
+
14
+ private
15
+
16
+ def self.casts
17
+ @casts ||= {}
18
+ end
19
+
20
+ class Cast
21
+ def initialize(value)
22
+ @value = value
23
+ end
24
+
25
+ def cast
26
+ value.is_a?(type) ? value : conversion
27
+ end
28
+
29
+ def type
30
+ self.class.type
31
+ end
32
+
33
+ def conversion
34
+ raise NotImplementedError
35
+ end
36
+
37
+ private
38
+
39
+ def self.type
40
+ raise NotImplementedError
41
+ end
42
+
43
+ attr_reader :value
44
+ end
45
+
46
+ class Identity < Cast
47
+ def cast
48
+ value
49
+ end
50
+ end
51
+
52
+ class Date < Cast
53
+ def self.type
54
+ ::Date
55
+ end
56
+
57
+ def conversion
58
+ ::Date.parse value
59
+ end
60
+
61
+ TypeCasts.register(self)
62
+ end
63
+
64
+ class Time < Cast
65
+ def self.type
66
+ ::Time
67
+ end
68
+
69
+ def conversion
70
+ ::Time.parse value
71
+ end
72
+
73
+ TypeCasts.register(self)
74
+ end
75
+
76
+ class Money < Cast
77
+ def self.type
78
+ ::Money
79
+ end
80
+
81
+ def conversion
82
+ ::Money.new value.to_i
83
+ end
84
+
85
+ TypeCasts.register(self)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,20 @@
1
+ module Structural
2
+ module Timestamps
3
+ def self.included(base)
4
+ base.field :created_at
5
+ base.field :updated_at
6
+ end
7
+
8
+ def initialize(data = {})
9
+ super data.merge(:created_at => data.fetch('created_at', Time.now))
10
+ end
11
+
12
+ def set(values)
13
+ self.class.new(super.data.merge(:updated_at => Time.now))
14
+ end
15
+
16
+ def unset(*keys)
17
+ self.class.new(super.data.merge(:updated_at => Time.now))
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Structural
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Structural::Model::Association do
4
+ module Foo
5
+ module Bar
6
+ module Baz
7
+ class Quux
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ let(:model) { double(:name => "Foo::Bar::Baz::Quux") }
14
+ let(:has_one) { Structural::Model::Association.new(model, "yak", {}) }
15
+
16
+ describe "hierarchy" do
17
+ it "builds the class and module hierarchy for the model" do
18
+ has_one.hierarchy.constants.should eq [
19
+ Foo::Bar::Baz::Quux,
20
+ Foo::Bar::Baz,
21
+ Foo::Bar,
22
+ Foo
23
+ ]
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ module Structural
4
+ module Model
5
+ module TypeCasts
6
+ describe Cast do
7
+ it 'requires a type' do
8
+ expect { Cast.new(1).type }.to raise_error NotImplementedError
9
+ end
10
+
11
+ it 'requires a conversion' do
12
+ expect { Cast.new(1).conversion }.to raise_error NotImplementedError
13
+ end
14
+
15
+ end
16
+
17
+ describe Date do
18
+ it 'casts strings to dates' do
19
+ Date.new("06-06-1983").cast.should eq ::Date.new(1983, 6, 6)
20
+ end
21
+ end
22
+
23
+ describe Time do
24
+ it 'casts strings to Times' do
25
+ Time.new("06-06-1983").cast.should eq ::Time.parse("06-06-1983")
26
+ end
27
+
28
+ it 'does nothing if the value is already of the correct type' do
29
+ time = ::Time.now
30
+ Time.new(time).cast.should eq time
31
+ end
32
+ end
33
+
34
+ describe Money do
35
+ it 'ints or strings to Money' do
36
+ Money.new("500").cast.should eq ::Money.new(5_00)
37
+ Money.new(500).cast.should eq ::Money.new(5_00)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,159 @@
1
+ require 'spec_helper'
2
+
3
+ class NestedModel
4
+ include Structural::Model
5
+ field :yak
6
+ end
7
+
8
+ class TestModel
9
+ include Structural::Model
10
+
11
+ field :foo
12
+ field :bar, :key => 'baz'
13
+ field :quux, :default => false
14
+ field :date_of_birth, :type => Date
15
+ field :empty_date, :type => Date
16
+ field :christmas, :default => Date.new(2014,12,25), :type => Date
17
+
18
+ has_one :aliased_model, :type => NestedModel
19
+ has_one :nested_model, :key => 'aliased_model'
20
+ has_one :extra_nested_model
21
+ has_one :test_model
22
+ has_many :nested_models
23
+
24
+ class ExtraNestedModel
25
+ include Structural::Model
26
+ field :cats
27
+ end
28
+ end
29
+
30
+ describe Structural::Model do
31
+ let(:model) do
32
+ TestModel.new(
33
+ :foo => 3,
34
+ :baz => 6,
35
+ :quxx => 8,
36
+ :test_model => {},
37
+ :date_of_birth => '06-06-1983',
38
+ :aliased_model => {'yak' => 11},
39
+ :nested_models => [{'yak' => 11}, {:yak => 14}],
40
+ :extra_nested_model => { :cats => "MIAOW" }
41
+ )
42
+ end
43
+
44
+
45
+ describe ".new" do
46
+ it 'converts any passed Structural models to their hash representations' do
47
+ new_model = TestModel.new(:test_model => model)
48
+ new_model.test_model.data.should eq model.data
49
+ end
50
+ end
51
+
52
+ describe ".field" do
53
+ it 'defines an accessor on the model' do
54
+ model.foo.should eq 3
55
+ end
56
+
57
+ it 'allows key aliases' do
58
+ model.bar.should eq 6
59
+ end
60
+
61
+ it 'allows default values' do
62
+ model.quux.should be_false
63
+ end
64
+
65
+ describe "typecast option" do
66
+ it 'typecasts to the provided type if a cast exists' do
67
+ model.date_of_birth.should be_a Date
68
+ model.christmas.should be_a Date
69
+ end
70
+ end
71
+ end
72
+
73
+ describe ".has_one" do
74
+ it "allows nested models" do
75
+ model.aliased_model.should be_a NestedModel
76
+ end
77
+ it "allows nested models" do
78
+ model.nested_model.should be_a NestedModel
79
+ model.nested_model.yak.should eq 11
80
+ end
81
+ it "allows associations to be nested within the class" do
82
+ model.extra_nested_model.should be_a TestModel::ExtraNestedModel
83
+ model.extra_nested_model.cats.should eq 'MIAOW'
84
+ end
85
+ it "allows recursively defined models" do
86
+ model.test_model.should be_a TestModel
87
+ end
88
+ end
89
+
90
+ describe ".has_many" do
91
+ it 'creates an array of nested models' do
92
+ model.nested_models.should be_a Array
93
+ model.nested_models.first.should be_a NestedModel
94
+ model.nested_models.first.yak.should eq 11
95
+ model.nested_models.last.yak.should eq 14
96
+ end
97
+ end
98
+
99
+ describe "#set" do
100
+ it "creates a new model with the provided values changed" do
101
+ model.set(:foo => 999).should be_a TestModel
102
+ model.set(:foo => 999).foo.should eq 999
103
+ end
104
+ end
105
+
106
+ describe "#unset" do
107
+ it 'returns a new basket minus the passed key' do
108
+ expect { model.set(:foo => 999, :bar => 555).unset(:foo, :bar).foo }.to raise_error Structural::MissingAttributeError, "foo"
109
+ end
110
+
111
+ it 'does not error if the key to be removed does not exist' do
112
+ expect { model.unset(:not_in_hash) }.to_not raise_error
113
+ end
114
+ end
115
+
116
+ describe "#fields are present methods" do
117
+ it 'allows you to check if fields are present' do
118
+ model = TestModel.new(:foo => 1)
119
+ model.foo?.should be_true
120
+ model.bar?.should be_false
121
+ end
122
+ end
123
+
124
+ describe "#==" do
125
+ it 'is equal to another Structural model with the same data' do
126
+ one = TestModel.new(:foo => 1)
127
+ two = TestModel.new(:foo => 1)
128
+ one.should eq two
129
+ end
130
+
131
+ it 'is not equal to two models with different data' do
132
+ one = TestModel.new(:foo => 1)
133
+ two = TestModel.new(:foo => 2)
134
+ one.should_not eq two
135
+ end
136
+ end
137
+
138
+ describe "#hash" do
139
+ it 'allows Structural models to be used as hash keys' do
140
+ one = TestModel.new(:foo => 1)
141
+ two = TestModel.new(:foo => 1)
142
+ hash = { one => :found }
143
+ hash[two].should eq :found
144
+ end
145
+ it 'they are different keys if the data is different' do
146
+ one = TestModel.new(:foo => 1)
147
+ two = TestModel.new(:foo => 2)
148
+ hash = { one => :found }
149
+ hash[two].should be_nil
150
+ hash[one].should eq :found
151
+ end
152
+ end
153
+
154
+ describe "#to_proc" do
155
+ it 'eta expands the model class into its constructor' do
156
+ [{},{}].map(&TestModel).all? { |m| m.is_a? TestModel }.should be_true
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ class TimeStampedModel
4
+ include Structural::Model
5
+ include Structural::Timestamps
6
+
7
+ field :foo
8
+ field :bar
9
+ end
10
+
11
+ module Structural
12
+ describe Timestamps do
13
+ let(:model) { TimeStampedModel.new(:foo => 999, :bar => 666) }
14
+
15
+ it 'should have a created_at date' do
16
+ model.created_at.should be_a Time
17
+ end
18
+
19
+ it 'should update the updated at when set is called' do
20
+ updated = model.set(:foo => 123)
21
+ expect(updated.created_at).to be < updated.updated_at
22
+ end
23
+
24
+ it 'should update the updated at when unset is called' do
25
+ updated = model.unset(:foo)
26
+ expect(updated.created_at).to be < updated.updated_at
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ require 'rspec'
2
+ require 'lib/structural'
3
+ require 'simplecov'
4
+
5
+ SimpleCov.start if ENV['COVERAGE']
6
+
7
+ I18n.enforce_available_locales = false
8
+
9
+ RSpec.configure do |config|
10
+ config.order = :rand
11
+ config.color_enabled = true
12
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'structural/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'structural'
8
+ spec.version = Structural::VERSION
9
+ spec.authors = ['Russell Dunphy', 'Radek Molenda', 'Jon Doveston']
10
+ spec.email = ['jon.doveston@onthebeach.co.uk']
11
+ spec.summary = %q{Simple models based on hashes}
12
+ spec.description = %q{A cut down fork of the Id gem developed at On The Beach Ltd.}
13
+ spec.homepage = 'https://github.com/onthebeach/structural'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
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_dependency 'money'
22
+ spec.add_dependency 'activesupport'
23
+
24
+ spec.add_development_dependency 'rspec'
25
+ spec.add_development_dependency 'simplecov'
26
+ spec.add_development_dependency 'yard'
27
+ spec.add_development_dependency 'redcarpet'
28
+ spec.add_development_dependency 'bundler', '~> 1.6'
29
+ spec.add_development_dependency 'rake'
30
+ end
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: structural
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Russell Dunphy
8
+ - Radek Molenda
9
+ - Jon Doveston
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-05-12 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: money
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: activesupport
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rspec
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: simplecov
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: yard
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: redcarpet
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ - !ruby/object:Gem::Dependency
100
+ name: bundler
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ~>
104
+ - !ruby/object:Gem::Version
105
+ version: '1.6'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ~>
111
+ - !ruby/object:Gem::Version
112
+ version: '1.6'
113
+ - !ruby/object:Gem::Dependency
114
+ name: rake
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ description: A cut down fork of the Id gem developed at On The Beach Ltd.
128
+ email:
129
+ - jon.doveston@onthebeach.co.uk
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .gitignore
135
+ - .ruby-version
136
+ - .travis.yml
137
+ - CONTRIBUTING.md
138
+ - Gemfile
139
+ - LICENSE.md
140
+ - README.md
141
+ - Rakefile
142
+ - lib/structural.rb
143
+ - lib/structural/hashifier.rb
144
+ - lib/structural/missing_attribute_error.rb
145
+ - lib/structural/model.rb
146
+ - lib/structural/model/association.rb
147
+ - lib/structural/model/definer.rb
148
+ - lib/structural/model/descriptor.rb
149
+ - lib/structural/model/field.rb
150
+ - lib/structural/model/has_many.rb
151
+ - lib/structural/model/has_one.rb
152
+ - lib/structural/model/type_casts.rb
153
+ - lib/structural/timestamps.rb
154
+ - lib/structural/version.rb
155
+ - spec/lib/structural/model/association_spec.rb
156
+ - spec/lib/structural/model/field_spec.rb
157
+ - spec/lib/structural/model/type_casts_spec.rb
158
+ - spec/lib/structural/model_spec.rb
159
+ - spec/lib/structural/timestamps_spec.rb
160
+ - spec/spec_helper.rb
161
+ - structural.gemspec
162
+ homepage: https://github.com/onthebeach/structural
163
+ licenses:
164
+ - MIT
165
+ metadata: {}
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 2.2.2
183
+ signing_key:
184
+ specification_version: 4
185
+ summary: Simple models based on hashes
186
+ test_files:
187
+ - spec/lib/structural/model/association_spec.rb
188
+ - spec/lib/structural/model/field_spec.rb
189
+ - spec/lib/structural/model/type_casts_spec.rb
190
+ - spec/lib/structural/model_spec.rb
191
+ - spec/lib/structural/timestamps_spec.rb
192
+ - spec/spec_helper.rb
193
+ has_rdoc: