document_file 0.0.3 → 0.0.4
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.
- data/Gemfile +1 -0
- data/Gemfile.lock +16 -0
- data/README.textile +100 -0
- data/lib/document_file/base.rb +5 -71
- data/lib/document_file/collection.rb +103 -0
- data/lib/document_file/version.rb +1 -1
- data/lib/document_file.rb +1 -0
- data/test/document_file_collection_test.rb +72 -0
- data/test/document_file_test.rb +48 -30
- data/test/documents/2010-08-08-test-document-file.textile +1 -0
- data/test/documents/2010-08-09-oink-post.textile +1 -0
- data/test/test_base.rb +12 -0
- metadata +10 -5
- data/README +0 -52
data/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gemspec :path => '.'
|
data/Gemfile.lock
ADDED
data/README.textile
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
h1. Document File
|
2
|
+
|
3
|
+
An attempt to create a simple model layer that abstracts flat text files. Text files look like the ones used in "jekyll":http://github.com/mojombo/jekyll. They consist of a preambel written in YAML (also called YAML front matter), and some content in the format you prefer, e.g. Textile.
|
4
|
+
|
5
|
+
|
6
|
+
h2. Example
|
7
|
+
|
8
|
+
As an example let's assume we have a directory called "documents" containing the following files:
|
9
|
+
|
10
|
+
<pre><code>
|
11
|
+
documents/
|
12
|
+
|-foo.textile
|
13
|
+
|-bar.textile
|
14
|
+
</code></pre>
|
15
|
+
|
16
|
+
Documents look somehow like this. The part between the @---@s is the YAML front matter. After the second @---@, there is one blank line, followed by the content of the file. All items in the YAML front matter and the content are accessible by Document File.
|
17
|
+
|
18
|
+
<pre><code>
|
19
|
+
---
|
20
|
+
id: 1
|
21
|
+
title: The shizzle!
|
22
|
+
tags: [tag]
|
23
|
+
number_of_foos: 42
|
24
|
+
status: published
|
25
|
+
---
|
26
|
+
|
27
|
+
I like the flowers.
|
28
|
+
</code></pre>
|
29
|
+
|
30
|
+
|
31
|
+
In order to access the documents in the folder, you have to create a document class that inherits from @DocumentFile::Base@. Inside the class definition, you must set the @documents_dir@ class variable in order to tell Document File where to look for files. In our little example, we will do the following:
|
32
|
+
|
33
|
+
<pre><code>
|
34
|
+
class MyDocument < DocumentFile::Base
|
35
|
+
self.documents_dir = './documents'
|
36
|
+
end
|
37
|
+
</code></pre>
|
38
|
+
|
39
|
+
|
40
|
+
h2. Available functionality
|
41
|
+
|
42
|
+
h3. Dynamic finders
|
43
|
+
|
44
|
+
<pre><code>
|
45
|
+
doc = MyDocument.find_by_title("The shizzle!") # => returns the document
|
46
|
+
doc = MyDocument.find_by_number_of_foos(42) # => returns the document
|
47
|
+
doc = MyDocument.find_by_file_name("foo.textile") # => returns the document
|
48
|
+
|
49
|
+
docs = MyDocument.find_all_by_status("published") # => [doc_1, doc2, ...]
|
50
|
+
docs = MyDocument.find_all_by_tag("tag") # => [doc_1, doc2, ...]
|
51
|
+
</code></pre>
|
52
|
+
|
53
|
+
h3. Listing documents by Array attributes
|
54
|
+
|
55
|
+
<pre><code>
|
56
|
+
docs = MyDocument.by_tags
|
57
|
+
# => Returns {"tag" => [doc_1, doc2, ...], "tag_2" => [doc_1, doc_3, ...], ...}
|
58
|
+
</code></pre>
|
59
|
+
|
60
|
+
h3. Chaining
|
61
|
+
|
62
|
+
<pre><code>
|
63
|
+
docs = MyDocument.find_all_by_status("published").by_tags
|
64
|
+
# => Returns {"tag" => [doc_1, doc2, ...], ...}
|
65
|
+
docs = MyDocument.find_all_by_status("published").find_all_by_tag("tag")
|
66
|
+
# => Returns [doc_1, doc2, ...]
|
67
|
+
</code></pre>
|
68
|
+
|
69
|
+
|
70
|
+
h3. Accessing the attributes of single documents
|
71
|
+
|
72
|
+
<pre><code>
|
73
|
+
doc.title # => "The shizzle!"
|
74
|
+
doc.tags # => ["tag"]
|
75
|
+
doc.content # => "I like the flowers."
|
76
|
+
doc.filename # => "foo"
|
77
|
+
doc.file_name_with_extension # => "foo.textile"
|
78
|
+
doc.file_extension # => ".textile"
|
79
|
+
</code></pre>
|
80
|
+
|
81
|
+
h3. Initializing single documents
|
82
|
+
|
83
|
+
This will even work without setting the @documents_dir@ class variable.
|
84
|
+
|
85
|
+
<pre><code>
|
86
|
+
doc = MyDocument.new('./documents/document-file.textile')
|
87
|
+
</code></pre>
|
88
|
+
|
89
|
+
h3. Reloading
|
90
|
+
|
91
|
+
If any of the files change, you must manually reload them:
|
92
|
+
<pre><code>
|
93
|
+
MyDocument.reload!
|
94
|
+
</code></pre>
|
95
|
+
|
96
|
+
|
97
|
+
h2. Author
|
98
|
+
|
99
|
+
Written by "Ralph von der Heyden":http://rvdh.de. Don't hesitate to contact me if you have any further questions.
|
100
|
+
Follow me on "Twitter":http://twitter.com/ralph.
|
data/lib/document_file/base.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
require 'yaml'
|
2
|
-
require 'active_support/inflector'
|
3
2
|
|
4
3
|
module DocumentFile
|
5
4
|
class Base
|
6
5
|
@@documents_dir = './documents'
|
7
6
|
@@documents = nil
|
8
|
-
attr_reader :content, :file_path
|
7
|
+
attr_reader :content, :file_path, :data
|
9
8
|
|
10
9
|
def initialize(new_file_path)
|
11
10
|
@file_path = new_file_path
|
12
|
-
define_attribute_finder('file_name')
|
13
11
|
read_yaml
|
14
12
|
end
|
15
13
|
|
@@ -33,7 +31,7 @@ module DocumentFile
|
|
33
31
|
def self.reload!
|
34
32
|
if File.directory?(@@documents_dir)
|
35
33
|
file_paths = Dir.glob("#{@@documents_dir}/*.*")
|
36
|
-
@@documents = file_paths.map { |file_path| self.new file_path }
|
34
|
+
@@documents = Collection.new file_paths.map { |file_path| self.new file_path }
|
37
35
|
else
|
38
36
|
[]
|
39
37
|
end
|
@@ -61,77 +59,13 @@ module DocumentFile
|
|
61
59
|
|
62
60
|
def define_dynamic_methods
|
63
61
|
@data.each do |attribute_name, value|
|
64
|
-
|
65
|
-
self.class.
|
66
|
-
|
67
|
-
if value.is_a? Array
|
68
|
-
define_by_attribute_finder(attribute_name)
|
69
|
-
define_find_all_by_attribute_finder(attribute_name)
|
70
|
-
end
|
71
|
-
|
72
|
-
define_attribute_finder(attribute_name)
|
62
|
+
attribute_reader = "def #{attribute_name}; @data['#{attribute_name}']; end"
|
63
|
+
self.class.module_eval attribute_reader
|
73
64
|
end
|
74
|
-
@@dynamic_methods_defined = true
|
75
|
-
end
|
76
|
-
|
77
|
-
# Defines an attribute finder, e.g.
|
78
|
-
# MyDocument.find_by_title('some_title') => some_document
|
79
|
-
def define_attribute_finder(attribute_name)
|
80
|
-
find_by_attribute_method = <<-eos
|
81
|
-
def self.find_by_#{attribute_name}(attribute)
|
82
|
-
all.detect do |document|
|
83
|
-
if document.respond_to?('#{attribute_name}')
|
84
|
-
document.#{attribute_name} == attribute
|
85
|
-
else
|
86
|
-
false
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
eos
|
91
|
-
self.class.send(:module_eval, find_by_attribute_method)
|
92
|
-
end
|
93
|
-
|
94
|
-
# Defines a by attribute finder for Array attributes, e.g.
|
95
|
-
# MyDocument.by_tags
|
96
|
-
# => {
|
97
|
-
# "tag_1" => [document_1, document_3],
|
98
|
-
# "tag_2" => [document_2]
|
99
|
-
# }
|
100
|
-
def define_by_attribute_finder(array_attribute)
|
101
|
-
by_attribute_method = <<-eos
|
102
|
-
def self.by_#{array_attribute}
|
103
|
-
documents = self.all
|
104
|
-
#{array_attribute}_items = {}
|
105
|
-
documents.each do |document|
|
106
|
-
document.#{array_attribute}.each do |single_item|
|
107
|
-
if #{array_attribute}_items.has_key? single_item
|
108
|
-
#{array_attribute}_items[single_item] << document
|
109
|
-
else
|
110
|
-
#{array_attribute}_items[single_item] = [document]
|
111
|
-
end
|
112
|
-
end if document.#{array_attribute}
|
113
|
-
end
|
114
|
-
#{array_attribute}_items
|
115
|
-
end
|
116
|
-
eos
|
117
|
-
self.class.send(:module_eval, by_attribute_method)
|
118
|
-
end
|
119
|
-
|
120
|
-
# Finds documents by a specific Array attribute value , e.g.
|
121
|
-
# MyDocument.find_all_by_tag('my_tag') => [document_1, document_2, ...]
|
122
|
-
def define_find_all_by_attribute_finder(array_attribute)
|
123
|
-
singular_array_attribute = ActiveSupport::Inflector.singularize array_attribute
|
124
|
-
find_all_by_attribute_method = <<-eos
|
125
|
-
def self.find_all_by_#{singular_array_attribute}(singular_array_attribute)
|
126
|
-
self.by_#{array_attribute}[singular_array_attribute]
|
127
|
-
end
|
128
|
-
eos
|
129
|
-
self.class.send(:module_eval, find_all_by_attribute_method)
|
130
65
|
end
|
131
66
|
|
132
67
|
def self.method_missing(method_name, *args)
|
133
|
-
self.all
|
134
|
-
respond_to?(method_name) ? self.send(method_name, *args) : super
|
68
|
+
self.all.respond_to?(method_name) ? self.all.send(method_name, *args) : super
|
135
69
|
end
|
136
70
|
end
|
137
71
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module DocumentFile
|
4
|
+
class Collection < Array
|
5
|
+
def <<(document)
|
6
|
+
self.class.ensure_document(document)
|
7
|
+
define_dynamic_finders document.data
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def new_with_finders(*args)
|
13
|
+
collection = new_without_finders(*args)
|
14
|
+
collection.each do |document|
|
15
|
+
self.ensure_document(document)
|
16
|
+
attributes_hash = document.data.merge({'file_name' => document.file_name})
|
17
|
+
collection.define_dynamic_finders attributes_hash
|
18
|
+
end
|
19
|
+
collection
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :new_without_finders, :new
|
23
|
+
alias_method :new, :new_with_finders
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.ensure_document(document)
|
27
|
+
raise ArgumentError unless document.is_a? DocumentFile::Base
|
28
|
+
end
|
29
|
+
|
30
|
+
def define_dynamic_finders(attributes_hash)
|
31
|
+
attributes_hash.each do |attribute, value|
|
32
|
+
define_find_all_by attribute, value
|
33
|
+
define_find_by attribute
|
34
|
+
|
35
|
+
define_by_array_attribute(attribute) if value.is_a? Array
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Defines a by attribute finder for Array attributes, e.g.
|
40
|
+
# MyDocument.by_tags
|
41
|
+
# => {
|
42
|
+
# "tag_1" => [document_1, document_3],
|
43
|
+
# "tag_2" => [document_2]
|
44
|
+
# }
|
45
|
+
def define_by_array_attribute(array_attribute)
|
46
|
+
by_attribute = <<-eos
|
47
|
+
def by_#{array_attribute}
|
48
|
+
#{array_attribute}_items = {}
|
49
|
+
each do |document|
|
50
|
+
document.#{array_attribute}.each do |single_item|
|
51
|
+
if #{array_attribute}_items.has_key? single_item
|
52
|
+
#{array_attribute}_items[single_item] << document
|
53
|
+
else
|
54
|
+
#{array_attribute}_items[single_item] = Collection.new [document]
|
55
|
+
end
|
56
|
+
end if document.#{array_attribute}
|
57
|
+
end
|
58
|
+
#{array_attribute}_items
|
59
|
+
end
|
60
|
+
eos
|
61
|
+
instance_eval by_attribute
|
62
|
+
end
|
63
|
+
|
64
|
+
# Finds documents by a specific Array attribute value , e.g.
|
65
|
+
# MyDocument.find_all_by_tag('my_tag') => [document_1, document_2, ...]
|
66
|
+
def define_find_all_by(attribute, value)
|
67
|
+
if value.is_a? Array
|
68
|
+
singular_attribute = ActiveSupport::Inflector.singularize attribute
|
69
|
+
else
|
70
|
+
singular_attribute = attribute
|
71
|
+
end
|
72
|
+
find_all_by_attribute = <<-eos
|
73
|
+
def find_all_by_#{singular_attribute}(attribute)
|
74
|
+
if respond_to? :by_#{attribute}
|
75
|
+
by_#{attribute}[attribute]
|
76
|
+
else
|
77
|
+
documents = select do |document|
|
78
|
+
if document.respond_to? :#{attribute}
|
79
|
+
document.#{attribute} == attribute
|
80
|
+
else
|
81
|
+
false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
Collection.new documents
|
85
|
+
end
|
86
|
+
end
|
87
|
+
eos
|
88
|
+
instance_eval find_all_by_attribute
|
89
|
+
end
|
90
|
+
|
91
|
+
# Defines an attribute finder for one document, e.g.
|
92
|
+
# MyDocument.find_by_title('some_title') => some_document
|
93
|
+
def define_find_by(attribute)
|
94
|
+
find_by_attribute = <<-eos
|
95
|
+
def find_by_#{attribute}(attribute)
|
96
|
+
documents = find_all_by_#{attribute}(attribute)
|
97
|
+
documents.any? ? documents.first : nil
|
98
|
+
end
|
99
|
+
eos
|
100
|
+
instance_eval find_by_attribute
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/document_file.rb
CHANGED
@@ -0,0 +1,72 @@
|
|
1
|
+
require './test/test_base'
|
2
|
+
|
3
|
+
describe DocumentFile::Collection do
|
4
|
+
describe 'when adding documents to the collection' do
|
5
|
+
before do
|
6
|
+
@collection = DocumentFile::Collection.new
|
7
|
+
@document = MyDocument.new(
|
8
|
+
TEST_DIR + '/documents/2010-08-08-test-document-file.textile'
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should not accept non-documents' do
|
13
|
+
begin
|
14
|
+
@collection << 'some string'
|
15
|
+
rescue ArgumentError
|
16
|
+
assert true
|
17
|
+
return
|
18
|
+
end
|
19
|
+
assert false, 'collection falsely accepted a non DocumentFile datatype'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should accept documents' do
|
23
|
+
@collection << @document
|
24
|
+
assert_equal @document, @collection.first
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should define find_by_attribute finders' do
|
28
|
+
@collection << @document
|
29
|
+
attr = :find_by_title
|
30
|
+
assert @collection.respond_to?(attr), fail_msg(attr)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should define find_all_by_attribute finders' do
|
34
|
+
@collection << @document
|
35
|
+
attr = :find_all_by_status
|
36
|
+
assert @collection.respond_to?(attr), fail_msg(attr)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should define by_attribute finders for Array attributes' do
|
40
|
+
@collection << @document
|
41
|
+
attr = :by_tags
|
42
|
+
assert @collection.respond_to?(attr), fail_msg(attr)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should define find_all_by_attribute finders for Array attributes' do
|
46
|
+
@collection << @document
|
47
|
+
attr = :find_all_by_tag
|
48
|
+
assert @collection.respond_to?(attr), fail_msg(attr)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def fail_msg(failed_attribute)
|
53
|
+
"collection does not respond to #{failed_attribute}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'when creating a collection from an Array' do
|
58
|
+
it 'should not accept non-documents' do
|
59
|
+
assert_raises ArgumentError do
|
60
|
+
DocumentFile::Collection.new ['a string', 'some more']
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should accept documents' do
|
65
|
+
document = MyDocument.new(
|
66
|
+
TEST_DIR + '/documents/2010-08-08-test-document-file.textile'
|
67
|
+
)
|
68
|
+
collection = DocumentFile::Collection.new [document]
|
69
|
+
assert document, collection.first
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/test/document_file_test.rb
CHANGED
@@ -1,20 +1,8 @@
|
|
1
|
-
require '
|
2
|
-
MiniTest::Unit.autorun
|
3
|
-
require 'set'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
|
-
testdir = File.dirname(__FILE__)
|
7
|
-
libdir = File.dirname(File.dirname(__FILE__)) + '/lib'
|
8
|
-
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
9
|
-
|
10
|
-
require 'document_file'
|
11
|
-
|
12
|
-
class MyDocument < DocumentFile::Base
|
13
|
-
end
|
1
|
+
require './test/test_base'
|
14
2
|
|
15
3
|
describe MyDocument do
|
16
4
|
before do
|
17
|
-
MyDocument.documents_dir =
|
5
|
+
MyDocument.documents_dir = TEST_DIR + '/documents'
|
18
6
|
end
|
19
7
|
|
20
8
|
describe 'when finding all document_files' do
|
@@ -22,8 +10,8 @@ describe MyDocument do
|
|
22
10
|
@document_files = MyDocument.all
|
23
11
|
end
|
24
12
|
|
25
|
-
it 'should return
|
26
|
-
assert_equal
|
13
|
+
it 'should return a DocumentFile::Collection' do
|
14
|
+
assert_equal DocumentFile::Collection, @document_files.class
|
27
15
|
end
|
28
16
|
|
29
17
|
it "should find all document_files" do
|
@@ -33,19 +21,21 @@ describe MyDocument do
|
|
33
21
|
|
34
22
|
describe 'when initializing a MyDocument' do
|
35
23
|
before do
|
36
|
-
@document_file = MyDocument.new(
|
24
|
+
@document_file = MyDocument.new(
|
25
|
+
TEST_DIR + '/documents/2010-08-08-test-document-file.textile'
|
26
|
+
)
|
37
27
|
end
|
38
28
|
|
39
29
|
it 'should initialize the content' do
|
40
30
|
assert_equal "I like the flowers.\n", @document_file.content
|
41
31
|
end
|
42
32
|
|
43
|
-
it 'should intitialize
|
33
|
+
it 'should intitialize Strings from the front matter' do
|
44
34
|
assert_equal String, @document_file.title.class
|
45
35
|
assert_equal 'The shizzle!', @document_file.title
|
46
36
|
end
|
47
37
|
|
48
|
-
it 'should intitialize
|
38
|
+
it 'should intitialize Arrays from the front matter' do
|
49
39
|
assert_equal Array, @document_file.tags.class
|
50
40
|
assert_equal ['tag'], @document_file.tags
|
51
41
|
end
|
@@ -80,9 +70,10 @@ describe MyDocument do
|
|
80
70
|
end
|
81
71
|
end
|
82
72
|
|
83
|
-
describe 'when finding document_files by an Array attribute value' do
|
84
|
-
it 'should return
|
85
|
-
|
73
|
+
describe 'when finding all document_files by an Array attribute value' do
|
74
|
+
it 'should return a DocumentFile::Collection' do
|
75
|
+
klass = MyDocument.find_all_by_tag('tag').class
|
76
|
+
assert_equal DocumentFile::Collection, klass
|
86
77
|
end
|
87
78
|
|
88
79
|
it 'should containt documents' do
|
@@ -95,6 +86,29 @@ describe MyDocument do
|
|
95
86
|
end
|
96
87
|
end
|
97
88
|
|
89
|
+
describe 'when finding all document_files by an attribute value' do
|
90
|
+
before do
|
91
|
+
@collection = MyDocument.find_all_by_status(:published)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should return a DocumentFile::Collection' do
|
95
|
+
assert_equal DocumentFile::Collection, @collection.class
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should containt documents' do
|
99
|
+
assert_equal MyDocument, @collection.first.class
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should return the right documents' do
|
103
|
+
assert_equal [1, 2], @collection.map(&:id)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should return an empty collection if the document was not found' do
|
107
|
+
empty_collection = MyDocument.find_all_by_status(:draft)
|
108
|
+
assert_equal [], empty_collection.map(&:id)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
98
112
|
describe 'when finding a document_file' do
|
99
113
|
it 'should find the right document_file by an attribute' do
|
100
114
|
title = 'The shizzle!'
|
@@ -115,28 +129,31 @@ describe MyDocument do
|
|
115
129
|
end
|
116
130
|
|
117
131
|
describe 'when getting the file name or file path' do
|
132
|
+
before do
|
133
|
+
@file_path = './test/documents/2010-08-08-test-document-file.textile'
|
134
|
+
end
|
135
|
+
|
118
136
|
it 'should show the right file name' do
|
119
|
-
document_file = MyDocument.new
|
137
|
+
document_file = MyDocument.new @file_path
|
120
138
|
file_name = '2010-08-08-test-document-file'
|
121
139
|
assert_equal file_name, document_file.file_name
|
122
140
|
end
|
123
141
|
|
124
142
|
it 'should show the right file name with extension' do
|
125
|
-
document_file = MyDocument.new
|
143
|
+
document_file = MyDocument.new @file_path
|
126
144
|
file_name = '2010-08-08-test-document-file.textile'
|
127
145
|
assert_equal file_name, document_file.file_name_with_extension
|
128
146
|
end
|
129
147
|
|
130
148
|
it 'should show the right extension' do
|
131
|
-
document_file = MyDocument.new
|
149
|
+
document_file = MyDocument.new @file_path
|
132
150
|
extension = '.textile'
|
133
151
|
assert_equal extension, document_file.file_extension
|
134
152
|
end
|
135
153
|
|
136
154
|
it 'should show the right file path' do
|
137
|
-
|
138
|
-
|
139
|
-
assert_equal file_path, document_file.file_path
|
155
|
+
document_file = MyDocument.new @file_path
|
156
|
+
assert_equal @file_path, document_file.file_path
|
140
157
|
end
|
141
158
|
end
|
142
159
|
|
@@ -146,14 +163,15 @@ describe MyDocument do
|
|
146
163
|
end
|
147
164
|
|
148
165
|
it 'should throw an error on the instance level' do
|
149
|
-
|
166
|
+
file_path = './test/documents/2010-08-08-test-document-file.textile'
|
167
|
+
document_file = MyDocument.new file_path
|
150
168
|
assert_raises(NoMethodError) { document_file.hululu }
|
151
169
|
end
|
152
170
|
end
|
153
171
|
|
154
172
|
describe 'when reloading all document_files' do
|
155
173
|
before do
|
156
|
-
@default_dir =
|
174
|
+
@default_dir = TEST_DIR + '/documents'
|
157
175
|
MyDocument.documents_dir = @default_dir
|
158
176
|
MyDocument.reload!
|
159
177
|
@document_files_before = MyDocument.all
|
data/test/test_base.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
MiniTest::Unit.autorun
|
3
|
+
require 'set'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
lib_dir = File.dirname(File.dirname(__FILE__)) + '/lib'
|
7
|
+
$LOAD_PATH.unshift lib_dir unless $LOAD_PATH.include?(lib_dir)
|
8
|
+
require 'document_file'
|
9
|
+
TEST_DIR = File.dirname(__FILE__)
|
10
|
+
|
11
|
+
class MyDocument < DocumentFile::Base
|
12
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ralph von der Heyden
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-08-
|
17
|
+
date: 2010-08-26 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -41,15 +41,20 @@ extensions: []
|
|
41
41
|
extra_rdoc_files: []
|
42
42
|
|
43
43
|
files:
|
44
|
-
-
|
45
|
-
-
|
44
|
+
- Gemfile
|
45
|
+
- Gemfile.lock
|
46
46
|
- LICENSE
|
47
|
+
- README.textile
|
48
|
+
- Rakefile
|
47
49
|
- lib/document_file/base.rb
|
50
|
+
- lib/document_file/collection.rb
|
48
51
|
- lib/document_file/version.rb
|
49
52
|
- lib/document_file.rb
|
53
|
+
- test/document_file_collection_test.rb
|
50
54
|
- test/document_file_test.rb
|
51
55
|
- test/documents/2010-08-08-test-document-file.textile
|
52
56
|
- test/documents/2010-08-09-oink-post.textile
|
57
|
+
- test/test_base.rb
|
53
58
|
has_rdoc: true
|
54
59
|
homepage: http://github.com/ralph/document_file
|
55
60
|
licenses: []
|
data/README
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
Document File
|
2
|
-
-------------
|
3
|
-
|
4
|
-
An attempt to create a simple model layer that abstracts flat text files.
|
5
|
-
|
6
|
-
Text files look like the ones used by jekyll (see
|
7
|
-
http://github.com/mojombo/jekyll). They consist of a preambel written in YAML
|
8
|
-
(also called YAML front matter), and some content in the format you prefer,
|
9
|
-
e.g. Textile. Example:
|
10
|
-
|
11
|
-
documents/
|
12
|
-
|-foo.textile
|
13
|
-
|-bar.textile
|
14
|
-
|
15
|
-
!!!document starts in the following line.
|
16
|
-
---
|
17
|
-
id: 1
|
18
|
-
title: The shizzle!
|
19
|
-
tags: [tag]
|
20
|
-
number_of_foos: 42
|
21
|
-
---
|
22
|
-
|
23
|
-
I like the flowers.
|
24
|
-
!!!document ends in the previous line.
|
25
|
-
|
26
|
-
Can be abstracted like this:
|
27
|
-
|
28
|
-
class MyDocument < DocumentFile::Base
|
29
|
-
self.documents_dir = './documents'
|
30
|
-
end
|
31
|
-
|
32
|
-
# You now have dynamic finders:
|
33
|
-
doc = MyDocument.find_by_title("The shizzle!") # => returns the document
|
34
|
-
doc = MyDocument.find_by_number_of_foos(42) # => returns the document
|
35
|
-
doc = MyDocument.find_by_file_name('foo.textile') # => returns the document
|
36
|
-
|
37
|
-
# You can list documents by Array attributes
|
38
|
-
docs = MyDocument.by_tags # => Returns {"tag" => [doc_1, doc2, ...], ...}
|
39
|
-
|
40
|
-
# You can access the attributes of single documents:
|
41
|
-
doc.title # => "The shizzle!"
|
42
|
-
doc.tags # => ["tag"]
|
43
|
-
doc.content # => "I like the flowers."
|
44
|
-
doc.filename # => returns the filename without extension
|
45
|
-
doc.file_name_with_extension # => does what it says
|
46
|
-
doc.file_extension # => does what it says
|
47
|
-
|
48
|
-
# You can initialize single documents, too:
|
49
|
-
doc = MyDocument.new('./documents/document-file.textile')
|
50
|
-
|
51
|
-
# If any of the files change, you must manually reload them:
|
52
|
-
MyDocument.reload!
|