data_doc 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|