document_mapper 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|