Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/dolly/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def initialize_default_properties options
_properties.reject { |property| options.keys.include? property.name }.each do |property|
property_value = property.default.clone unless Dolly::Property::CANT_CLONE.any? { |klass| property.default.is_a? klass }
property_value ||= property.default
property_value.default_proc = property.default_proc if property.procable?
self.doc[property.name] ||= property_value
end
end
Expand Down
16 changes: 14 additions & 2 deletions lib/dolly/property.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ module Dolly
class Property
attr_writer :value
attr_accessor :name
attr_reader :class_name, :default
attr_reader :class_name, :default, :default_proc

CANT_CLONE = [NilClass, TrueClass, FalseClass, Fixnum].freeze

def initialize opts = {}
@class_name = opts.delete(:class_name) if opts.present?
@name = opts.delete(:name).to_s
@default = opts.delete(:default)
@default_proc = opts.delete(:default_proc)
@default = @default.clone if @default && CANT_CLONE.none? { |klass| @default.is_a? klass }
@value = @default if @default
warn 'There are some unprocessed options!' if opts.present?
Expand All @@ -32,7 +33,9 @@ def array_value
end

def hash_value
@value.to_h
@value.to_h.tap do |h|
h.default_proc = @default_proc if @default_proc
end
end

def string_value
Expand Down Expand Up @@ -71,7 +74,16 @@ def boolean?
self_klass == TrueClass || self_klass == FalseClass
end

def procable?
default_proc? && (default.is_a?(Hash) || class_name == Hash)
end

private

def default_proc?
@default_proc.present?
end

def truthy_value?
@value =~ /true/ || @value === true
end
Expand Down
27 changes: 27 additions & 0 deletions test/document_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ class Bar < FooBar
property :a, :b
end

class DefaultProcDoc < Dolly::Document
property :foo, class_name: Hash, default: {}, default_proc: Proc.new { |h,k| h[k] = Hash.new &h.default_proc }
end

class DocumentTest < ActiveSupport::TestCase
DB_BASE_PATH = "http://localhost:5984/test".freeze

Expand Down Expand Up @@ -498,6 +502,29 @@ def setup
assert_equal 1, bar.a
end

test "hash properties can have a default proc" do
doc = DefaultProcDoc.new
doc.foo['a']['b']['c'] = 'd'
assert_equal 'd', doc.foo['a']['b']['c']
end

test "hash properties have their default proc reappliced after a query" do
assert _doc_id = "default_proc_doc/5623c56d-1c12-4f75-9202-93da5925177a"
assert save_response = {ok: true, id: _doc_id, rev: "1"}
assert FakeWeb.register_uri :put, /http:\/\/localhost:5984\/test\/default_proc_doc%2F.+/, body: save_response.to_json
assert doc = DefaultProcDoc.new
assert doc.doc['_id'] = _doc_id
assert doc.foo['a']['b']['c'] = 'd'
assert doc.save
expected_doc = doc.doc
assert FakeWeb.register_uri :get, "#{query_base_path}?keys=%5B%22default_proc_doc%2F5623c56d-1c12-4f75-9202-93da5925177a%22%5D&include_docs=true",
body: build_view_response([expected_doc]).to_json
assert doc.reload
assert_equal 'd', doc.foo['a']['b']['c']
assert doc.foo['a']['b']['d']['e'] = 'f'
assert_equal 'f', doc.foo['a']['b']['d']['e']
end

private
def generic_response rows, count = 1
{total_rows: count, offset:0, rows: rows}
Expand Down