mem_model 0.2.0 → 0.3.0

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MWY1MWQ5NzM1YmIzNDMyNzgzY2EwYmRhZDBmNDU2OWMzZTRmOWFmYg==
4
+ YjE0N2IyYTEwODVjYjExZDIxMzllMDIyMzk2ZDI2MzhiYjU5ZWY0Yw==
5
5
  data.tar.gz: !binary |-
6
- NWQ2OWZmMDc3YTFiOTVhNTA5MTJlODM1MDlkN2YzZGE3NDZiYzQxYg==
6
+ YWVkM2FhMTUzOTlhODYwMjQ2NDRlN2M2MzMxYjc2MzMzNjY4NGE4YQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDQ1ZjEwYTI1ZTdmN2U2NDIxMGFiYmI4ZTdiNDkwYmU0YWNhYzNkYjA1MmRh
10
- YjEzM2FkOWQxZDhkNjY5MWIwNzNjN2U0MTkyOTBiZjAwZTg1ZjkxMDM4NTc3
11
- YTJmNjI0NDlkZmJmOGEzOTI4YWYxN2YyOGIyZWU0MGI3ZDViMWI=
9
+ NDlmOTM3M2VkZWJkYjdmYjg0MWFlZWU1YjcxYWRjZDA0MTk2ZTM1NGE4NGQy
10
+ MTdhODRmMmExM2M3NGM0ZTY3NmUyZGNmMWFiN2NkOTBhYjQ0ZDQxZDdiOGE1
11
+ NWEyOTA0MmUzYmQzNjgyOTU0YjhlYzg5NjI5M2I4ZWZiZjUxODM=
12
12
  data.tar.gz: !binary |-
13
- NTc1YjYzYzVhZGZmNzM5ZmNjZjU0MWFlMjM2ODUyYzNhN2U5MGM1MTUzYTdj
14
- ZWUzNmNmMjUwOTUyMjA3ODk5YjcyYzU3MTc1YTRjZjVkNDM1ZTVjNGI2MDk4
15
- ZmJhZTNhOGQ2MDUxOGY2YjhlNzA3YmJlYjNlZDMzN2IwMWEwZDM=
13
+ NjljNmVmMjkwYmUyMDFlOGNhY2Y3Yzk2NjQ3NWE3ZjgwNjQ1Mzg4Zjg0MmRi
14
+ MzIyZTNjZmQ3ODJmMzMzMDJmMjQ0YTcyNjI1ZjkzZWIzYmE1ZDcyOWM5ZWFi
15
+ Yzg2MmJiNTZhNzlhMWQyZWNmMDM1MDIwMDhjNjUxMTUzNWE2MWE=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ### 0.3.0 / 2013-12-27
2
+
3
+ * 1 enhancement
4
+
5
+ * Add initial Validations (presence)
6
+
7
+
1
8
  ### 0.2.0 / 2013-12-23
2
9
 
3
10
  * 1 enhancement
data/Gemfile.ci CHANGED
@@ -2,7 +2,5 @@ source 'http://rubygems.org'
2
2
 
3
3
  gem 'rake'
4
4
  gem 'hoe'
5
- gem 'active_attr', '>= 0.8.2'
6
- gem 'activesupport', '= 3.2.15' # MagLev optimized version
7
5
  gem 'minitest'
8
6
  gem 'coveralls', :require => false
data/Manifest.txt CHANGED
@@ -10,14 +10,19 @@ README.md
10
10
  Rakefile
11
11
  lib/mem_model.rb
12
12
  lib/mem_model/base.rb
13
+ lib/mem_model/concern.rb
14
+ lib/mem_model/errors.rb
13
15
  lib/mem_model/guid.rb
16
+ lib/mem_model/model_name.rb
14
17
  lib/mem_model/rooted_base.rb
15
- lib/mem_model/rooted_store.rb
18
+ lib/mem_model/validations.rb
16
19
  lib/mem_model/version.rb
17
20
  mem_model.gemspec
18
21
  test/helper.rb
19
22
  test/mem_model/test_active_model.rb
20
23
  test/mem_model/test_base.rb
21
24
  test/mem_model/test_guid.rb
