memory_record 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.
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