data_doc 0.1.0 → 0.2.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.
- data/History.txt +11 -0
- data/README.rdoc +6 -5
- data/lib/data_doc.rb +1 -2
- data/lib/data_doc/cli.rb +7 -2
- data/lib/data_doc/document.rb +36 -8
- data/lib/data_doc/present.rb +61 -14
- data/lib/data_doc/store.rb +83 -9
- data/test/test_data_doc_cli.rb +8 -0
- data/test/test_data_doc_document.rb +43 -8
- data/test/test_data_doc_present.rb +61 -0
- data/test/test_data_doc_store.rb +33 -6
- metadata +3 -3
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
=== 0.2.0 2012-10-25
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
* Generates PDF (using prince)
|
5
|
+
|
6
|
+
* 1 minor enhancement:
|
7
|
+
* Improved examples
|
8
|
+
|
9
|
+
* 1 known issue:
|
10
|
+
* ERB processing under $SAFE = 4 unavailable
|
11
|
+
|
1
12
|
=== 0.1.0 2012-10-23
|
2
13
|
|
3
14
|
* 2 major enhancements:
|
data/README.rdoc
CHANGED
@@ -5,10 +5,10 @@
|
|
5
5
|
== DEVELOPMENT STATUS:
|
6
6
|
|
7
7
|
Generates html from markdown files containing erb, including layout and
|
8
|
-
headers. DSL in place for stores, attributes and simple tables
|
9
|
-
|
8
|
+
headers. DSL in place for stores, attributes and simple tables, but no
|
9
|
+
alternate keys. Error messages are raw, fit for technical only.
|
10
10
|
|
11
|
-
{<img src="https://secure.travis-ci.org/alilee/data_doc.png" alt="Build Status" />}[http://travis-ci.org/alilee/data_doc] {<img src="https://gemnasium.com/alilee/data_doc.png" alt="Dependency Status" />}[https://gemnasium.com/alilee/data_doc]
|
11
|
+
{<img src="https://secure.travis-ci.org/alilee/data_doc.png" alt="Build Status" />}[http://travis-ci.org/alilee/data_doc] {<img src="https://gemnasium.com/alilee/data_doc.png" alt="Dependency Status" />}[https://gemnasium.com/alilee/data_doc] {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/alilee/data_doc]
|
12
12
|
|
13
13
|
== DESCRIPTION:
|
14
14
|
|
@@ -24,7 +24,7 @@ Note: See security implications below.
|
|
24
24
|
* Main document is Markdown for convenient content authoring.
|
25
25
|
* Builds up data in relational database, facilitating review and
|
26
26
|
analysis.
|
27
|
-
* Generates HTML from Markdown.
|
27
|
+
* Generates HTML from Markdown, and pdf if {prince}[princexml.com] is available.
|
28
28
|
* Provides fine-grained control over the HTML headers, including
|
29
29
|
CSS, for the output.
|
30
30
|
* Simple DSL for capturing structured data.
|
@@ -52,7 +52,8 @@ your level of risk.
|
|
52
52
|
-r, --read-only Use data already in database rather than document data
|
53
53
|
-d, --data-only Use document data but do not change database schema
|
54
54
|
-o, --output FILENAME Put generated output in FILENAME
|
55
|
-
-f, --format TYPE Select type of output from html (default: html)
|
55
|
+
-f, --format TYPE Select type of output from html, pdf (default: html)
|
56
|
+
-p, --prince PATH Path for prince pdf generator
|
56
57
|
-v, --[no-]verbose Run verbosely
|
57
58
|
|
58
59
|
Common options:
|
data/lib/data_doc.rb
CHANGED
@@ -6,10 +6,9 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
6
6
|
#
|
7
7
|
module DataDoc
|
8
8
|
# Gem version
|
9
|
-
VERSION = '0.
|
9
|
+
VERSION = '0.2.0'
|
10
10
|
# A summary of purpose of the tool.
|
11
11
|
DESCRIPTION = 'Processes structured data embedded in a markdown document and then renders it into configurable tables.'
|
12
12
|
end
|
13
13
|
|
14
14
|
require 'data_doc/document.rb'
|
15
|
-
# require 'data_doc/table.rb'
|
data/lib/data_doc/cli.rb
CHANGED
@@ -32,9 +32,9 @@ module DataDoc
|
|
32
32
|
opts.separator "Specific options:"
|
33
33
|
|
34
34
|
opts.on("-c", "--connection FILENAME",
|
35
|
-
"Override document connection settings with FILENAME") do |
|
35
|
+
"Override document connection settings with FILENAME") do |conn_filename|
|
36
36
|
begin
|
37
|
-
doc.connection =
|
37
|
+
doc.connection = conn_filename
|
38
38
|
rescue Exception => e
|
39
39
|
stdout.puts "ERROR with connection file (#{e.message})"
|
40
40
|
return 1
|
@@ -58,6 +58,11 @@ module DataDoc
|
|
58
58
|
opts.on("-f", "--format TYPE", DataDoc::Document::OUTPUT_TYPES, "Select type of output from #{type_list} (default: #{doc.format})") do |format|
|
59
59
|
doc.format = format
|
60
60
|
end
|
61
|
+
|
62
|
+
opts.on("-p", "--prince PATH",
|
63
|
+
"Path for prince pdf generator") do |p|
|
64
|
+
doc.prince = p
|
65
|
+
end
|
61
66
|
|
62
67
|
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
63
68
|
doc.verbose = v
|
data/lib/data_doc/document.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rdiscount'
|
2
2
|
require 'erb'
|
3
|
+
require 'tempfile'
|
3
4
|
require 'data_doc/store.rb'
|
4
5
|
require 'data_doc/present.rb'
|
5
6
|
|
@@ -23,6 +24,7 @@ module DataDoc
|
|
23
24
|
#
|
24
25
|
def initialize
|
25
26
|
@format = 'html'
|
27
|
+
@prince_path = 'prince'
|
26
28
|
@verbose = false
|
27
29
|
@read_only = false
|
28
30
|
@data_only = false
|
@@ -37,7 +39,7 @@ module DataDoc
|
|
37
39
|
attr_accessor :format
|
38
40
|
|
39
41
|
# Available mime types that can be generated.
|
40
|
-
OUTPUT_TYPES = ['html']
|
42
|
+
OUTPUT_TYPES = ['html', 'pdf']
|
41
43
|
|
42
44
|
# display verbose output during processing
|
43
45
|
attr_accessor :verbose
|
@@ -75,6 +77,13 @@ module DataDoc
|
|
75
77
|
def layout=(filename)
|
76
78
|
@layout_filename = filename
|
77
79
|
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Sets path to find the pdf generator.
|
83
|
+
#
|
84
|
+
def prince=(prince_path)
|
85
|
+
@prince_path = prince_path
|
86
|
+
end
|
78
87
|
|
79
88
|
#
|
80
89
|
# :section: 2. Main function
|
@@ -94,7 +103,13 @@ module DataDoc
|
|
94
103
|
# @store.untaint
|
95
104
|
end
|
96
105
|
content_html = RDiscount.new(mark_down).to_html
|
97
|
-
wrap_in_layout(content_html)
|
106
|
+
html = wrap_in_layout(content_html)
|
107
|
+
case @format
|
108
|
+
when 'pdf'
|
109
|
+
html_to_pdf(html)
|
110
|
+
else
|
111
|
+
html
|
112
|
+
end
|
98
113
|
end
|
99
114
|
|
100
115
|
#
|
@@ -147,7 +162,7 @@ module DataDoc
|
|
147
162
|
# Adds a meta tag to the headers
|
148
163
|
#
|
149
164
|
def meta(attrs = {})
|
150
|
-
add_header "<meta #{html_attrs(attrs)}
|
165
|
+
add_header "<meta #{html_attrs(attrs)} />"
|
151
166
|
end
|
152
167
|
|
153
168
|
#
|
@@ -161,7 +176,7 @@ module DataDoc
|
|
161
176
|
# Adds a link tag to the headers
|
162
177
|
#
|
163
178
|
def link(attrs = {})
|
164
|
-
add_header "<link #{html_attrs(attrs)}
|
179
|
+
add_header "<link #{html_attrs(attrs)} />"
|
165
180
|
end
|
166
181
|
|
167
182
|
|
@@ -181,7 +196,7 @@ module DataDoc
|
|
181
196
|
# Define a table store.
|
182
197
|
#
|
183
198
|
def store(name, opts = {}, &blk)
|
184
|
-
@stores[name.to_s] = DataDoc::Store.
|
199
|
+
@stores[name.to_s] = DataDoc::Store.store(self, name, opts, &blk)
|
185
200
|
name
|
186
201
|
end
|
187
202
|
|
@@ -193,8 +208,8 @@ module DataDoc
|
|
193
208
|
# Present a table. Pass a block to set options for display.
|
194
209
|
# For more information see DataDoc::Present
|
195
210
|
#
|
196
|
-
def present(arel_or_str)
|
197
|
-
DataDoc::Present.present(self, arel_or_str)
|
211
|
+
def present(arel_or_str, &blk)
|
212
|
+
DataDoc::Present.present(self, arel_or_str, &blk)
|
198
213
|
end
|
199
214
|
|
200
215
|
protected
|
@@ -264,7 +279,20 @@ module DataDoc
|
|
264
279
|
end
|
265
280
|
end
|
266
281
|
|
267
|
-
|
282
|
+
#
|
283
|
+
# Make PDF from HTML.
|
284
|
+
#
|
285
|
+
def html_to_pdf(html)
|
286
|
+
pdf_file = Tempfile.new('prince')
|
287
|
+
pdf_file.close
|
288
|
+
html_file = Tempfile.open('prince', '.') do |f|
|
289
|
+
f.write(html)
|
290
|
+
f
|
291
|
+
end
|
292
|
+
system("#{@prince_path} -o #{pdf_file.path} #{html_file.path}")
|
293
|
+
File.read(pdf_file.path)
|
294
|
+
end
|
295
|
+
|
268
296
|
end
|
269
297
|
|
270
298
|
end
|
data/lib/data_doc/present.rb
CHANGED
@@ -10,10 +10,18 @@ module DataDoc
|
|
10
10
|
#
|
11
11
|
# Accept display options from a block. Returns html table.
|
12
12
|
#
|
13
|
+
# present 'select one, two from relation' do
|
14
|
+
# caption 'Table caption'
|
15
|
+
# column_order 'two', 'one'
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# For more table configuration options see the member functions
|
19
|
+
# of DataDoc::Present
|
20
|
+
#
|
13
21
|
def self.present(doc, arel_or_str, &blk)
|
14
22
|
rows = doc.connection.select_all(arel_or_str)
|
15
23
|
p = Present.new(doc, rows)
|
16
|
-
p.instance_eval(&blk)
|
24
|
+
p.instance_eval(&blk) unless blk.nil?
|
17
25
|
p.render
|
18
26
|
end
|
19
27
|
|
@@ -22,6 +30,10 @@ module DataDoc
|
|
22
30
|
#
|
23
31
|
# Not every field queried needs to be presented.
|
24
32
|
#
|
33
|
+
# present 'select one, two from relation' do
|
34
|
+
# column_order 'two', 'one'
|
35
|
+
# end
|
36
|
+
#
|
25
37
|
def column_order(*order)
|
26
38
|
@column_order = order
|
27
39
|
end
|
@@ -29,6 +41,10 @@ module DataDoc
|
|
29
41
|
#
|
30
42
|
# Set the caption for the table
|
31
43
|
#
|
44
|
+
# present 'select 1' do
|
45
|
+
# caption 'Table caption'
|
46
|
+
# end
|
47
|
+
#
|
32
48
|
def caption(text)
|
33
49
|
@caption = text
|
34
50
|
end
|
@@ -36,6 +52,10 @@ module DataDoc
|
|
36
52
|
#
|
37
53
|
# Rename the column heading text for a particular column.
|
38
54
|
#
|
55
|
+
# present 'select one, two from relation' do
|
56
|
+
# label 'one', 'New column heading'
|
57
|
+
# end
|
58
|
+
#
|
39
59
|
def label(column, text)
|
40
60
|
@labels[column] = text
|
41
61
|
end
|
@@ -46,17 +66,40 @@ module DataDoc
|
|
46
66
|
#
|
47
67
|
# Return nil to revert to the default behaviour.
|
48
68
|
#
|
49
|
-
|
50
|
-
|
69
|
+
# present 'select one, two from relation' do
|
70
|
+
# each_cell 'one' do |col, row|
|
71
|
+
# row[col] == 'true' ? 'Short' : 'Long'
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
def each_cell(col, &blk) # :yields: col, row
|
76
|
+
@each_cell[col] = blk
|
51
77
|
end
|
52
78
|
|
53
79
|
#
|
54
80
|
# Define a calculated column based on a block.
|
55
81
|
#
|
56
|
-
|
82
|
+
# present 'select one, two from relation' do
|
83
|
+
# calculated 'three' do |col, row|
|
84
|
+
# row['two'] == 'true' ? 'Short' : 'Long'
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
def calculated(col, &blk) # :yields: row
|
57
89
|
@calculated[col] = blk
|
58
90
|
end
|
59
91
|
|
92
|
+
#
|
93
|
+
# Suppress header row.
|
94
|
+
#
|
95
|
+
# present 'select one, two from relation' do
|
96
|
+
# no_headers
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
def no_headers
|
100
|
+
@no_headers = true
|
101
|
+
end
|
102
|
+
|
60
103
|
#
|
61
104
|
# Generate html.
|
62
105
|
#
|
@@ -64,20 +107,23 @@ module DataDoc
|
|
64
107
|
h = Builder::XmlMarkup.new
|
65
108
|
h.table {
|
66
109
|
h.caption(@caption) unless @caption.nil?
|
67
|
-
|
68
|
-
h.
|
69
|
-
|
110
|
+
unless @no_headers
|
111
|
+
h.thead {
|
112
|
+
h.tr {
|
113
|
+
@column_order.each { |c| h.th(@labels[c] || c.to_s.humanize) }
|
114
|
+
}
|
70
115
|
}
|
71
|
-
|
116
|
+
end
|
72
117
|
h.tfoot
|
73
118
|
h.tbody {
|
74
119
|
@rows.each do |r|
|
75
120
|
h.tr {
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
121
|
+
@column_order.each do |col|
|
122
|
+
r[col.to_s] = @calculated[col].call(col, r) unless @calculated[col].nil?
|
123
|
+
if @each_cell[col].nil?
|
124
|
+
h.td(r[col.to_s])
|
125
|
+
else
|
126
|
+
h.td(@each_cell[col].call(col, r) || r[col.to_s])
|
81
127
|
end
|
82
128
|
end
|
83
129
|
}
|
@@ -95,9 +141,10 @@ module DataDoc
|
|
95
141
|
@doc = doc
|
96
142
|
@rows = rows
|
97
143
|
@caption = nil
|
98
|
-
@each_cell =
|
144
|
+
@each_cell = Hash.new
|
99
145
|
@labels = Hash.new
|
100
146
|
@calculated = Hash.new
|
147
|
+
@no_headers = false
|
101
148
|
@column_order = rows.first.keys
|
102
149
|
end
|
103
150
|
|
data/lib/data_doc/store.rb
CHANGED
@@ -17,10 +17,11 @@ module DataDoc
|
|
17
17
|
# schema definition. Table is re-created and emptied unless
|
18
18
|
# read_only, and just emptied if data_only.
|
19
19
|
#
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def self.store(doc, table_name_or_sym, opts = {}, &blk) # :yields:
|
21
|
+
s = Store.new(doc)
|
22
|
+
s.create_store(table_name_or_sym, opts)
|
23
|
+
s.instance_eval(&blk) unless blk.nil?
|
24
|
+
s
|
24
25
|
end
|
25
26
|
|
26
27
|
# AREL object encapsulating table.
|
@@ -29,6 +30,11 @@ module DataDoc
|
|
29
30
|
#
|
30
31
|
# Define a string field.
|
31
32
|
#
|
33
|
+
# store 'relation' do
|
34
|
+
# string 'field_name', default: 'value'
|
35
|
+
# string :another_field, null: false
|
36
|
+
# end
|
37
|
+
#
|
32
38
|
def string(name, opts = {})
|
33
39
|
@connection.add_column(@arel.name, name, :string, opts)
|
34
40
|
end
|
@@ -36,6 +42,11 @@ module DataDoc
|
|
36
42
|
#
|
37
43
|
# Define an integer field.
|
38
44
|
#
|
45
|
+
# store 'relation' do
|
46
|
+
# integer 'field_name', default: 42
|
47
|
+
# integer :another_field
|
48
|
+
# end
|
49
|
+
#
|
39
50
|
def integer(name, opts = {})
|
40
51
|
@connection.add_column(@arel.name, name, :integer, opts)
|
41
52
|
end
|
@@ -43,6 +54,11 @@ module DataDoc
|
|
43
54
|
#
|
44
55
|
# Define a text field.
|
45
56
|
#
|
57
|
+
# store 'relation' do
|
58
|
+
# text 'field_name'
|
59
|
+
# text :another_field
|
60
|
+
# end
|
61
|
+
#
|
46
62
|
def text(name, opts = {})
|
47
63
|
@connection.add_column(@arel.name, name, :text, opts)
|
48
64
|
end
|
@@ -50,10 +66,63 @@ module DataDoc
|
|
50
66
|
#
|
51
67
|
# Define a datetime field.
|
52
68
|
#
|
69
|
+
# store 'relation' do
|
70
|
+
# datetime 'field_name'
|
71
|
+
# datetime :another_field
|
72
|
+
# end
|
73
|
+
#
|
53
74
|
def datetime(name, opts = {})
|
54
75
|
@connection.add_column(@arel.name, name, :datetime, opts)
|
55
76
|
end
|
56
77
|
|
78
|
+
#
|
79
|
+
# Define a datetime field.
|
80
|
+
#
|
81
|
+
# store 'relation' do
|
82
|
+
# time 'field_name'
|
83
|
+
# time :another_field
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
def time(name, opts = {})
|
87
|
+
@connection.add_column(@arel.name, name, :time, opts)
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Define a date field.
|
92
|
+
#
|
93
|
+
# store 'relation' do
|
94
|
+
# date 'field_name'
|
95
|
+
# date :another_field
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
def date(name, opts = {})
|
99
|
+
@connection.add_column(@arel.name, name, :date, opts)
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Define a boolean field.
|
104
|
+
#
|
105
|
+
# store 'relation' do
|
106
|
+
# boolean 'field_name'
|
107
|
+
# boolean :another_field
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
def boolean(name, opts = {})
|
111
|
+
@connection.add_column(@arel.name, name, :boolean, opts)
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# Define a float field.
|
116
|
+
#
|
117
|
+
# store 'relation' do
|
118
|
+
# float 'field_name'
|
119
|
+
# float :another_field
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
def float(name, opts = {})
|
123
|
+
@connection.add_column(@arel.name, name, :float, opts)
|
124
|
+
end
|
125
|
+
|
57
126
|
#
|
58
127
|
# Insert a row from a hash.
|
59
128
|
#
|
@@ -64,13 +133,11 @@ module DataDoc
|
|
64
133
|
manager.insert(columns.zip(record.values))
|
65
134
|
@connection.insert(manager)
|
66
135
|
end
|
67
|
-
|
68
|
-
protected
|
69
136
|
|
70
137
|
#
|
71
138
|
# Create and empty the store unless options prevent.
|
72
139
|
#
|
73
|
-
def create_store(table_name_or_sym, opts = {}
|
140
|
+
def create_store(table_name_or_sym, opts = {})
|
74
141
|
table_name = table_name_or_sym.to_s
|
75
142
|
@arel = Arel::Table.new(table_name)
|
76
143
|
unless @doc.read_only
|
@@ -80,9 +147,16 @@ module DataDoc
|
|
80
147
|
@connection.create_table(table_name, opts.merge(force: true))
|
81
148
|
end
|
82
149
|
end
|
83
|
-
self.instance_eval(&blk) if block_given?
|
84
|
-
table_name_or_sym
|
85
150
|
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# Create new.
|
154
|
+
#
|
155
|
+
def initialize(doc)
|
156
|
+
@doc = doc
|
157
|
+
@connection = @doc.connection
|
158
|
+
end
|
159
|
+
|
86
160
|
|
87
161
|
end
|
88
162
|
|
data/test/test_data_doc_cli.rb
CHANGED
@@ -80,6 +80,14 @@ YAML
|
|
80
80
|
execute_cli("--format", 'html', @filename)
|
81
81
|
end
|
82
82
|
|
83
|
+
it "should accept a pdf format option" do
|
84
|
+
execute_cli("--format", 'pdf', @filename)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should accept a path to prince option" do
|
88
|
+
execute_cli("--prince", '/usr/local/bin/prince', @filename)
|
89
|
+
end
|
90
|
+
|
83
91
|
it "should require a format for format option" do
|
84
92
|
proc { execute_cli("--format") }.must_raise OptionParser::MissingArgument
|
85
93
|
end
|
@@ -7,11 +7,19 @@ describe DataDoc::Document do
|
|
7
7
|
@input = ""
|
8
8
|
@expected_output = ""
|
9
9
|
@expected_rows = nil
|
10
|
+
@expected_matches = Array.new
|
10
11
|
end
|
11
12
|
|
12
13
|
after do
|
13
14
|
output = @doc.generate(StringIO.new(@input))
|
14
|
-
output.strip.must_equal @expected_output.strip
|
15
|
+
output.strip.must_equal @expected_output.strip unless @expected_output.nil?
|
16
|
+
@expected_matches.each do |m|
|
17
|
+
if m.kind_of?(String)
|
18
|
+
output.force_encoding("ASCII-8BIT").scan(m).first.must_equal(m)
|
19
|
+
else
|
20
|
+
output.must_match(m)
|
21
|
+
end
|
22
|
+
end
|
15
23
|
unless @expected_rows.nil?
|
16
24
|
@doc.connection.select_value("select count(1) from #{@expected_table_name}").must_equal(@expected_rows)
|
17
25
|
end
|
@@ -23,10 +31,28 @@ describe DataDoc::Document do
|
|
23
31
|
@expected_output = ""
|
24
32
|
end
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
describe "for a simple document" do
|
35
|
+
|
36
|
+
before do
|
37
|
+
@input = '# Introduction'
|
38
|
+
@doc.layout = temp_file('<%= yield %>')
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should process markdown into html" do
|
42
|
+
@expected_output = '<h1>Introduction</h1>'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should process markdown into pdf" do
|
46
|
+
@expected_output = nil
|
47
|
+
if system("prince 1> /dev/null 2> /dev/null")
|
48
|
+
@doc.format = 'pdf'
|
49
|
+
@expected_matches.push("%PDF")
|
50
|
+
@doc.layout = temp_file('<%= yield %>')
|
51
|
+
else
|
52
|
+
skip "can't test pdf without prince"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
30
56
|
end
|
31
57
|
|
32
58
|
describe "layout" do
|
@@ -51,7 +77,7 @@ describe DataDoc::Document do
|
|
51
77
|
it "should insert meta tags into the head" do
|
52
78
|
@input = '<% meta author: "Author" %>'
|
53
79
|
@doc.layout = temp_file('<%= yield :head %>')
|
54
|
-
@expected_output = '<meta author="Author"
|
80
|
+
@expected_output = '<meta author="Author" />'
|
55
81
|
end
|
56
82
|
|
57
83
|
it "should insert script tags into the head" do
|
@@ -63,7 +89,7 @@ describe DataDoc::Document do
|
|
63
89
|
it "should insert link tags into the head" do
|
64
90
|
@input = '<% link rel: "stylesheet", type: "text/css", href: "mystyle.css" %>'
|
65
91
|
@doc.layout = temp_file('<%= yield :head %>')
|
66
|
-
@expected_output = '<link rel="stylesheet" type="text/css" href="mystyle.css"
|
92
|
+
@expected_output = '<link rel="stylesheet" type="text/css" href="mystyle.css" />'
|
67
93
|
end
|
68
94
|
|
69
95
|
it "should set the html document title in the head and in a div.title in the content" do
|
@@ -157,7 +183,16 @@ EOS
|
|
157
183
|
end
|
158
184
|
|
159
185
|
it "should present an arel" do
|
160
|
-
@doc.present(@doc.relation.project('*'))
|
186
|
+
table = @doc.present(@doc.relation.project('*'))
|
187
|
+
table.must_match(/<table>.*<\/table>/)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should call a block for table configuration" do
|
191
|
+
table = @doc.present(@doc.relation.project('*')) do
|
192
|
+
caption 'Caption'
|
193
|
+
end
|
194
|
+
table.must_match(/<table>.*<\/table>/)
|
195
|
+
table.must_match(/<caption>Caption<\/caption>/)
|
161
196
|
end
|
162
197
|
|
163
198
|
end
|
@@ -14,5 +14,66 @@ describe DataDoc::Present do
|
|
14
14
|
DataDoc::Present.present(@mock_doc, "select 1").must_match(/<table>.*<\/table>/)
|
15
15
|
end
|
16
16
|
|
17
|
+
describe "generating a table" do
|
18
|
+
|
19
|
+
before do
|
20
|
+
@mock_doc.connection.execute("create table relation (one integer, two varchar)")
|
21
|
+
@mock_doc.connection.insert_sql("insert into relation(one, two) values (1, 'one')")
|
22
|
+
@mock_doc.connection.insert_sql("insert into relation(one, two) values (2, 'two')")
|
23
|
+
@mock_doc.connection.insert_sql("insert into relation(one, two) values (3, 'three')")
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "for a complex table" do
|
27
|
+
|
28
|
+
before do
|
29
|
+
@result = DataDoc::Present.present(@mock_doc, "select * from relation") do
|
30
|
+
caption "Caption"
|
31
|
+
label :one, "Renamed"
|
32
|
+
column_order :two, :one, :three
|
33
|
+
each_cell(:two) do |col, row|
|
34
|
+
"two-changed"
|
35
|
+
end
|
36
|
+
calculated(:three) do |col, row|
|
37
|
+
"column-three"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should accept a caption" do
|
43
|
+
@result.must_match(/<caption>Caption<\/caption>/)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should rename a field label" do
|
47
|
+
@result.must_match(/<th>Renamed<\/th>/)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should define the order of columns" do
|
51
|
+
@result.must_match(/<th>Two<\/th><th>Renamed<\/th>/)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should allow a cell's contents to be programmed" do
|
55
|
+
@result.must_match(/<td>two-changed<\/td>/)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should allow a calculation for a new column" do
|
59
|
+
@result.must_match(/<td>column-three<\/td>/)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "for a table with headers" do
|
65
|
+
before do
|
66
|
+
@result = DataDoc::Present.present(@mock_doc, "select * from relation") do
|
67
|
+
no_headers
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should suppress headers" do
|
72
|
+
@result.wont_match(/<th>/)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
17
78
|
end
|
18
79
|
|
data/test/test_data_doc_store.rb
CHANGED
@@ -19,7 +19,7 @@ describe DataDoc::Store do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
after do
|
22
|
-
DataDoc::Store.
|
22
|
+
DataDoc::Store.store(@mock_doc, 'relation')
|
23
23
|
@mock_doc.connection.select_value('select count(1) from relation').must_equal @expected_rows
|
24
24
|
if @confirm_old_table_value
|
25
25
|
@mock_doc.connection.select_value('select string from relation limit 1').must_equal 'present'
|
@@ -61,33 +61,60 @@ describe DataDoc::Store do
|
|
61
61
|
end
|
62
62
|
|
63
63
|
it "adds a string attribute" do
|
64
|
-
DataDoc::Store.
|
64
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
65
65
|
string 'string'
|
66
66
|
end
|
67
67
|
check_insert('string', 'a string')
|
68
68
|
end
|
69
69
|
|
70
70
|
it "adds an integer attribute" do
|
71
|
-
DataDoc::Store.
|
71
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
72
72
|
integer 'number'
|
73
73
|
end
|
74
74
|
check_insert('number', 42)
|
75
75
|
end
|
76
76
|
|
77
77
|
it "adds a text attribute" do
|
78
|
-
DataDoc::Store.
|
78
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
79
79
|
text 'description'
|
80
80
|
end
|
81
81
|
check_insert('description', 'a string')
|
82
82
|
end
|
83
83
|
|
84
84
|
it "adds a datetime attribute" do
|
85
|
-
DataDoc::Store.
|
85
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
86
86
|
datetime 'timestamp'
|
87
87
|
end
|
88
88
|
check_insert('timestamp', '2012-10-12')
|
89
89
|
end
|
90
90
|
|
91
|
+
it "adds a date attribute" do
|
92
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
93
|
+
date 'datestamp'
|
94
|
+
end
|
95
|
+
check_insert('datestamp', Date.today)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "adds a time attribute" do
|
99
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
100
|
+
time 'timestamp'
|
101
|
+
end
|
102
|
+
check_insert('timestamp', Time.now)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "adds a float attribute" do
|
106
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
107
|
+
float 'value'
|
108
|
+
end
|
109
|
+
check_insert('value', 42.234)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "adds a boolean attribute" do
|
113
|
+
DataDoc::Store.store(@mock_doc, 'relation') do
|
114
|
+
boolean 'flag'
|
115
|
+
end
|
116
|
+
check_insert('flag', true)
|
117
|
+
end
|
91
118
|
end
|
92
119
|
|
93
120
|
describe "alternate keys" do
|
@@ -98,7 +125,7 @@ describe DataDoc::Store do
|
|
98
125
|
describe "accepting rows" do
|
99
126
|
|
100
127
|
before do
|
101
|
-
@store = DataDoc::Store.
|
128
|
+
@store = DataDoc::Store.store(@mock_doc, 'relation') do
|
102
129
|
string 's'
|
103
130
|
integer 'i'
|
104
131
|
text 't'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_doc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -141,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
141
|
version: '0'
|
142
142
|
segments:
|
143
143
|
- 0
|
144
|
-
hash: -
|
144
|
+
hash: -3309162244341749974
|
145
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
146
|
none: false
|
147
147
|
requirements:
|