22
- test/mem_model/test_rooted_store.rb
23
- test/test_version.rb
25
+ test/mem_model/test_rooted_base.rb
26
+ test/mem_model/test_validations.rb
27
+ test/mem_model/test_version.rb
28
+ test/support/active_model_lint.rb
data/README.md CHANGED
@@ -32,7 +32,7 @@ require 'mem_model'
32
32
 
33
33
  class Account
34
34
  include MemModel::Base
35
- attribute :balance
35
+ attr_accessor :balance
36
36
  validates_presence_of :balance
37
37
  end
38
38
 
data/Rakefile CHANGED
@@ -29,6 +29,11 @@ task :changelog do
29
29
  puts "Prepended these new changes:\n\n#{changes}"
30
30
  end
31
31
 
32
+ desc 'Console'
33
+ task :console do
34
+ sh "irb -rubygems -r ./lib/mem_model"
35
+ end
36
+
32
37
  if defined? Hoe
33
38
 
34
39
  [ :debug, :deps, :gemcutter, :newb, :publish, :signing ].each do |plugin|
@@ -37,7 +42,6 @@ end
37
42
 
38
43
  Hoe.plugin :git
39
44
  Hoe.plugin :gemspec
40
- #Hoe.plugin :rubygems
41
45
 
42
46
  Hoe.spec 'mem_model' do
43
47
  developer 'JohnnyT', 'ubergeek3141@gmail.com'
@@ -57,9 +61,6 @@ Hoe.spec 'mem_model' do
57
61
 
58
62
  license 'MIT'
59
63
 
60
- dependency 'active_attr', '>= 0.8.2'
61
- dependency 'activesupport', '>= 3.2.15'
62
-
63
64
  dependency 'minitest', '>= 5.0.0', :development
64
65
  dependency 'minitest-reporters', '>= 1.0.0', :development
65
66
  dependency 'coveralls', '>= 1.0.0', :development
@@ -1,24 +1,41 @@
1
1
  module MemModel
2
- class UnknownRecord < ArgumentError; end
3
- class InvalidRecord < StandardError; end
4
-
5
2
  module Base
6
- def self.included(base)
7
- base.send :include, ActiveAttr::Model
8
- base.send :extend, Enumerable
9
- base.send :extend, ClassMethods
10
- base.class_eval do
11
- attribute :id
12
- end
3
+ extend MemModel::Concern
4
+
5
+ included do
6
+ include MemModel::Validations
7
+ attr_accessor :id
13
8
  end
14
9
 
15
10
  module ClassMethods
16
- extend Forwardable
17
- def_delegators :store, :each, :size, :entries
18
- alias_method :all, :entries
11
+ include Enumerable
12
+
13
+ def each(&block)
14
+ store.each(&block)
15
+ end
16
+
17
+ def model_name
18
+ @model_name ||= ModelName.new(self.name)
19
+ end
20
+
21
+ def store_class
22
+ MemModel.maglev? ? IdentitySet : Set
23
+ end
19
24
 
20
25
  def store
21
- @store ||= Set.new
26
+ @store ||= store_class.new
27
+ end
28
+
29
+ def size
30
+ store.size
31
+ end
32
+
33
+ def all
34
+ store.to_a
35
+ end
36
+
37
+ def last
38
+ all[-1]
22
39
  end
23
40
 
24
41
  def generate_id
@@ -40,22 +57,6 @@ module MemModel
40
57
  store.any?{ |record| record.id == id }
41
58
  end
42
59
 
43
- def update(id, atts)
44
- find(id).update_attributes(atts)
45
- end
46
-
47
- def destroy(id)
48
- find(id).destroy
49
- end
50
-
51
- # Removes all records and executes
52
- # destroy callbacks.
53
- def destroy_all
54
- all.each {|r| r.destroy }
55
- end
56
-
57
- # Removes all records without executing
58
- # destroy callbacks.
59
60
  def delete_all
60
61
  store.clear
61
62
  end
@@ -68,8 +69,24 @@ module MemModel
68
69
  rec.save && rec
69
70
  end
70
71
 
