memory_record 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: 0a0d02478e038db4812bab5276b78fea07776ab4
4
+ data.tar.gz: 98d8b5e8afc8d4953dc71e240112ea96deb13bcc
5
+ SHA512:
6
+ metadata.gz: 57018d07d34f7087d497ed1e31df045590b3ba664607a2990c65ac5aa1cf0e6f3af45c72790a0dc576da73dc1412b66f6ed9de2773e0c0de41485b3371f6a4a5
7
+ data.tar.gz: 37dc4b8c4ff4a17d5a70e1681993b42d65186a7b3cfdd4b04b1de74dd3e8fd31a26013a275a4226422130ae3a857b22a3c9246cd57f55de6ea9b4ac1c22092d3
data/.gitignore ADDED
@@ -0,0 +1,18 @@
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
+ /*.html
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 akicho8
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.org ADDED
@@ -0,0 +1,123 @@
1
+ * A small number of records Easy handling library
2
+
3
+ #+BEGIN_SRC ruby
4
+ class Direction
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: :left, name: "←", vector: [-1, 0]},
8
+ {key: :right, name: "→", vector: [ 1, 0]},
9
+ ], attr_reader_auto: true
10
+
11
+ def long_name
12
+ "#{key}:#{name}"
13
+ end
14
+ end
15
+
16
+ Direction.collect(&:name) # => ["←", "→"]
17
+ Direction.keys # => [:left, :right]
18
+
19
+ Direction[:right].key # => :right
20
+ Direction[:right].code # => 1
21
+ Direction[:right].vector # => [1, 0]
22
+ Direction[:right].long_name # => "right:→"
23
+
24
+ Direction[1].key # => :right
25
+
26
+ Direction[:up] # => nil
27
+ Direction.fetch(:up) rescue $! # => #<KeyError: Direction.fetch(:up) does not match anything。
28
+ #+END_SRC
29
+
30
+ *** How to decide =code= yourself?
31
+
32
+ #+BEGIN_SRC ruby
33
+ class Foo
34
+ include MemoryRecord
35
+ memory_record [
36
+ {code: 1, key: :a, name: "A"},
37
+ {code: 2, key: :b, name: "B"},
38
+ {code: 3, key: :c, name: "C"},
39
+ ], attr_reader: :name
40
+ end
41
+
42
+ Foo.collect(&:code) # => [1, 2, 3]
43
+ #+END_SRC
44
+
45
+ It is used only when refactoring legacy code, when compatibility is required.
46
+
47
+ *** How to turn as an array?
48
+
49
+ =Enumerable= extended, so that =each= method is available
50
+
51
+ #+BEGIN_SRC ruby
52
+ Foo.each {|v| ... }
53
+ Foo.collect {|v| ... }
54
+ #+END_SRC
55
+
56
+ *** How do I submit a form to select in Rails?
57
+
58
+ #+BEGIN_SRC ruby
59
+ form.collection_select(:selection_code, Foo, :code, :name)
60
+ #+END_SRC
61
+
62
+ *** Is the reference in subscripts slow?
63
+
64
+ Since it has a hash internally using the key value as a key, it can be acquired with O (1).
65
+
66
+ #+BEGIN_SRC ruby
67
+ Foo[1].name # => "A"
68
+ Foo[:a].name # => "A"
69
+ #+END_SRC
70
+
71
+ *** Instances always react to =code= and =key=
72
+
73
+ #+BEGIN_SRC ruby
74
+ object = Foo.first
75
+ object.key # => :a
76
+ object.code # => 1
77
+ #+END_SRC
78
+
79
+ *** =attr_reader= option
80
+
81
+ The attribute value can be referenced with =@attributes[:xxx]=, but it is troublesome to refer frequently, so it is methodized with =attr_reader: xxx=.
82
+
83
+ *** =attr_reader_auto= option
84
+
85
+ Automatically all attributes =attr_reader=
86
+
87
+ *** What if I do not want you to feel free to access the attributes of a record?
88
+
89
+ =attr_reader= with no method definition and reference =object.attributes[:xxx]=
90
+
91
+ *** How do I add a method to an instance?
92
+
93
+ For that, I am creating a new class so I need to define it normally
94
+
95
+ *** =name= method is special?
96
+
97
+ If =name= is not defined, it defines a =name= method that returns a translation of =key=
98
+
99
+ *** =to_s= method is defined?
100
+
101
+ = Alias of =name=, =to_s= is defined.
102
+
103
+ *** If there is no key, use fetch to get an error
104
+
105
+ #+BEGIN_SRC ruby
106
+ Foo.fetch(:xxx) # => <KeyError: ...>
107
+ #+END_SRC
108
+
109
+ The following are all the same
110
+
111
+ #+BEGIN_SRC ruby
112
+ Foo[:xxx] || :default # => :default
113
+ Foo.fetch(:xxx, :default} # => :default
114
+ Foo.fetch(:xxx) { :default } # => :default
115
+ #+END_SRC
116
+
117
+ *** Use fetch_if to ignore if the key is nil
118
+
119
+ #+BEGIN_SRC ruby
120
+ Foo.fetch_if(nil) # => nil
121
+ Foo.fetch_if(:a) # => #<Foo:... @attributes={...}>
122
+ Foo.fetch_if(:xxx) # => <KeyError: ...>
123
+ #+END_SRC
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ task :default => :spec
@@ -0,0 +1,16 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: :male, name: 'otoko'},
8
+ {key: :female, name: 'onna'},
9
+ ], attr_reader: :name
10
+ end
11
+
12
+ Foo[:male] # => #<Foo:0x007ff459a494a8 @attributes={:key=>:male, :name=>"otoko", :code=>0}>
13
+ Foo[:female] # => #<Foo:0x007ff459a49390 @attributes={:key=>:female, :name=>"onna", :code=>1}>
14
+
15
+ Foo[:male].name # => "otoko"
16
+ Foo[:female].name # => "onna"
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ model = Class.new do
5
+ include MemoryRecord
6
+ memory_record [
7
+ {a: 1},
8
+ {b: 2},
9
+ ], attr_reader_auto: true
10
+ end
11
+
12
+ model.first.name # => nil
13
+ model.first.a # => 1
14
+ model.first.b # => nil
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [
7
+ {code: 1, key: :a, name: 'A'},
8
+ {code: 2, key: :b, name: 'B'},
9
+ {code: 3, key: :c, name: 'C'},
10
+ ], :attr_reader => :name
11
+ end
12
+
13
+ Foo[2].name # => 'B'
14
+ Foo[:b].name # => 'B'
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class C
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: [:a, :b]},
8
+ ]
9
+ end
10
+
11
+ C.keys # => [:a_b]
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class C
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: :a, x: 1},
8
+ ]
9
+ end
10
+
11
+ C[:a][:x] # => 1
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Direction
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: :left, name: '←', vector: [-1, 0]},
8
+ {key: :right, name: '→', vector: [ 1, 0]},
9
+ ], attr_reader_auto: true
10
+
11
+ def long_name
12
+ '#{name}方向'
13
+ end
14
+ end
15
+
16
+ Direction.collect(&:name) # => ['←', '→']
17
+ Direction.keys # => [:left, :right]
18
+
19
+ Direction[:right].key # => :right
20
+ Direction[:right].code # => 1
21
+ Direction[:right].vector # => [1, 0]
22
+ Direction[:right].long_name # => '→方向'
23
+
24
+ Direction[1].key # => :right
25
+
26
+ Direction[:up] # => nil
27
+ Direction.fetch(:up) rescue $! # => #<KeyError: Direction.fetch(:up) does not match anything
@@ -0,0 +1,21 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class C
5
+ include MemoryRecord
6
+ memory_record [{key: :a}], attr_reader: :name
7
+ end
8
+
9
+ C.keys # => [:a]
10
+
11
+ # memory_record では更新できない
12
+ class C
13
+ memory_record [{key: :b}], attr_reader: :name
14
+ end
15
+
16
+ C.keys # => [:a]
17
+
18
+ # memory_record_list_set を使うこと
19
+ C.memory_record_list_set [{key: :c}]
20
+
21
+ C.keys # => [:c]
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: '↑', name: '上'},
8
+ ], attr_reader: :name
9
+ end
10
+
11
+ Foo['↑'].name # => '上'
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: 'true', name: '有効'},
8
+ {key: 'false', name: '無効'},
9
+ ], attr_reader: :name
10
+ end
11
+
12
+ flag = true
13
+
14
+ Foo[flag.to_s].name # => '有効'
@@ -0,0 +1,24 @@
1
+ # freeze してしまうとこれらのメモ化ができなくなる
2
+
3
+ $LOAD_PATH.unshift '../lib'
4
+ require 'memory_record'
5
+
6
+ class C
7
+ def self.x
8
+ @x ||= 'OK'
9
+ end
10
+ end
11
+
12
+ class C2
13
+ include MemoryRecord
14
+ memory_record [
15
+ {model: C},
16
+ ], attr_reader_auto: true
17
+
18
+ def x
19
+ @x ||= 'OK'
20
+ end
21
+ end
22
+
23
+ C2.first.x # => "OK"
24
+ C2.first.model.x # => "OK"
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [
7
+ {a: 10},
8
+ ], attr_reader: :a
9
+
10
+ def a
11
+ super * 2
12
+ end
13
+
14
+ def name
15
+ "(#{super})"
16
+ end
17
+ end
18
+
19
+ Foo.first.a # => 20
20
+ Foo.first.name # => "(Key0)"
@@ -0,0 +1,23 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [
7
+ {name: 'alice'},
8
+ {name: 'bob'},
9
+ ], attr_reader_auto: true
10
+ end
11
+
12
+ require 'active_model'
13
+
14
+ class Foo
15
+ include ActiveModel::Validations
16
+ validates :name, length: { maximum: 3 }
17
+ end
18
+
19
+ Foo.collect(&:valid?) # => [false, true]
20
+
21
+ foo = Foo.first
22
+ foo.valid? # => false
23
+ foo.errors.full_messages # => ['Name is too long (maximum is 3 characters)']
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [{key: :a}, {key: :a},] rescue $! # => #<ArgumentError: Foo#key の :a が重複しています
7
+ end
8
+
9
+ class Bar
10
+ include MemoryRecord
11
+ memory_record [{code: 0}, {code: 0},] rescue $! # => #<ArgumentError: Bar#code の 0 が重複しています
12
+ end
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ class Foo
5
+ include MemoryRecord
6
+ memory_record [
7
+ {key: '01', name: '→'},
8
+ {key: '02', name: '←'},
9
+ ], attr_reader: :name
10
+ end
11
+
12
+ Foo['01'] # => #<Foo:0x007fac2c35db28 @attributes={:key=>:'01', :name=>'→', :code=>0}>
13
+ Foo['02'] # => #<Foo:0x007fac2c35d9e8 @attributes={:key=>:'02', :name=>'←', :code=>1}>
14
+
15
+ # このようにもできるがまったくオススメできない
16
+ # マジックナンバーを増やすメリットはない
17
+ # なんのためにキーがあるのか考えよう
@@ -0,0 +1,33 @@
1
+ $LOAD_PATH.unshift '../lib'
2
+ require 'memory_record'
3
+
4
+ require 'active_record'
5
+
6
+ ActiveRecord::VERSION::STRING # => "5.1.3"
7
+ ActiveRecord::Migration.verbose = false
8
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
9
+
10
+ ActiveRecord::Schema.define do
11
+ create_table :users do |t|
12
+ t.integer :gender_key
13
+ end
14
+ end
15
+
16
+ class GenderInfo
17
+ include MemoryRecord
18
+ memory_record [
19
+ {key: :male, name: 'otoko'},
20
+ {key: :female, name: 'onna'},
21
+ ], attr_reader: :name
22
+ end
23
+
24
+ class User < ActiveRecord::Base
25
+ enum gender_key: GenderInfo.keys
26
+
27
+ def gender_info
28
+ GenderInfo[gender_key]
29
+ end
30
+ end
31
+
32
+ user = User.create!(gender_key: :male)
33
+ user.gender_info.name # => "otoko"
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+ require 'active_support/concern'
3
+ require 'active_support/core_ext/module/concerning'
4
+ require 'active_support/core_ext/class/attribute'
5
+ require 'active_support/core_ext/array/wrap'
6
+ require 'active_model'
7
+
8
+ module MemoryRecord
9
+ extend ActiveSupport::Concern
10
+
11
+ class_methods do
12
+ def memory_record(list, **options, &block)
13
+ return if memory_record_defined?
14
+
15
+ extend ActiveModel::Translation
16
+ extend Enumerable
17
+ include ::MemoryRecord::SingletonMethods
18
+
19
+ class_attribute :memory_record_configuration
20
+ self.memory_record_configuration = {
21
+ attr_reader: [],
22
+ }.merge(options)
23
+
24
+ if block_given?
25
+ yield memory_record_configuration
26
+ end
27
+
28
+ if memory_record_configuration[:attr_reader_auto]
29
+ _attr_reader = list.inject([]) { |a, e| a | e.keys.collect(&:to_sym) }
30
+ else
31
+ _attr_reader = memory_record_configuration[:attr_reader]
32
+ end
33
+
34
+ include Module.new.tap { |m|
35
+ ([:key, :code] + Array.wrap(_attr_reader)).uniq.each do |key|
36
+ m.class_eval do
37
+ define_method(key) { @attributes[key.to_sym] }
38
+ end
39
+ end
40
+
41
+ unless m.method_defined?(:name)
42
+ m.class_eval do
43
+ define_method(:name) do
44
+ if self.class.name
45
+ self.class.human_attribute_name(key)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ }
51
+
52
+ memory_record_list_set(list)
53
+ end
54
+
55
+ def memory_record_defined?
56
+ ancestors.include?(SingletonMethods)
57
+ end
58
+ end
59
+
60
+ concern :SingletonMethods do
61
+ class_methods do
62
+ def memory_record?
63
+ memory_record_defined?
64
+ end
65
+
66
+ def lookup(key)
67
+ return key if key.kind_of? self
68
+ case key
69
+ when Symbol, String
70
+ @values_hash[:key][key.to_sym]
71
+ else
72
+ @values_hash[:code][key]
73
+ end
74
+ end
75
+ alias [] lookup
76
+
77
+ def fetch(key, default = nil, &block)
78
+ raise ArgumentError if block_given? && default
79
+ v = lookup(key)
80
+ unless v
81
+ case
82
+ when block_given?
83
+ v = yield
84
+ when default
85
+ v = default
86
+ else
87
+ raise KeyError, [
88
+ "#{name}.fetch(#{key.inspect}) does not match anything",
89
+ "keys: #{keys.inspect}",
90
+ "codes: #{codes.inspect}",
91
+ ].join("\n")
92
+ end
93
+ end
94
+ v
95
+ end
96
+
97
+ def fetch_if(key, default = nil, &block)
98
+ if key
99
+ fetch(key, default, &block)
100
+ end
101
+ end
102
+
103
+ delegate :each, to: :values
104
+
105
+ def keys
106
+ @keys ||= @values_hash[:key].keys
107
+ end
108
+
109
+ def codes
110
+ @codes ||= @values_hash[:code].keys
111
+ end
112
+
113
+ attr_reader :values
114
+
115
+ def memory_record_list_set(list)
116
+ @keys = nil
117
+ @codes = nil
118
+ @values = list.collect.with_index {|e, i| new(_attributes_normalize(e, i)) }.freeze
119
+ @values_hash = {}
120
+ [:code, :key].each do |pk|
121
+ @values_hash[pk] = @values.inject({}) do |a, e|
122
+ a.merge(e.send(pk) => e) do |key, a, b|
123
+ raise ArgumentError, [
124
+ "#{name}##{pk} #{key.inspect} is duplicate",
125
+ "Existing: #{a.attributes.inspect}",
126
+ "Collision: #{b.attributes.inspect}",
127
+ ].join("\n")
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ private
134
+
135
+ def _attributes_normalize(attrs, index)
136
+ key = attrs[:key] || "_key#{index}"
137
+ if key.kind_of? Array
138
+ key = key.join('_')
139
+ end
140
+ attrs.merge(code: attrs[:code] || index, key: key.to_sym)
141
+ end
142
+ end
143
+
144
+ attr_reader :attributes
145
+
146
+ delegate :[], to: :attributes
147
+ delegate :to_s, to: :name
148
+
149
+ def initialize(attributes)
150
+ @attributes = attributes
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,3 @@
1
+ module MemoryRecord
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'memory_record/version'
2
+ require 'memory_record/memory_record'
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'memory_record/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'memory_record'
7
+ spec.version = MemoryRecord::VERSION
8
+ spec.authors = ['akicho8']
9
+ spec.email = ['akicho8@gmail.com']
10
+ spec.description = %q{A small number of records Easy handling library}
11
+ spec.summary = %q{A small number of records Easy handling library}
12
+ spec.homepage = ''
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'rake'
21
+ spec.add_development_dependency 'rspec'
22
+ spec.add_development_dependency 'test-unit'
23
+
24
+ spec.add_dependency 'activesupport'
25
+ spec.add_dependency 'activemodel'
26
+ end
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ class Model
4
+ include MemoryRecord
5
+ memory_record [
6
+ {name: 'A'},
7
+ {name: 'B'},
8
+ ], attr_reader: :name
9
+ end
10
+
11
+ class Legacy
12
+ include MemoryRecord
13
+ memory_record [
14
+ {code: 10, key: :a, name: 'A'},
15
+ {code: 20, key: :b, name: 'B'},
16
+ ], attr_reader: :name
17
+ end
18
+
19
+ RSpec.describe MemoryRecord do
20
+ def __define(table)
21
+ Class.new {
22
+ include MemoryRecord
23
+ memory_record table, attr_reader_auto: true
24
+ }
25
+ end
26
+
27
+ let(:instance) { Model.first }
28
+
29
+ context 'Useful Class Methods' do
30
+ it 'each' do
31
+ assert Model.each
32
+ end
33
+
34
+ it 'keys' do
35
+ assert_equal [:_key0, :_key1], Model.keys
36
+ end
37
+
38
+ it 'values' do
39
+ assert_equal Model.each.to_a, Model.values
40
+ end
41
+ end
42
+
43
+ context 'Subscript access to class' do
44
+ it 'When code and key are automatically waved' do
45
+ assert_equal 'A', Model[0].name
46
+ end
47
+
48
+ it 'It will not cause an error even if there is no corresponding key' do
49
+ assert_nothing_raised { Model[:unknown] }
50
+ end
51
+
52
+ it 'In the case of fetch, if there is no corresponding key, an error occurs' do
53
+ assert_raises { Model.fetch(:unknown) }
54
+ end
55
+
56
+ it 'fetch_if' do
57
+ assert_nothing_raised { Model.fetch_if(nil) }
58
+ end
59
+ end
60
+
61
+ context 'Subscript access to instance' do
62
+ it do
63
+ instance[:name].should == 'A'
64
+ instance[:xxxx].should == nil
65
+ end
66
+ end
67
+
68
+ context 'to_s' do
69
+ it do
70
+ instance.to_s.should == 'A'
71
+ end
72
+ end
73
+
74
+ context 'instance accessor' do
75
+ it do
76
+ assert instance.attributes
77
+ assert instance.key
78
+ assert instance.code
79
+ end
80
+ end
81
+
82
+ context 'Re-set' do
83
+ before do
84
+ @model = __define [{key: :a}]
85
+ @model.memory_record_list_set [{key: :b}, {key: :c}]
86
+ end
87
+ it 'changed' do
88
+ assert_equal [:b, :c], @model.keys
89
+ assert_equal [0, 1], @model.codes
90
+ end
91
+ end
92
+
93
+ context 'Subtle specifications' do
94
+ it 'When keys are specified as an array, they become symbols with underscores' do
95
+ model = __define [{key: [:id, :desc]}]
96
+ assert_equal [:id_desc], model.keys
97
+ end
98
+
99
+ it 'Name method is automatically defined if it is not defined' do
100
+ model = __define []
101
+ assert_equal true, model.instance_methods.include?(:name)
102
+ end
103
+ end
104
+
105
+ it 'Japanese can be used for key' do
106
+ model = __define [{key: 'あ'}]
107
+ assert model['あ']
108
+ end
109
+
110
+ it 'When you define code and keys yourself' do
111
+ assert_equal 'A', Legacy[10].name
112
+ end
113
+
114
+ it 'We do not freeze values because memoization becomes impossible' do
115
+ Model.first.name.upcase!
116
+ end
117
+
118
+ describe 'super' do
119
+ class Model2
120
+ include MemoryRecord
121
+ memory_record [
122
+ {var: 'x'},
123
+ ], attr_reader: :var
124
+
125
+ def var
126
+ super + 'y'
127
+ end
128
+ end
129
+
130
+ it 'Since methods are defined in ancestry, you can use super' do
131
+ assert_equal 'xy', Model2.first.var
132
+ end
133
+ end
134
+
135
+ describe 'attr_reader_auto' do
136
+ class Model3
137
+ include MemoryRecord
138
+ memory_record [
139
+ {a: 1},
140
+ {b: 2},
141
+ ], attr_reader_auto: true
142
+ end
143
+
144
+ it do
145
+ assert_equal 1, Model3.first.a
146
+ assert_equal nil, Model3.first.b
147
+ end
148
+ end
149
+
150
+ describe 'Do not duplicate key and code' do
151
+ it do
152
+ expect { Model.memory_record_list_set([{key: :a}, {key: :a}]) }.to raise_error(ArgumentError)
153
+ expect { Model.memory_record_list_set([{code: 0}, {code: 0}]) }.to raise_error(ArgumentError)
154
+ end
155
+ end
156
+
157
+ describe 'Human_attribute_name can not be used in anonymous class' do
158
+ let(:model) { __define [{foo: 1}] }
159
+
160
+ it 'It does not cause an error' do
161
+ model.first.name.should == nil
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'memory_record'
3
+
4
+ RSpec.configure do |config|
5
+ config.expect_with :rspec do |expectations|
6
+ expectations.syntax = [:should, :expect]
7
+ end
8
+ config.expect_with :test_unit
9
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: memory_record
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - akicho8
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-11 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: '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: rspec
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: test-unit
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: activesupport
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: activemodel
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
+ description: A small number of records Easy handling library
84
+ email:
85
+ - akicho8@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.org
96
+ - Rakefile
97
+ - examples/0110_basic.rb
98
+ - examples/0120_attr_reader_auto_option.rb
99
+ - examples/0130_for_legacy_code.rb
100
+ - examples/0140_key_join_underscore_if_array.rb
101
+ - examples/0150_behavior_like_hash.rb
102
+ - examples/0160_practice.rb
103
+ - examples/0170_reset.rb
104
+ - examples/0180_key_is_anything_ok.rb
105
+ - examples/0190_tips_on_handling_boolean_type.rb
106
+ - examples/0200_freeze_makes_it_impossible_to_memorize.rb
107
+ - examples/0210_super_usable.rb
108
+ - examples/0230_validation.rb
109
+ - examples/0240_key_duplicate.rb
110
+ - examples/0250_when_key_like_numeric.rb
111
+ - examples/0260_with_use_activerecord_enum.rb
112
+ - lib/memory_record.rb
113
+ - lib/memory_record/memory_record.rb
114
+ - lib/memory_record/version.rb
115
+ - memory_record.gemspec
116
+ - spec/memory_record_spec.rb
117
+ - spec/spec_helper.rb
118
+ homepage: ''
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 2.6.11
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: A small number of records Easy handling library
142
+ test_files:
143
+ - spec/memory_record_spec.rb
144
+ - spec/spec_helper.rb