document_mapper 0.2.1 → 0.2.2
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 +4 -4
- data/lib/document_mapper/attribute_methods.rb +5 -2
- data/lib/document_mapper/constants.rb +9 -7
- data/lib/document_mapper/core_ext/object.rb +3 -1
- data/lib/document_mapper/core_ext/symbol.rb +6 -4
- data/lib/document_mapper/document.rb +18 -13
- data/lib/document_mapper/errors.rb +2 -0
- data/lib/document_mapper/query.rb +14 -13
- data/lib/document_mapper/selector.rb +6 -4
- data/lib/document_mapper/to_html.rb +2 -1
- data/lib/document_mapper/version.rb +3 -1
- data/lib/document_mapper/yaml_parsing.rb +32 -21
- data/lib/document_mapper.rb +2 -0
- data/test/document_mapper/core_ext/symbol_test.rb +10 -10
- data/test/document_mapper/document_mapper_test.rb +56 -67
- data/test/document_mapper/selector_test.rb +4 -2
- data/test/documents_with_invalid_yaml/2010-08-08-test-document-file.textile +8 -0
- data/test/documents_with_invalid_yaml/invalid_yaml.textile +5 -0
- data/test/test_base.rb +13 -6
- metadata +43 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 686cfa311491dffd0850086273e27f69df1db880f6d2628c20ae22d6e05051f3
|
4
|
+
data.tar.gz: cca3a95f9b6b940e0217e4bb6fae4a67cb65a004aa71b498cdf728bc982c00ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4dbfa2ab84854f3b8d3e365fcf61bf75f573a7f1f4ab426cda3bf5592d5223531f40ce91bff1a7fb0601e00ae1fa6aea02118710c121563d1013d40af28941d
|
7
|
+
data.tar.gz: f549a89c9744e30b38dd621b63d09df35f163f5401798d201cd012f14fdf2ff7ab6ad96f8af11ceb548ef3ede288d6b5fc1a0e1a911e7b4c17d9a090b859ab00
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DocumentMapper
|
2
4
|
module AttributeMethods
|
3
5
|
module Read
|
@@ -10,8 +12,9 @@ module DocumentMapper
|
|
10
12
|
|
11
13
|
module ClassMethods
|
12
14
|
def define_read_method(attr_name)
|
13
|
-
|
14
|
-
|
15
|
+
generated_attribute_methods.redefine_method(attr_name) do
|
16
|
+
attributes[attr_name]
|
17
|
+
end
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DocumentMapper
|
2
4
|
OPERATOR_MAPPING = {
|
3
|
-
'equal'
|
4
|
-
'gt'
|
5
|
-
'gte'
|
6
|
-
'in'
|
5
|
+
'equal' => :==,
|
6
|
+
'gt' => :>,
|
7
|
+
'gte' => :>=,
|
8
|
+
'in' => :in?,
|
7
9
|
'include' => :include?,
|
8
|
-
'lt'
|
9
|
-
'lte'
|
10
|
-
}
|
10
|
+
'lt' => :<,
|
11
|
+
'lte' => :<=
|
12
|
+
}.freeze
|
11
13
|
|
12
14
|
VALID_OPERATORS = OPERATOR_MAPPING.keys
|
13
15
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Backported from ActiveSupport 3.1. Should be removed once the 3.1
|
2
4
|
# version is out.
|
3
5
|
|
@@ -13,6 +15,6 @@ class Object
|
|
13
15
|
def in?(another_object)
|
14
16
|
another_object.include?(self)
|
15
17
|
rescue NoMethodError
|
16
|
-
raise ArgumentError
|
18
|
+
raise ArgumentError, 'The parameter passed to #in? must respond to #include?'
|
17
19
|
end
|
18
20
|
end
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Symbol
|
2
4
|
DocumentMapper::VALID_OPERATORS.each do |operator|
|
3
|
-
class_eval <<-OPERATORS
|
5
|
+
class_eval <<-OPERATORS, __FILE__, __LINE__ + 1
|
4
6
|
def #{operator}
|
5
7
|
DocumentMapper::Selector.new(:attribute => self, :operator => '#{operator}')
|
6
8
|
end
|
7
9
|
OPERATORS
|
8
10
|
end
|
9
|
-
|
10
|
-
unless method_defined?(
|
11
|
+
|
12
|
+
unless method_defined?(:<=>)
|
11
13
|
def <=>(other)
|
12
|
-
|
14
|
+
to_s <=> other.to_s
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_model'
|
2
4
|
|
3
5
|
module DocumentMapper
|
@@ -14,9 +16,10 @@ module DocumentMapper
|
|
14
16
|
@documents = []
|
15
17
|
end
|
16
18
|
|
17
|
-
def ==(
|
18
|
-
return false unless
|
19
|
-
|
19
|
+
def ==(other)
|
20
|
+
return false unless other.is_a? Document
|
21
|
+
|
22
|
+
file_path == other.file_path
|
20
23
|
end
|
21
24
|
|
22
25
|
module ClassMethods
|
@@ -25,17 +28,16 @@ module DocumentMapper
|
|
25
28
|
end
|
26
29
|
|
27
30
|
def reload
|
28
|
-
|
31
|
+
reset
|
29
32
|
self.directory = @directory.path
|
30
33
|
end
|
31
34
|
|
32
35
|
def from_file(file_path)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
self.new.tap do |document|
|
36
|
+
raise FileNotFoundError unless File.exist? file_path
|
37
|
+
|
38
|
+
new.tap do |document|
|
37
39
|
document.attributes = {
|
38
|
-
:
|
40
|
+
file_path: File.expand_path(file_path)
|
39
41
|
}
|
40
42
|
document.read_yaml
|
41
43
|
@documents << document
|
@@ -44,11 +46,13 @@ module DocumentMapper
|
|
44
46
|
|
45
47
|
def directory=(new_directory)
|
46
48
|
raise FileNotFoundError unless File.directory?(new_directory)
|
47
|
-
|
49
|
+
|
50
|
+
reset
|
48
51
|
@directory = Dir.new File.expand_path(new_directory)
|
49
52
|
@directory.each do |file|
|
50
|
-
next if file[0,1] == '.'
|
51
|
-
|
53
|
+
next if file[0, 1] == '.'
|
54
|
+
|
55
|
+
from_file [@directory.path, file].join('/')
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
@@ -56,7 +60,8 @@ module DocumentMapper
|
|
56
60
|
documents = @documents.dup
|
57
61
|
options[:where].each do |selector, selector_value|
|
58
62
|
documents = documents.select do |document|
|
59
|
-
next unless document.attributes.
|
63
|
+
next unless document.attributes.key? selector.attribute
|
64
|
+
|
60
65
|
document_value = document.send(selector.attribute)
|
61
66
|
operator = OPERATOR_MAPPING[selector.operator]
|
62
67
|
document_value.send operator, selector_value
|
@@ -1,15 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DocumentMapper
|
2
4
|
class Query
|
3
5
|
def initialize(model)
|
4
6
|
@model = model
|
5
7
|
@where = {}
|
8
|
+
@limit = nil
|
9
|
+
@offset = nil
|
10
|
+
@order_by = nil
|
6
11
|
end
|
7
12
|
|
8
13
|
def where(constraints_hash)
|
9
|
-
selector_hash = constraints_hash.
|
10
|
-
symbol_hash = constraints_hash.reject { |key,
|
14
|
+
selector_hash = constraints_hash.select { |key, _value| key.is_a? Selector }
|
15
|
+
symbol_hash = constraints_hash.reject { |key, _value| key.is_a? Selector }
|
11
16
|
symbol_hash.each do |attribute, value|
|
12
|
-
selector = Selector.new(:
|
17
|
+
selector = Selector.new(attribute: attribute, operator: 'equal')
|
13
18
|
selector_hash.update({ selector => value })
|
14
19
|
end
|
15
20
|
@where.merge! selector_hash
|
@@ -17,7 +22,7 @@ module DocumentMapper
|
|
17
22
|
end
|
18
23
|
|
19
24
|
def order_by(field)
|
20
|
-
@order_by = field.is_a?(Symbol) ? {field => :asc} : field
|
25
|
+
@order_by = field.is_a?(Symbol) ? { field => :asc } : field
|
21
26
|
self
|
22
27
|
end
|
23
28
|
|
@@ -32,21 +37,17 @@ module DocumentMapper
|
|
32
37
|
end
|
33
38
|
|
34
39
|
def first
|
35
|
-
|
40
|
+
all.first
|
36
41
|
end
|
37
42
|
|
38
43
|
def last
|
39
|
-
|
44
|
+
all.last
|
40
45
|
end
|
41
46
|
|
42
47
|
def all
|
43
|
-
result = @model.select(:
|
44
|
-
if @offset.present?
|
45
|
-
|
46
|
-
end
|
47
|
-
if @limit.present?
|
48
|
-
result = result.first(@limit)
|
49
|
-
end
|
48
|
+
result = @model.select(where: @where, order_by: @order_by)
|
49
|
+
result = result.last([result.size - @offset, 0].max) if @offset.present?
|
50
|
+
result = result.first(@limit) if @limit.present?
|
50
51
|
result
|
51
52
|
end
|
52
53
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DocumentMapper
|
2
4
|
class Selector
|
3
5
|
attr_reader :attribute, :operator
|
4
6
|
|
5
7
|
def initialize(opts = {})
|
6
|
-
unless VALID_OPERATORS.include? opts[:operator]
|
7
|
-
|
8
|
-
|
9
|
-
@
|
8
|
+
raise OperatorNotSupportedError unless VALID_OPERATORS.include? opts[:operator]
|
9
|
+
|
10
|
+
@attribute = opts[:attribute]
|
11
|
+
@operator = opts[:operator]
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,45 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
1
5
|
module DocumentMapper
|
2
6
|
class YamlParsingError < StandardError; end
|
3
7
|
|
8
|
+
PERMITTED_CLASSES = [
|
9
|
+
Date,
|
10
|
+
Symbol
|
11
|
+
].freeze
|
12
|
+
|
4
13
|
module YamlParsing
|
5
14
|
def read_yaml
|
6
|
-
file_path =
|
7
|
-
|
15
|
+
file_path = attributes[:file_path]
|
16
|
+
file_content = File.read(file_path)
|
8
17
|
|
9
|
-
if
|
10
|
-
@content =
|
11
|
-
|
18
|
+
if file_content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
19
|
+
@content = file_content[(Regexp.last_match(1).size + Regexp.last_match(2).size)..]
|
20
|
+
attributes.update(yaml_load(Regexp.last_match(1), file_path).transform_keys(&:to_sym))
|
12
21
|
end
|
13
22
|
|
14
23
|
file_name = File.basename(file_path)
|
15
24
|
extension = File.extname(file_path)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
25
|
+
attributes.update({
|
26
|
+
file_name: file_name,
|
27
|
+
extension: extension.sub(/^\./, ''),
|
28
|
+
file_name_without_extension: File.basename(file_path, extension)
|
29
|
+
})
|
21
30
|
|
22
|
-
|
31
|
+
unless attributes.key? :date
|
23
32
|
begin
|
24
33
|
match = attributes[:file_name].match(/(\d{4})-(\d{1,2})-(\d{1,2}).*/)
|
25
|
-
year
|
26
|
-
|
27
|
-
|
34
|
+
year = match[1].to_i
|
35
|
+
month = match[2].to_i
|
36
|
+
day = match[3].to_i
|
37
|
+
attributes[:date] = ::Date.new(year, month, day)
|
38
|
+
rescue NoMethodError
|
28
39
|
end
|
29
40
|
end
|
30
41
|
|
31
|
-
if
|
32
|
-
|
33
|
-
|
34
|
-
|
42
|
+
if attributes.key? :date
|
43
|
+
attributes[:year] = attributes[:date].year
|
44
|
+
attributes[:month] = attributes[:date].month
|
45
|
+
attributes[:day] = attributes[:date].day
|
35
46
|
end
|
36
47
|
|
37
|
-
self.class.define_attribute_methods
|
38
|
-
|
48
|
+
self.class.define_attribute_methods attributes.keys
|
49
|
+
attributes.each_key { |attr| self.class.define_read_method attr }
|
39
50
|
end
|
40
51
|
|
41
52
|
def yaml_load(yaml, file)
|
42
|
-
YAML.
|
53
|
+
YAML.safe_load(yaml, permitted_classes: PERMITTED_CLASSES)
|
43
54
|
rescue ArgumentError, Psych::SyntaxError
|
44
55
|
raise YamlParsingError, "Unable to parse YAML of #{file}"
|
45
56
|
end
|
data/lib/document_mapper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_base'
|
2
4
|
include DocumentMapper
|
3
5
|
|
@@ -9,16 +11,14 @@ describe Symbol do
|
|
9
11
|
end
|
10
12
|
|
11
13
|
it 'should not raise an error on valid operators' do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
assert false, 'Calling operator on symbol raised error'
|
21
|
-
end
|
14
|
+
:my_attribute.equal
|
15
|
+
:my_attribute.gt
|
16
|
+
:my_attribute.gte
|
17
|
+
:my_attribute.in
|
18
|
+
:my_attribute.lt
|
19
|
+
:my_attribute.lte
|
20
|
+
rescue StandardError
|
21
|
+
assert false, 'Calling operator on symbol raised error'
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'should raise an error on invalid operators' do
|
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_base'
|
2
4
|
include DocumentMapper
|
3
5
|
|
4
6
|
describe MyDocument do
|
5
7
|
before do
|
8
|
+
MyDocument.directory = 'test/documents'
|
6
9
|
MyDocument.reset
|
7
10
|
end
|
8
11
|
|
@@ -67,17 +70,17 @@ describe MyDocument do
|
|
67
70
|
|
68
71
|
it 'should not freak out if there is no date' do
|
69
72
|
@document = sample_document_without_date
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
73
|
+
assert_nil @document.date
|
74
|
+
assert_nil @document.year
|
75
|
+
assert_nil @document.month
|
76
|
+
assert_nil @document.day
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
80
|
describe 'loading a documents directory' do
|
78
81
|
it 'should load all the documents in that directory' do
|
79
82
|
MyDocument.directory = 'test/documents'
|
80
|
-
assert_equal_set [1,2,3,4], MyDocument.all.map(&:id)
|
83
|
+
assert_equal_set [1, 2, 3, 4], MyDocument.all.map(&:id)
|
81
84
|
end
|
82
85
|
|
83
86
|
it 'should ignore all dotfile' do
|
@@ -111,15 +114,15 @@ describe MyDocument do
|
|
111
114
|
end
|
112
115
|
|
113
116
|
it 'should limit the documents to the number specified' do
|
114
|
-
assert_equal_set [1,2], MyDocument.order_by(:id).limit(2).all.map(&:id)
|
117
|
+
assert_equal_set [1, 2], MyDocument.order_by(:id).limit(2).all.map(&:id)
|
115
118
|
end
|
116
119
|
|
117
120
|
it 'should offset the documents by the number specified' do
|
118
|
-
assert_equal_set [3,4], MyDocument.order_by(:id).offset(2).all.map(&:id)
|
121
|
+
assert_equal_set [3, 4], MyDocument.order_by(:id).offset(2).all.map(&:id)
|
119
122
|
end
|
120
123
|
|
121
124
|
it 'should support offset and limit at the same time' do
|
122
|
-
assert_equal_set [2,3], MyDocument.order_by(:id).offset(1).limit(2).all.map(&:id)
|
125
|
+
assert_equal_set [2, 3], MyDocument.order_by(:id).offset(1).limit(2).all.map(&:id)
|
123
126
|
end
|
124
127
|
|
125
128
|
it 'should not freak out about an offset higher than the document count' do
|
@@ -145,71 +148,71 @@ describe MyDocument do
|
|
145
148
|
|
146
149
|
describe 'with an equal operator' do
|
147
150
|
it 'should return the right documents' do
|
148
|
-
found_document = MyDocument.where(:
|
151
|
+
found_document = MyDocument.where(title: @document_1.title).first
|
149
152
|
assert_equal @document_1, found_document
|
150
|
-
found_document = MyDocument.where(:
|
153
|
+
found_document = MyDocument.where(title: @document_2.title).first
|
151
154
|
assert_equal @document_2, found_document
|
152
155
|
end
|
153
156
|
|
154
157
|
it 'should be chainable' do
|
155
|
-
document_proxy = MyDocument.where(:
|
156
|
-
document_proxy.where(:
|
158
|
+
document_proxy = MyDocument.where(title: @document_1.title)
|
159
|
+
document_proxy.where(id: @document_1.id)
|
157
160
|
assert_equal @document_1, document_proxy.first
|
158
161
|
end
|
159
162
|
|
160
163
|
it 'should work with file names without extensions' do
|
161
164
|
file_name = '2010-08-08-test-document-file'
|
162
|
-
selector_hash = { :
|
165
|
+
selector_hash = { file_name_without_extension: file_name }
|
163
166
|
found_document = MyDocument.where(selector_hash).first
|
164
167
|
assert_equal sample_document_1, found_document
|
165
168
|
end
|
166
169
|
|
167
170
|
it 'should work with file names' do
|
168
171
|
file_name = '2010-08-08-test-document-file.textile'
|
169
|
-
found_document = MyDocument.where(:
|
172
|
+
found_document = MyDocument.where(file_name: file_name).first
|
170
173
|
assert_equal sample_document_1, found_document
|
171
174
|
end
|
172
175
|
|
173
176
|
it 'should work with dates' do
|
174
|
-
found_documents = MyDocument.where(:
|
177
|
+
found_documents = MyDocument.where(year: 2010).all
|
175
178
|
expected_documents = [sample_document_1, sample_document_2]
|
176
179
|
assert_equal_set expected_documents.map(&:id), found_documents.map(&:id)
|
177
180
|
end
|
178
181
|
|
179
182
|
it 'should not be confused by attributes not present in all documents' do
|
180
183
|
MyDocument.directory = 'test/documents'
|
181
|
-
result = MyDocument.where(:
|
184
|
+
result = MyDocument.where(seldom_attribute: 'is seldom').all
|
182
185
|
assert_equal_set [4], result.map(&:id)
|
183
186
|
end
|
184
187
|
end
|
185
188
|
|
186
189
|
describe 'with a gt operator' do
|
187
190
|
it 'should return the right documents' do
|
188
|
-
selector = Selector.new :
|
191
|
+
selector = Selector.new attribute: :id, operator: 'gt'
|
189
192
|
found_documents = MyDocument.where(selector => 2).all
|
190
|
-
assert_equal_set [3,4], found_documents.map(&:id)
|
193
|
+
assert_equal_set [3, 4], found_documents.map(&:id)
|
191
194
|
end
|
192
195
|
end
|
193
196
|
|
194
197
|
describe 'with a gte operator' do
|
195
198
|
it 'should return the right documents' do
|
196
|
-
selector = Selector.new :
|
199
|
+
selector = Selector.new attribute: :id, operator: 'gte'
|
197
200
|
found_documents = MyDocument.where(selector => 2).all
|
198
|
-
assert_equal_set [2,3,4], found_documents.map(&:id)
|
201
|
+
assert_equal_set [2, 3, 4], found_documents.map(&:id)
|
199
202
|
end
|
200
203
|
end
|
201
204
|
|
202
205
|
describe 'with an in operator' do
|
203
206
|
it 'should return the right documents' do
|
204
|
-
selector = Selector.new :
|
205
|
-
found_documents = MyDocument.where(selector => [2,3]).all
|
206
|
-
assert_equal_set [2,3], found_documents.map(&:id)
|
207
|
+
selector = Selector.new attribute: :id, operator: 'in'
|
208
|
+
found_documents = MyDocument.where(selector => [2, 3]).all
|
209
|
+
assert_equal_set [2, 3], found_documents.map(&:id)
|
207
210
|
end
|
208
211
|
end
|
209
212
|
|
210
213
|
describe 'with an lt operator' do
|
211
214
|
it 'should return the right documents' do
|
212
|
-
selector = Selector.new :
|
215
|
+
selector = Selector.new attribute: :id, operator: 'lt'
|
213
216
|
found_documents = MyDocument.where(selector => 2).all
|
214
217
|
assert_equal_set [1], found_documents.map(&:id)
|
215
218
|
end
|
@@ -217,25 +220,25 @@ describe MyDocument do
|
|
217
220
|
|
218
221
|
describe 'with an lte operator' do
|
219
222
|
it 'should return the right documents' do
|
220
|
-
selector = Selector.new :
|
223
|
+
selector = Selector.new attribute: :id, operator: 'lte'
|
221
224
|
found_documents = MyDocument.where(selector => 2).all
|
222
|
-
assert_equal_set [1,2], found_documents.map(&:id)
|
225
|
+
assert_equal_set [1, 2], found_documents.map(&:id)
|
223
226
|
end
|
224
227
|
end
|
225
228
|
|
226
229
|
describe 'with an include operator' do
|
227
230
|
it 'include should return the right documents' do
|
228
|
-
selector = Selector.new :
|
231
|
+
selector = Selector.new attribute: :tags, operator: 'include'
|
229
232
|
found_documents = MyDocument.where(selector => 'ruby').all
|
230
|
-
assert_equal_set [1,2], found_documents.map(&:id)
|
233
|
+
assert_equal_set [1, 2], found_documents.map(&:id)
|
231
234
|
end
|
232
235
|
end
|
233
236
|
|
234
237
|
describe 'with mixed operators' do
|
235
238
|
it 'should return the right documents' do
|
236
|
-
in_selector = Selector.new :
|
237
|
-
gt_selector = Selector.new :
|
238
|
-
documents_proxy = MyDocument.where(in_selector => [2,3])
|
239
|
+
in_selector = Selector.new attribute: :id, operator: 'in'
|
240
|
+
gt_selector = Selector.new attribute: :id, operator: 'gt'
|
241
|
+
documents_proxy = MyDocument.where(in_selector => [2, 3])
|
239
242
|
found_documents = documents_proxy.where(gt_selector => 2).all
|
240
243
|
assert_equal_set [3], found_documents.map(&:id)
|
241
244
|
end
|
@@ -243,9 +246,9 @@ describe MyDocument do
|
|
243
246
|
|
244
247
|
describe 'using multiple constrains in one where' do
|
245
248
|
it 'should return the right documents' do
|
246
|
-
selector = Selector.new :
|
249
|
+
selector = Selector.new attribute: :id, operator: 'lte'
|
247
250
|
found_documents = MyDocument.where(selector => 2, :status => :published).all
|
248
|
-
assert_equal_set [1,2], found_documents.map(&:id)
|
251
|
+
assert_equal_set [1, 2], found_documents.map(&:id)
|
249
252
|
end
|
250
253
|
end
|
251
254
|
end
|
@@ -256,41 +259,39 @@ describe MyDocument do
|
|
256
259
|
end
|
257
260
|
|
258
261
|
it 'should support ordering by attribute ascending' do
|
259
|
-
found_documents = MyDocument.order_by(:
|
260
|
-
assert_equal [2,3,1,4], found_documents.map(&:id)
|
262
|
+
found_documents = MyDocument.order_by(title: :asc).all
|
263
|
+
assert_equal [2, 3, 1, 4], found_documents.map(&:id)
|
261
264
|
end
|
262
265
|
|
263
266
|
it 'should support ordering by attribute descending' do
|
264
|
-
found_documents = MyDocument.order_by(:
|
265
|
-
assert_equal [4,1,3,2], found_documents.map(&:id)
|
267
|
+
found_documents = MyDocument.order_by(title: :desc).all
|
268
|
+
assert_equal [4, 1, 3, 2], found_documents.map(&:id)
|
266
269
|
end
|
267
270
|
|
268
271
|
it 'should order by attribute ascending by default' do
|
269
272
|
found_documents = MyDocument.order_by(:title).all
|
270
|
-
assert_equal [2,3,1,4], found_documents.map(&:id)
|
273
|
+
assert_equal [2, 3, 1, 4], found_documents.map(&:id)
|
271
274
|
end
|
272
275
|
|
273
276
|
it 'should exclude documents that do not own the attribute' do
|
274
277
|
found_documents = MyDocument.order_by(:status).all
|
275
|
-
assert_equal [1,2].to_set, found_documents.map(&:id).to_set
|
278
|
+
assert_equal [1, 2].to_set, found_documents.map(&:id).to_set
|
276
279
|
end
|
277
280
|
end
|
278
281
|
|
279
282
|
describe 'reloading the Document class' do
|
280
283
|
it 'should discover new documents' do
|
281
284
|
@file_path = 'test/documents/2011-04-26-new-stuff.textile'
|
282
|
-
File.
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
EOS
|
291
|
-
end
|
285
|
+
File.write(@file_path, <<~DOCUMENT)
|
286
|
+
---
|
287
|
+
id: 5
|
288
|
+
title: Some brand new document
|
289
|
+
---
|
290
|
+
|
291
|
+
Very new stuff.
|
292
|
+
DOCUMENT
|
292
293
|
MyDocument.reload
|
293
|
-
assert_equal [1,2,3,4,5].sort, MyDocument.all.map(&:id).sort
|
294
|
+
assert_equal [1, 2, 3, 4, 5].sort, MyDocument.all.map(&:id).sort
|
294
295
|
end
|
295
296
|
|
296
297
|
def teardown
|
@@ -304,7 +305,7 @@ EOS
|
|
304
305
|
end
|
305
306
|
|
306
307
|
it 'should return an ordered list of all the attributes' do
|
307
|
-
expected_attributes = %w
|
308
|
+
expected_attributes = %w[
|
308
309
|
date
|
309
310
|
day
|
310
311
|
extension
|
@@ -320,7 +321,7 @@ EOS
|
|
320
321
|
tags
|
321
322
|
title
|
322
323
|
year
|
323
|
-
|
324
|
+
].map(&:to_sym)
|
324
325
|
assert_equal expected_attributes, MyDocument.attributes
|
325
326
|
end
|
326
327
|
end
|
@@ -338,21 +339,9 @@ EOS
|
|
338
339
|
|
339
340
|
describe 'loading a document with invalid yaml' do
|
340
341
|
it 'should raise with a decent error message' do
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
---
|
345
|
-
title: Look: Invalid YAML!
|
346
|
-
---
|
347
|
-
|
348
|
-
This is definitely gonna blow up.
|
349
|
-
EOS
|
350
|
-
end
|
351
|
-
proc { MyDocument.reload }.must_raise(DocumentMapper::YamlParsingError, "Unable to parse YAML of #{@file_path}")
|
352
|
-
end
|
353
|
-
|
354
|
-
def teardown
|
355
|
-
File.delete @file_path
|
342
|
+
_ do
|
343
|
+
MyDocument.directory = 'test/documents_with_invalid_yaml'
|
344
|
+
end.must_raise(DocumentMapper::YamlParsingError, "Unable to parse YAML of #{@file_path}")
|
356
345
|
end
|
357
346
|
end
|
358
347
|
|
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_base'
|
2
4
|
include DocumentMapper
|
3
5
|
|
4
6
|
describe Selector do
|
5
7
|
it 'should initialize with an attribute and an operator' do
|
6
|
-
selector = Selector.new :
|
8
|
+
selector = Selector.new attribute: :author, operator: 'equal'
|
7
9
|
assert_equal :author, selector.attribute
|
8
10
|
assert_equal 'equal', selector.operator
|
9
11
|
end
|
10
12
|
|
11
13
|
it 'should raise an exception if the operator is not supported' do
|
12
14
|
assert_raises OperatorNotSupportedError do
|
13
|
-
|
15
|
+
Selector.new attribute: :author, operator: 'zomg'
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
data/test/test_base.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'bundler/setup'
|
3
5
|
require 'set'
|
4
|
-
require 'minitest/
|
5
|
-
MiniTest
|
6
|
+
require 'minitest/autorun'
|
7
|
+
MiniTest.autorun
|
6
8
|
|
7
9
|
lib_dir = File.join(File.dirname(__FILE__), '..', 'lib')
|
8
10
|
$LOAD_PATH.unshift lib_dir unless $LOAD_PATH.include?(lib_dir)
|
9
11
|
require 'document_mapper'
|
10
12
|
|
13
|
+
# Prevent verbose warnings
|
14
|
+
# $VERBOSE = nil
|
15
|
+
|
11
16
|
class MyDocument
|
12
17
|
include DocumentMapper::Document
|
13
18
|
end
|
@@ -16,9 +21,11 @@ class MyOtherDocument
|
|
16
21
|
include DocumentMapper::Document
|
17
22
|
end
|
18
23
|
|
19
|
-
module MiniTest
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
module MiniTest
|
25
|
+
module Assertions
|
26
|
+
def assert_equal_set(exp, act, msg = nil)
|
27
|
+
msg = message(msg) { "Expected #{mu_pp(exp)}, not #{mu_pp(act)}" }
|
28
|
+
assert(exp.to_set == act.to_set, msg)
|
29
|
+
end
|
23
30
|
end
|
24
31
|
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: document_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ralph von der Heyden
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activemodel
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: debug
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -94,6 +94,34 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: RedCloth
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
97
125
|
description: " DocumentMapper is an object mapper for plain text documents. The documents
|
98
126
|
look like the ones used in jekyll (http://github.com/mojombo/jekyll). They consist
|
99
127
|
of a preambel written in YAML (also called YAML front matter), and some content
|
@@ -125,12 +153,15 @@ files:
|
|
125
153
|
- test/documents/2010-08-09-another-test-document.textile
|
126
154
|
- test/documents/document_with_date_in_yaml.textile
|
127
155
|
- test/documents/document_without_date.textile
|
156
|
+
- test/documents_with_invalid_yaml/2010-08-08-test-document-file.textile
|
157
|
+
- test/documents_with_invalid_yaml/invalid_yaml.textile
|
128
158
|
- test/other_documents/2011-12-26-some-test-document.textile
|
129
159
|
- test/test_base.rb
|
130
160
|
homepage: http://github.com/ralph/document_mapper
|
131
161
|
licenses: []
|
132
|
-
metadata:
|
133
|
-
|
162
|
+
metadata:
|
163
|
+
rubygems_mfa_required: 'true'
|
164
|
+
post_install_message:
|
134
165
|
rdoc_options: []
|
135
166
|
require_paths:
|
136
167
|
- lib
|
@@ -138,15 +169,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
138
169
|
requirements:
|
139
170
|
- - ">="
|
140
171
|
- !ruby/object:Gem::Version
|
141
|
-
version:
|
172
|
+
version: 2.6.0
|
142
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
174
|
requirements:
|
144
175
|
- - ">="
|
145
176
|
- !ruby/object:Gem::Version
|
146
177
|
version: '0'
|
147
178
|
requirements: []
|
148
|
-
rubygems_version: 3.
|
149
|
-
signing_key:
|
150
|
-
specification_version:
|
179
|
+
rubygems_version: 3.3.7
|
180
|
+
signing_key:
|
181
|
+
specification_version: 4
|
151
182
|
summary: DocumentMapper is an object mapper for plain text documents.
|
152
183
|
test_files: []
|