71
- def create!(*args)
72
- create(*args) || raise(InvalidRecord)
72
+ def maglev?
73
+ MemModel.maglev?
74
+ end
75
+
76
+ def abort
77
+ # no-op
78
+ true
79
+ end
80
+
81
+ def commit
82
+ # no-op
83
+ true
84
+ end
85
+
86
+ alias_method :to_str, :to_s
87
+
88
+ def delete(record)
89
+ store.delete(record)
73
90
  end
74
91
  end
75
92
 
@@ -79,6 +96,34 @@ module MemModel
79
96
  load_attributes(attributes)
80
97
  end
81
98
 
99
+
100
+ def model_name; self.class.model_name; end
101
+ def persisted?; true; end
102
+
103
+ def to_key; end
104
+ def to_param; end
105
+ def to_partial_path; 'something'; end
106
+
107
+ def errors; @errors ||= Errors.new(self); end
108
+
109
+
110
+ def maglev?
111
+ self.class.maglev?
112
+ end
113
+
114
+ def abort
115
+ self.class.abort
116
+ end
117
+
118
+ def commit
119
+ self.class.commit
120
+ end
121
+
122
+ def persistent(&block)
123
+ # no-op
124
+ block.call
125
+ end
126
+
82
127
  def new?
83
128
  !exists?
84
129
  end
@@ -92,19 +137,17 @@ module MemModel
92
137
  new? ? create : update
93
138
  end
94
139
 
95
- def save!
96
- save || raise(InvalidRecord)
97
- end
98
-
99
140
  def create
100
141
  self.id ||= generate_id
101
- self.class.store << self
102
- @persisted = true
142
+ persistent do
143
+ self.class.store << self
144
+ @persisted = true
145
+ end
103
146
  self.id
104
147
  end
105
148
 
106
149
  def update
107
- # no-op
150
+ commit
108
151
  true
109
152
  end
110
153
 
@@ -113,8 +156,8 @@ module MemModel
113
156
  save
114
157
  end
115
158
 
116
- def destroy
117
- self.class.records.delete(self.id)
159
+ def delete
160
+ self.class.delete(self)
118
161
  self
119
162
  end
120
163
 
@@ -0,0 +1,28 @@
1
+ module MemModel
2
+ module Concern
3
+ def self.extended(base)
4
+ base.instance_variable_set("@_dependencies", [])
5
+ end
6
+
7
+ def append_features(base)
8
+ if base.instance_variable_defined?("@_dependencies")
9
+ base.instance_variable_get("@_dependencies") << self
10
+ return false
11
+ else
12
+ return false if base < self
13
+ @_dependencies.each { |dep| base.send(:include, dep) }
14
+ super
15
+ base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
16
+ base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
17
+ end
18
+ end
19
+
20
+ def included(base = nil, &block)
21
+ if base.nil?
22
+ @_included_block = block
23
+ else
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,45 @@
1
+ module MemModel
2
+ class UnknownRecord < ArgumentError; end
3
+ class InvalidRecord < StandardError; end
4
+
5
+ class Errors
6
+ include Enumerable
7
+
8
+ attr_reader :messages
9
+
10
+ def initialize(base)
11
+ @base = base
12
+ @messages = {}
13
+ end
14
+
15
+ def each
16
+ messages.each_key do |attribute|
17
+ self[attribute].each { |error| yield attribute, error }
18
+ end
19
+ end
20
+
21
+ def full_messages
22
+ map { |attribute, message| full_message(attribute, message) }
23
+ end
24
+
25
+ def full_message(attribute, message)
26
+ [attribute, message].join(' ')
27
+ end
28
+
29
+ def [](attribute)
30
+ get(attribute.to_sym) || set(attribute.to_sym, [])
31
+ end
32
+
33
+ def []=(attribute, error)
34
+ self[attribute] << error
35
+ end
36
+
37
+ def get(key)
38
+ messages[key]
39
+ end
40
+
41
+ def set(key, value)
42
+ messages[key] = value
43
+ end
44
+ end
45
+ end
@@ -1,8 +1,6 @@
1
1
  module MemModel
2
2
  module Guid
3
- def self.included(base)
4
- base.send :extend, MemModel::Guid::ClassMethods
5
- end
3
+ extend MemModel::Concern
6
4
 
7
5
  module ClassMethods
8
6
  def generate_id
