lean-attributes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c6b251b6f7693a6a788b8cf3f006658fe11e256c
4
+ data.tar.gz: d117bf7bb0f11f7857516109bc0416a8ab6d639d
5
+ SHA512:
6
+ metadata.gz: cddfdcbf8ee64247a616dc021339322f7aeb19fa7156fad8934eedf8fe005b5fbcbbf31b8fc9d9b0e2582be402282553495de9d87b0173c64f7193362634e4d3
7
+ data.tar.gz: e2e7859b6340308338c77bcced6816d2d9f226912e134997e4b4bf06c5933915649aa7116f66037054abb57f4f6e89c724ba12c12bf971797c55cbb3b1263c02
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) [year] [fullname]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ # Lean::Attributes
2
+
3
+ ## Status
4
+ [![Build Status](https://travis-ci.org/lleolin/lean-attributes.svg)](https://travis-ci.org/lleolin/lean-attributes)
5
+ [![Test Coverage](https://codeclimate.com/github/lleolin/lean-attributes/badges/coverage.svg)](https://codeclimate.com/github/lleolin/lean-attributes/coverage)
6
+ [![Code Climate](https://codeclimate.com/github/lleolin/lean-attributes/badges/gpa.svg)](https://codeclimate.com/github/lleolin/lean-attributes)
7
+ [![Dependency Status](https://gemnasium.com/lleolin/lean-attributes.svg)](https://gemnasium.com/lleolin/lean-attributes)
8
+ [![Inline docs](http://inch-ci.org/github/lotus/model.svg?branch=master)](http://inch-ci.org/github/lleolin/lean-attributes)
@@ -0,0 +1 @@
1
+ require 'lean-attributes/attributes'
@@ -0,0 +1,14 @@
1
+ require 'lean-attributes/attributes/class_methods'
2
+ require 'lean-attributes/attributes/coercion'
3
+ require 'lean-attributes/attributes/initializer'
4
+
5
+ module Lean
6
+ module Attributes
7
+ def self.included(base)
8
+ base.class_eval do
9
+ extend ClassMethods
10
+ include Coercion
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,78 @@
1
+ module Lean
2
+ module Attributes
3
+ class Attribute
4
+ attr_reader :name
5
+
6
+ def initialize(options = {})
7
+ @default_value = options[:default_value]
8
+ @name = options[:name]
9
+ @parent_class = options[:parent_class]
10
+ @type = options[:type].to_s
11
+ end
12
+
13
+ def coercion_method
14
+ <<-EOS
15
+ def #{coercion_method_name(name)}(value)
16
+ #{coercion_method_name}(value)
17
+ end
18
+ EOS
19
+ end
20
+
21
+ def coercible?
22
+ return @coercible unless @coercible.nil?
23
+
24
+ @coercible = @parent_class.method_defined?(coercion_method_name)
25
+ end
26
+
27
+ def coercion_method_name(from = nil)
28
+ ['coerce', from, 'to', @type.downcase].compact.join('_')
29
+ end
30
+
31
+ def default_value
32
+ return "send(:#{@default_value})" if @default_value.is_a?(Symbol) &&
33
+ !@type.is_a?(Symbol)
34
+
35
+ @default_value.inspect
36
+ end
37
+
38
+ def getter_method
39
+ return getter_method_with_default unless @default_value.nil?
40
+
41
+ "attr_reader :#{@name}"
42
+ end
43
+
44
+ def getter_method_with_default
45
+ <<-EOS
46
+ def #{name}
47
+ @#{name} ||= #{default_value}
48
+ end
49
+ EOS
50
+ end
51
+
52
+ def name
53
+ @name.to_sym
54
+ end
55
+
56
+ def setter_method
57
+ <<-EOS
58
+ def #{name}=(value)
59
+ #{setter_method_coercion}
60
+ @#{name} = value
61
+ end
62
+ EOS
63
+ end
64
+
65
+ def setter_method_coercion
66
+ return unless coercible?
67
+
68
+ <<-EOS
69
+ value = #{coercion_method_name}(value) unless value.is_a?(#{@type})
70
+ EOS
71
+ end
72
+
73
+ # def type_coercion_method_name
74
+ # @type_coercion_method_name ||= :"coerce_to_#{@type.downcase}"
75
+ # end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,19 @@
1
+ require 'lean-attributes/attributes/attribute'
2
+
3
+ module Lean
4
+ module Attributes
5
+ module ClassMethods
6
+ def attribute(name, type, options = {})
7
+ attribute = Attribute.new(default_value: options[:default],
8
+ name: name, parent_class: self, type: type)
9
+
10
+ class_eval(attribute.coercion_method, __FILE__, __LINE__ + 1) \
11
+ if attribute.coercible?
12
+ class_eval(attribute.getter_method, __FILE__, __LINE__ + 1)
13
+ class_eval(attribute.setter_method, __FILE__, __LINE__ + 1)
14
+
15
+ attribute
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ module Lean
2
+ module Attributes
3
+ module Coercion
4
+ def coerce_to_array(value)
5
+ Array(value) unless value.nil?
6
+ end
7
+
8
+ def coerce_to_bigdecimal(value)
9
+ BigDecimal.new(value, 0) unless value.nil?
10
+ end
11
+
12
+ def coerce_to_date(value)
13
+ Date.parse(value) unless value.nil?
14
+ end
15
+
16
+ def coerce_to_datetime(value)
17
+ DateTime.parse(value) unless value.nil?
18
+ end
19
+
20
+ def coerce_to_integer(value)
21
+ value.to_i unless value.nil?
22
+ end
23
+
24
+ def coerce_to_string(value)
25
+ value.to_s unless value.nil?
26
+ end
27
+
28
+ def coerce_to_symbol(value)
29
+ value.to_sym unless value.nil?
30
+ end
31
+
32
+ def coerce_to_time(value)
33
+ Time.new(value) unless value.nil?
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ module Lean
2
+ module Attributes
3
+ module Initializer
4
+ def initialize(attributes = {})
5
+ attributes.each do |name, value|
6
+ send("#{name}=", value)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module Lean
2
+ module Attributes
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,37 @@
1
+ require 'bigdecimal'
2
+
3
+ class Medium
4
+ include Lean::Attributes
5
+
6
+ attribute :authors, Array
7
+ attribute :finished, DateTime
8
+ attribute :price, BigDecimal
9
+ attribute :published, Date
10
+ attribute :rate, Float
11
+ attribute :sold, Time
12
+ attribute :title, String
13
+ end
14
+
15
+ class Book < Medium
16
+ attribute :format, Symbol, default: :hardcover
17
+ attribute :pages, Integer
18
+ end
19
+
20
+ class Author
21
+ include Lean::Attributes
22
+ include Lean::Attributes::Initializer
23
+
24
+ attribute :age, Integer
25
+ attribute :name, String
26
+ end
27
+
28
+ class ReadingProgress
29
+ include Lean::Attributes
30
+
31
+ attribute :date, Time, default: :time_now
32
+ attribute :page, Integer, default: 1
33
+
34
+ def time_now
35
+ Time.new('2015-09-08').utc
36
+ end
37
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Lean::Attributes' do
4
+ context 'inclusive class' do
5
+ let(:book) do
6
+ Book.new.tap do |book|
7
+ book.title = :"War and Peace"
8
+ book.pages = '1'
9
+ book.authors = 'Leo Tolstoy'
10
+ book.published = '1869-01-01'
11
+ book.sold = '2015-09-08'
12
+ book.finished = '2015-09-10'
13
+ book.price = 10.00
14
+ book.format = 'paperback'
15
+ end
16
+ end
17
+
18
+ it 'has no initializer' do
19
+ expect { Book.new(title: 'War and Peace') } \
20
+ .to raise_error(ArgumentError)
21
+ end
22
+
23
+ it 'has coercible and writable attributes' do
24
+ expect(book.title).to match 'War and Peace'
25
+ expect(book.pages).to eq 1
26
+ expect(book.authors).to match_array ['Leo Tolstoy']
27
+ expect(book.published).to eq Date.parse('1869-01-01')
28
+ expect(book.sold).to eq Time.new('2015-09-08')
29
+ expect(book.price).to be_kind_of BigDecimal
30
+ expect(book.price).to eq 10.00
31
+ expect(book.format).to eq :paperback
32
+ end
33
+ end
34
+
35
+ context 'inclusive class with Initializer' do
36
+ let(:author) { Author.new(name: 'Elliott Mason', age: 30) }
37
+
38
+ it { expect(author.name).to match 'Elliott Mason' }
39
+ it { expect(author.age).to eq 30 }
40
+ end
41
+
42
+ context 'inclusive class with attribute defaults' do
43
+ let(:reading_progress) { ReadingProgress.new }
44
+
45
+ it { expect(reading_progress.page).to eq 1 }
46
+ it { expect(reading_progress.date).to be_kind_of Time }
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ require 'simplecov'
2
+ require 'codeclimate-test-reporter'
3
+
4
+ formatters = [SimpleCov::Formatter::HTMLFormatter]
5
+ formatters << CodeClimate::TestReporter::Formatter if ENV['TRAVIS']
6
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[*formatters]
7
+ SimpleCov.start do
8
+ add_filter '/.bundle'
9
+ add_filter '/spec'
10
+ end
11
+
12
+ require 'rspec'
13
+
14
+ RSpec.configure do |config|
15
+ config.before(:each) do |example|
16
+ SimpleCov.command_name(example.location)
17
+ end
18
+ end
19
+
20
+ require 'lean-attributes'
21
+ require 'fixtures.rb'
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lean-attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - R. Elliott Mason
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 10.3.2
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '10.3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 10.3.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 3.0.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '3.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 3.0.0
53
+ description: |
54
+ lean-attributes allows you to define coerced attributes for Ruby classes
55
+ email:
56
+ - r.elliott.mason@fastmail.fm
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - README.md
61
+ files:
62
+ - LICENSE
63
+ - README.md
64
+ - lib/lean-attributes.rb
65
+ - lib/lean-attributes/attributes.rb
66
+ - lib/lean-attributes/attributes/attribute.rb
67
+ - lib/lean-attributes/attributes/class_methods.rb
68
+ - lib/lean-attributes/attributes/coercion.rb
69
+ - lib/lean-attributes/attributes/initializer.rb
70
+ - lib/lean-attributes/version.rb
71
+ - spec/fixtures.rb
72
+ - spec/lean_attributes_spec.rb
73
+ - spec/spec_helper.rb
74
+ homepage: https://github.com/lleolin/lean-attributes
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 1.9.3
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.4.5
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Lean attributes for Ruby classes
98
+ test_files:
99
+ - spec/fixtures.rb
100
+ - spec/lean_attributes_spec.rb
101
+ - spec/spec_helper.rb