@@ -0,0 +1,7 @@
1
+ module MemModel
2
+ class ModelName < String
3
+ def human; self; end
4
+ def singular; self; end
5
+ def plural; self; end
6
+ end
7
+ end
@@ -1,8 +1,49 @@
1
1
  module MemModel
2
+ PERSISTENT_ROOT = {} if !MemModel.maglev?
3
+
2
4
  module RootedBase
3
- def self.included(base)
4
- base.send :include, Base
5
- base.send :include, RootedStore
5
+ extend MemModel::Concern
6
+ include Base
7
+
8
+ module ClassMethods
9
+ def root_container
10
+ MemModel.maglev? ? Maglev : MemModel
11
+ end
12
+
13
+ def container_key
14
+ name.to_sym
15
+ end
16
+
17
+ def store
18
+ root[:MemModel] ||= {}
19
+ root[:MemModel][container_key] ||= store_class.new
20
+ end
21
+
22
+ def root
23
+ @root ||= root_container::PERSISTENT_ROOT
24
+ end
25
+
26
+ def abort
27
+ Maglev.abort_transaction if maglev?
28
+ true
29
+ end
30
+
31
+ def commit
32
+ Maglev.commit_transaction if maglev?
33
+ true
34
+ end
35
+
36
+ def persistent(&block)
37
+ abort
38
+ maglev? ?
39
+ Maglev.persistent { block.call } :
40
+ block.call
41
+ commit
42
+ end
43
+ end
44
+
45
+ def persistent(&block)
46
+ self.class.persistent(&block)
6
47
  end
7
48
  end
8
49
  end
@@ -0,0 +1,26 @@
1
+ module MemModel
2
+ module Validations
3
+ extend MemModel::Concern
4
+
5
+ module ClassMethods
6
+ def validations
7
+ @validations ||= []
8
+ end
9
+
10
+ def validates_presence_of(attr)
11
+ validations << [:presence, attr]
12
+ end
13
+ end
14
+
15
+ def valid?
16
+ validations.empty? || validations.all? do |kind, attr|
17
+ value = self.send(attr)
18
+ value && value != ''
19
+ end
20
+ end
21
+
22
+ def validations
23
+ self.class.validations
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module MemModel
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/mem_model.rb CHANGED
@@ -1,24 +1,16 @@
1
1
  lib_dir = File.dirname(__FILE__)
2
2
  $LOAD_PATH << lib_dir unless $LOAD_PATH.include? lib_dir
3
3
 
4
- require 'active_attr'
5
4
  require 'securerandom'
6
- require 'forwardable'
7
5
  require 'set'
8
- require 'active_support/dependencies/autoload'
9
6
 
10
7
  module MemModel
11
8
  def maglev?
12
9
  !defined?(Maglev).nil?
13
10
  end
14
11
  module_function :maglev?
15
-
16
- extend ActiveSupport::Autoload
17
-
18
- autoload :Base
19
- autoload :Guid
20
- autoload :RootedBase
21
- autoload :RootedStore
22
12
  end
23
13
 
24
- require 'mem_model/version'
14
+ %w[ concern base errors guid model_name rooted_base validations version ].each do |file|
15
+ load File.expand_path("../mem_model/#{file}.rb", __FILE__)
16
+ end
data/mem_model.gemspec CHANGED
@@ -1,17 +1,17 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: mem_model 0.2.0.20131223123844 ruby lib
2
+ # stub: mem_model 0.3.0.20131227093624 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "mem_model"
6
- s.version = "0.2.0.20131223123844"
6
+ s.version = "0.3.0.20131227093624"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.authors = ["JohnnyT"]
10
- s.date = "2013-12-23"
10
+ s.date = "2013-12-27"
11
11
  s.description = "MemModel persists Ruby objects using MagLev as a data storage engine. It's an ActiveModel implementation so it works stand-alone or in Rails 3 as a drop-in replacement for ActiveRecord or DataMapper. If MemModel is used in non-MagLev platforms, objects will be persisted to in-memory sets."
12
12
  s.email = ["ubergeek3141@gmail.com"]
13
13
  s.extra_rdoc_files = ["CHANGELOG.md", "CONTRIBUTING.md", "LICENSE.md", "Manifest.txt", "README.md"]
14
- s.files = [".coveralls.yml", ".gitignore", ".travis.yml", "CHANGELOG.md", "CONTRIBUTING.md", "Gemfile.ci", "LICENSE.md", "Manifest.txt", "README.md", "Rakefile", "lib/mem_model.rb", "lib/mem_model/base.rb", "lib/mem_model/guid.rb", "lib/mem_model/rooted_base.rb", "lib/mem_model/rooted_store.rb", "lib/mem_model/version.rb", "mem_model.gemspec", "test/helper.rb", "test/mem_model/test_active_model.rb", "test/mem_model/test_base.rb", "test/mem_model/test_guid.rb", "test/mem_model/test_rooted_store.rb", "test/test_version.rb", ".gemtest"]
14
+ s.files = [".coveralls.yml", ".gitignore", ".travis.yml", "CHANGELOG.md", "CONTRIBUTING.md", "Gemfile.ci", "LICENSE.md", "Manifest.txt", "README.md", "Rakefile", "lib/mem_model.rb", "lib/mem_model/base.rb", "lib/mem_model/guid.rb", "lib/mem_model/rooted_base.rb", "lib/mem_model/rooted_store.rb", "lib/mem_model/version.rb", "mem_model.gemspec", "test/helper.rb", "test/mem_model/test_active_model.rb", "test/mem_model/test_base.rb", "test/mem_model/test_guid.rb", "test/mem_model/test_rooted_store.rb", "test/test_version.rb", "test/mem_model/test_rooted_base.rb", "test/mem_model/test_validations.rb", "test/mem_model/test_version.rb", ".gemtest"]
15
15
  s.homepage = "https://github.com/johnnyt/mem_model"
16
16
  s.licenses = ["MIT"]
17
17
  s.rdoc_options = ["--main", "README.md"]
@@ -19,29 +19,23 @@ Gem::Specification.new do |s|
19
19
  s.rubyforge_project = "mem_model"
20
20
  s.rubygems_version = "2.1.11"
21
21
  s.summary = "ActiveModel-compliant MagLev persistence"
22
- s.test_files = ["test/mem_model/test_guid.rb", "test/mem_model/test_base.rb", "test/mem_model/test_rooted_store.rb", "test/mem_model/test_active_model.rb", "test/test_version.rb"]
22
+ s.test_files = ["test/mem_model/test_rooted_base.rb", "test/mem_model/test_guid.rb", "test/mem_model/test_base.rb", "test/mem_model/test_active_model.rb", "test/mem_model/test_validations.rb", "test/mem_model/test_version.rb"]
23
23
 
24
24
  if s.respond_to? :specification_version then
25
25
  s.specification_version = 4
26
26
 
27
27
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
- s.add_runtime_dependency(%q<active_attr>, [">= 0.8.2"])
29
- s.add_runtime_dependency(%q<activesupport>, [">= 3.2.15"])
30
28
  s.add_development_dependency(%q<minitest>, [">= 5.0.0"])
31
29
  s.add_development_dependency(%q<minitest-reporters>, [">= 1.0.0"])
32
30
  s.add_development_dependency(%q<coveralls>, [">= 1.0.0"])
33
31
  s.add_development_dependency(%q<hoe>, ["~> 3.7"])
34
32
  else
35
- s.add_dependency(%q<active_attr>, [">= 0.8.2"])
36
- s.add_dependency(%q<activesupport>, [">= 3.2.15"])
37
33
  s.add_dependency(%q<minitest>, [">= 5.0.0"])
38
34
  s.add_dependency(%q<minitest-reporters>, [">= 1.0.0"])
39
35
  s.add_dependency(%q<coveralls>, [">= 1.0.0"])
40
36
  s.add_dependency(%q<hoe>, ["~> 3.7"])
41
37
  end
42
38
  else
43
- s.add_dependency(%q<active_attr>, [">= 0.8.2"])
44
- s.add_dependency(%q<activesupport>, [">= 3.2.15"])
45
39
  s.add_dependency(%q<minitest>, [">= 5.0.0"])
46
40
  s.add_dependency(%q<minitest-reporters>, [">= 1.0.0"])
47
41
  s.add_dependency(%q<coveralls>, [">= 1.0.0"])
data/test/helper.rb CHANGED
@@ -1,9 +1,5 @@
1
1
  require 'rubygems'
2
2
 
3
- # Disable warning message
4
- require 'i18n'
5
- I18n.enforce_available_locales = false
6
-
7
3
  # Only run coverage in MRI
8
4
  unless defined? Maglev
9
5
  if ENV['CI']
@@ -16,6 +12,6 @@ unless defined? Maglev
16
12
  end
17
13
 
18
14
  require File.expand_path('lib/mem_model')
19
- require 'active_model/lint'
15
+ Dir[File.expand_path('../support/*.rb', __FILE__)].each { |file| require file }
20
16
  gem 'minitest', '5.2.0'
21
17
  require 'minitest/autorun'
@@ -3,7 +3,7 @@ require File.expand_path('../../helper', __FILE__)
3
3
  class TestBase < Minitest::Test
4
4
  class Account
5
5
  include MemModel::Base
6
- attribute :balance
6
+ attr_accessor :balance
7
7
  end
8
8
 
9
9
  def setup
@@ -25,14 +25,14 @@ class TestBase < Minitest::Test
25
25
  assert Account.exists? @account.id
26
26
  end
27
27
 
28
- def test_update
29
- @account.save
30
- new_balance = 314
31
- refute_equal new_balance, @account.balance
28
+ #def test_update
29
+ # @account.save
30
+ # new_balance = 314
31
+ # refute_equal new_balance, @account.balance
32
32
 
33
- Account.update @account.id, :balance => new_balance
34
- assert_equal new_balance, @account.balance
35
- end
33
+ # Account.update @account.id, :balance => new_balance
34
+ # assert_equal new_balance, @account.balance
35
+ #end
36
36
 
37
37
  def test_new_model_is_new_record
38
38
  assert @account.new_record?
@@ -53,4 +53,45 @@ class TestBase < Minitest::Test
53
53
  @account.save
54
54
  assert_equal @account, Account.find(@account.id)
55
55
  end
56
+
57
+ def test_size
58
+ assert Account.size.zero?
59
+ @account.save
60
+ assert_equal 1, Account.size
61
+ end
62
+
63
+ def test_last
64
+ @account.save
65
+ assert_equal @account, Account.last
66
+ end
67
+
68
+ def test_all
69
+ @account.save
70
+ assert_equal [@account], Account.all
71
+ end
72
+
73
+ def test_abort
74
+ # no-op in MRI
75
+ assert @account.abort
76
+ end
77
+
78
+ def test_commit
79
+ # no-op in MRI
80
+ assert @account.commit
81
+ end
82
+
83
+ def test_delete
84
+ @account.save
85
+ refute Account.size.zero?
86
+ @account.delete
87
+ assert Account.size.zero?
88
+ end
89
+
90
+ def test_maglev?
91
+ if defined? Maglev
92
+ assert @account.maglev?
93
+ else
94
+ refute @account.maglev?
95
+ end
96
+ end
56
97
  end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path('../../helper', __FILE__)
2
2
 
3
- class TestRootedStore < Minitest::Test
3
+ class TestRootedBase < Minitest::Test
4
4
  class Account
5
5
  include MemModel::RootedBase
6
6
  end
@@ -31,4 +31,14 @@ class TestRootedStore < Minitest::Test
31
31
  assert_equal MemModel, Account.root_container
32
32
  end
33
33
  end
34
+
35
+ def test_abort
36
+ # no-op in MRI
37
+ assert @account.abort
38
+ end
39
+
40
+ def test_commit
41
+ # no-op in MRI
42
+ assert @account.commit
43
+ end
34
44
  end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../../helper', __FILE__)
2
+
3
+ class TestValidations < Minitest::Test
4
+ class Account
5
+ include MemModel::Base
6
+ attr_accessor :balance
7
+ validates_presence_of :balance
8
+ end
9
+
10
+ def setup
11
+ @account = Account.new
12
+ end
13
+
14
+ def teardown
15
+ @account = nil
16
+ Account.delete_all
17
+ end
18
+
19
+ def test_presence
20
+ refute @account.valid?
21
+ @account.balance = 0
22
+ assert @account.valid?
23
+ end
24
+ end
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require File.expand_path('../../helper', __FILE__)
2
2
 
3
3
  class TestVersion < Minitest::Test
4
4
  def test_version
@@ -0,0 +1,110 @@
1
+ module ActiveModel
2
+ module Lint
3
+ # == Active \Model \Lint \Tests
4
+ #
5
+ # You can test whether an object is compliant with the Active \Model API by
6
+ # including <tt>ActiveModel::Lint::Tests</tt> in your TestCase. It will
7
+ # include tests that tell you whether your object is fully compliant,
8
+ # or if not, which aspects of the API are not implemented.
9
+ #
10
+ # Note an object is not required to implement all APIs in order to work
11
+ # with Action Pack. This module only intends to provide guidance in case
12
+ # you want all features out of the box.
13
+ #
14
+ # These tests do not attempt to determine the semantic correctness of the
15
+ # returned values. For instance, you could implement <tt>valid?</tt> to
16
+ # always return true, and the tests would pass. It is up to you to ensure
17
+ # that the values are semantically meaningful.
18
+ #
19
+ # Objects you pass in are expected to return a compliant object from a call
20
+ # to <tt>to_model</tt>. It is perfectly fine for <tt>to_model</tt> to return
21
+ # +self+.
22
+ module Tests
23
+
24
+ # == Responds to <tt>to_key</tt>
25
+ #
26
+ # Returns an Enumerable of all (primary) key attributes
27
+ # or nil if <tt>model.persisted?</tt> is false. This is used by
28
+ # <tt>dom_id</tt> to generate unique ids for the object.
29
+ def test_to_key
30
+ assert model.respond_to?(:to_key), "The model should respond to to_key"
31
+ def model.persisted?() false end
32
+ assert model.to_key.nil?, "to_key should return nil when `persisted?` returns false"
33
+ end
34
+
35
+ # == Responds to <tt>to_param</tt>
36
+ #
37
+ # Returns a string representing the object's key suitable for use in URLs
38
+ # or +nil+ if <tt>model.persisted?</tt> is +false+.
39
+ #
40
+ # Implementers can decide to either raise an exception or provide a
41
+ # default in case the record uses a composite primary key. There are no
42
+ # tests for this behavior in lint because it doesn't make sense to force
43
+ # any of the possible implementation strategies on the implementer.
44
+ # However, if the resource is not persisted?, then <tt>to_param</tt>
45
+ # should always return +nil+.
46
+ def test_to_param
47
+ assert model.respond_to?(:to_param), "The model should respond to to_param"
48
+ def model.to_key() [1] end
49
+ def model.persisted?() false end
50
+ assert model.to_param.nil?, "to_param should return nil when `persisted?` returns false"
51
+ end
52
+
53
+ # == Responds to <tt>to_partial_path</tt>
54
+ #
55
+ # Returns a string giving a relative path. This is used for looking up
56
+ # partials. For example, a BlogPost model might return "blog_posts/blog_post"
57
+ def test_to_partial_path
58
+ assert model.respond_to?(:to_partial_path), "The model should respond to to_partial_path"
59
+ assert_kind_of String, model.to_partial_path
60
+ end
61
+
62
+ # == Responds to <tt>persisted?</tt>
63
+ #
64
+ # Returns a boolean that specifies whether the object has been persisted
65
+ # yet. This is used when calculating the URL for an object. If the object
66
+ # is not persisted, a form for that object, for instance, will route to
67
+ # the create action. If it is persisted, a form for the object will routes
68
+ # to the update action.
69
+ def test_persisted?
70
+ assert model.respond_to?(:persisted?), "The model should respond to persisted?"
71
+ assert_boolean model.persisted?, "persisted?"
72
+ end
73
+
74
+ # == \Naming
75
+ #
76
+ # Model.model_name must return a string with some convenience methods:
77
+ # <tt>:human</tt>, <tt>:singular</tt> and <tt>:plural</tt>. Check
78
+ # ActiveModel::Naming for more information.
79
+ def test_model_naming
80
+ assert model.class.respond_to?(:model_name), "The model should respond to model_name"
81
+ model_name = model.class.model_name
82
+ assert model_name.respond_to?(:to_str)
83
+ assert model_name.human.respond_to?(:to_str)
84
+ assert model_name.singular.respond_to?(:to_str)
85
+ assert model_name.plural.respond_to?(:to_str)
86
+ end
87
+
88
+ # == \Errors Testing
89
+ #
90
+ # Returns an object that implements [](attribute) defined which returns an
91
+ # Array of Strings that are the errors for the attribute in question.
92
+ # If localization is used, the Strings should be localized for the current
93
+ # locale. If no error is present, this method should return an empty Array.
94
+ def test_errors_aref
95
+ assert model.respond_to?(:errors), "The model should respond to errors"
96
+ assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array"
97
+ end
98
+
99
+ private
100
+ def model
101
+ assert @model.respond_to?(:to_model), "The object should respond to to_model"
102
+ @model.to_model
103
+ end
104
+
105
+ def assert_boolean(result, name)
106
+ assert result == true || result == false, "#{name} should be a boolean"
107
+ end
108
+ end
109
+ end
110
+ end
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mem_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - JohnnyT
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-23 00:00:00.000000000 Z
11
+ date: 2013-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: active_attr
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ! '>='
18
- - !ruby/object:Gem::Version
19
- version: 0.8.2
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ! '>='
25
- - !ruby/object:Gem::Version
26
- version: 0.8.2
27
- - !ruby/object:Gem::Dependency
28
- name: activesupport
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ! '>='
32
- - !ruby/object:Gem::Version
33
- version: 3.2.15
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ! '>='
39
- - !ruby/object:Gem::Version
40
- version: 3.2.15
41
13
  - !ruby/object:Gem::Dependency
42
14
  name: minitest
43
15
  requirement: !ruby/object:Gem::Requirement
@@ -121,17 +93,22 @@ files:
121
93
  - Rakefile
122
94
  - lib/mem_model.rb
123
95
  - lib/mem_model/base.rb
96
+ - lib/mem_model/concern.rb
97
+ - lib/mem_model/errors.rb
124
98
  - lib/mem_model/guid.rb
99
+ - lib/mem_model/model_name.rb
125
100
  - lib/mem_model/rooted_base.rb
126
- - lib/mem_model/rooted_store.rb
101
+ - lib/mem_model/validations.rb
127
102
  - lib/mem_model/version.rb
128
103
  - mem_model.gemspec
129
104
  - test/helper.rb
130
105
  - test/mem_model/test_active_model.rb
131
106
  - test/mem_model/test_base.rb
132
107
  - test/mem_model/test_guid.rb
133
- - test/mem_model/test_rooted_store.rb
134
- - test/test_version.rb
108
+ - test/mem_model/test_rooted_base.rb
109
+ - test/mem_model/test_validations.rb
110
+ - test/mem_model/test_version.rb
111
+ - test/support/active_model_lint.rb
135
112
  - .gemtest
136
113
  homepage: https://github.com/johnnyt/mem_model
137
114
  licenses:
@@ -160,8 +137,9 @@ signing_key:
160
137
  specification_version: 4
161
138
  summary: ActiveModel-compliant MagLev persistence
162
139
  test_files:
140
+ - test/mem_model/test_rooted_base.rb
163
141
  - test/mem_model/test_guid.rb
164
142
  - test/mem_model/test_base.rb
165
- - test/mem_model/test_rooted_store.rb
166
143
  - test/mem_model/test_active_model.rb
167
- - test/test_version.rb
144
+ - test/mem_model/test_validations.rb
145
+ - test/mem_model/test_version.rb
@@ -1,28 +0,0 @@
1
- module MemModel
2
- PERSISTENT_ROOT = {} if !MemModel.maglev?
3
-
4
- module RootedStore
5
- def self.included(base)
6
- base.send :extend, ClassMethods
7
- end
8
-
9
- module ClassMethods
10
- def store_class
11
- MemModel.maglev? ? IdentitySet : Set
12
- end
13
-
14
- def root_container
15
- MemModel.maglev? ? Maglev : MemModel
16
- end
17
-
18
- def store
19
- root[:MemModel] ||= {}
20
- root[:MemModel][name] ||= store_class.new
21
- end
22
-
23
- def root
24
- @root ||= root_container::PERSISTENT_ROOT
25
- end
26
- end
27
- end
28
- end