data_doc 0.0.2 → 0.0.3
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 +9 -1
- data/Manifest.txt +6 -1
- data/README.rdoc +55 -5
- data/Rakefile +3 -11
- data/lib/data_doc.rb +12 -2
- data/lib/data_doc/cli.rb +83 -22
- data/lib/data_doc/document.rb +198 -0
- data/lib/data_doc/present.rb +0 -0
- data/lib/data_doc/store.rb +0 -0
- data/test/test_data_doc.rb +6 -7
- data/test/test_data_doc_cli.rb +95 -10
- data/test/test_data_doc_document.rb +76 -0
- data/test/test_data_doc_present.rb +0 -0
- data/test/test_data_doc_store.rb +0 -0
- data/test/test_helper.rb +19 -1
- metadata +30 -7
- data/PostInstall.txt +0 -7
data/History.txt
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
=== 0.0.3 2012-10-22
|
2
|
+
|
3
|
+
* 4 minor enhancements:
|
4
|
+
* RDoc coverage established
|
5
|
+
* Layouts
|
6
|
+
* Headers
|
7
|
+
* ERB processing under $SAFE = 4
|
8
|
+
|
1
9
|
=== 0.0.2 2012-10-18
|
2
10
|
|
3
|
-
*
|
11
|
+
* 2 minor enhancements:
|
4
12
|
* Documentation fix
|
5
13
|
* Test release
|
6
14
|
|
data/Manifest.txt
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
History.txt
|
2
2
|
Manifest.txt
|
3
|
-
PostInstall.txt
|
4
3
|
README.rdoc
|
5
4
|
Rakefile
|
6
5
|
bin/data_doc
|
7
6
|
lib/data_doc.rb
|
8
7
|
lib/data_doc/cli.rb
|
8
|
+
lib/data_doc/document.rb
|
9
|
+
lib/data_doc/store.rb
|
10
|
+
lib/data_doc/present.rb
|
9
11
|
script/console
|
10
12
|
script/destroy
|
11
13
|
script/generate
|
12
14
|
test/test_data_doc.rb
|
15
|
+
test/test_data_doc_document.rb
|
16
|
+
test/test_data_doc_store.rb
|
17
|
+
test/test_data_doc_present.rb
|
13
18
|
test/test_data_doc_cli.rb
|
14
19
|
test/test_helper.rb
|
data/README.rdoc
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
|
5
5
|
{<img src="https://secure.travis-ci.org/alilee/data_doc.png" alt="Build Status" />}[http://travis-ci.org/alilee/data_doc]
|
6
6
|
|
7
|
+
NOTE: THIS GEM DOES NOTHING YET.
|
8
|
+
|
7
9
|
== DESCRIPTION:
|
8
10
|
|
9
11
|
Complex documents can be challenging to author, and time-consuming to achieve
|
@@ -11,6 +13,8 @@ high levels of internal consistency. This gem offers a Domain Specific Language
|
|
11
13
|
to embed structured data in a markdown document and then render it into
|
12
14
|
configurable tables.
|
13
15
|
|
16
|
+
Note: See security implications below.
|
17
|
+
|
14
18
|
== FEATURES/PROBLEMS:
|
15
19
|
|
16
20
|
* Main document is Markdown for convenient content authoring.
|
@@ -19,25 +23,71 @@ configurable tables.
|
|
19
23
|
* Generates HTML from Markdown.
|
20
24
|
* Provides fine-grained control over the HTML headers, including
|
21
25
|
CSS, for the output.
|
22
|
-
* Simple DSL for capturing structured data
|
26
|
+
* Simple DSL for capturing structured data.
|
23
27
|
* Simple DSL for querying data stores and laying out in tables.
|
28
|
+
* Command line interface
|
29
|
+
* Simple web-page interface using sinatra
|
30
|
+
|
31
|
+
== SECURITY IMPLICATIONS:
|
32
|
+
|
33
|
+
This gem uses ERB to process arbitrary ruby code provided by a user.
|
34
|
+
Some sandboxing ($SAFE) is used, but you should assess and manage
|
35
|
+
your level of risk.
|
24
36
|
|
25
37
|
== SYNOPSIS:
|
26
38
|
|
27
|
-
data_doc
|
39
|
+
$ bin/data_doc --help
|
40
|
+
Processes structured data embedded in a markdown document and then renders it into configurable tables.
|
41
|
+
|
42
|
+
Usage: data_doc [options] filename
|
43
|
+
|
44
|
+
Options are:
|
45
|
+
|
46
|
+
Specific options:
|
47
|
+
-c, --connection FILENAME Override document connection settings with FILENAME
|
48
|
+
-r, --read-only Use data already in database rather than document data
|
49
|
+
-d, --data-only Use document data but do not change database schema
|
50
|
+
-o, --output FILENAME Put generated output in FILENAME
|
51
|
+
-f, --format TYPE Select type of output from html (default: html)
|
52
|
+
-v, --[no-]verbose Run verbosely
|
53
|
+
|
54
|
+
Common options:
|
55
|
+
-h, --help Show this message
|
56
|
+
--version Show version
|
57
|
+
$
|
28
58
|
|
29
59
|
The data definition language looks like this:
|
30
60
|
|
61
|
+
connection adapter: sqlite3 database: '/tmp/example.db'
|
62
|
+
|
63
|
+
store 'priority' do
|
64
|
+
string 'name'
|
65
|
+
alternate_key 'name'
|
66
|
+
end
|
67
|
+
|
68
|
+
priority name: 'high'
|
69
|
+
priority name: 'medium'
|
70
|
+
priority name: 'low'
|
71
|
+
|
31
72
|
store 'requirement' do
|
32
73
|
string 'name'
|
33
74
|
text 'description'
|
34
|
-
|
75
|
+
ref 'priority', in: 'priority'
|
35
76
|
alternate_key 'name'
|
36
77
|
end
|
37
78
|
|
38
|
-
requirement name: "It MUST "
|
79
|
+
requirement name: "It MUST be fast", description: "It must return within 5s.", priority: 'high'
|
80
|
+
requirement name: "It MUST look good", description: "It must be blue in colour.", priority: 'medium'
|
81
|
+
|
82
|
+
The table presentation language looks like this:
|
83
|
+
|
84
|
+
present 'select * from priority' #=> '<table>...</table>'
|
39
85
|
|
40
|
-
|
86
|
+
present requirement.project('priority', 'name') do
|
87
|
+
caption 'Table of requirements by priority'
|
88
|
+
column_order 'name', 'priority'
|
89
|
+
label 'priority, 'Importance'
|
90
|
+
end #=> '<table>...</table>'
|
41
91
|
|
42
92
|
== REQUIREMENTS:
|
43
93
|
|
data/Rakefile
CHANGED
@@ -5,22 +5,14 @@ require 'fileutils'
|
|
5
5
|
require './lib/data_doc'
|
6
6
|
|
7
7
|
Hoe.plugin :newgem
|
8
|
-
# Hoe.plugin :website
|
9
|
-
# Hoe.plugin :cucumberfeatures
|
10
8
|
|
11
9
|
# Generate all the Rake tasks
|
12
10
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
13
11
|
$hoe = Hoe.spec 'data_doc' do
|
14
|
-
self.developer
|
15
|
-
self.
|
16
|
-
self.
|
17
|
-
# self.extra_deps = [['activesupport','>= 2.0.2']]
|
18
|
-
|
12
|
+
self.developer 'Alister Lee', 'gems@shortepic.com'
|
13
|
+
self.rubyforge_name = 'data-doc'
|
14
|
+
self.extra_deps = [['activerecord','>= 2.0.2']]
|
19
15
|
end
|
20
16
|
|
21
17
|
require 'newgem/tasks'
|
22
18
|
Dir['tasks/**/*.rake'].each { |t| load t }
|
23
|
-
|
24
|
-
# TODO - want other tests/tasks run by default? Add them to the list
|
25
|
-
# remove_task :default
|
26
|
-
# task :default => [:spec, :features]
|
data/lib/data_doc.rb
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)) unless
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
|
+
#
|
5
|
+
# Encompasses the data_doc classes.
|
6
|
+
#
|
4
7
|
module DataDoc
|
5
|
-
|
6
|
-
|
8
|
+
# Gem version
|
9
|
+
VERSION = '0.0.3'
|
10
|
+
# A summary of purpose of the tool.
|
11
|
+
DESCRIPTION = 'Processes structured data embedded in a markdown document and then renders it into configurable tables.'
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'data_doc/document.rb'
|
15
|
+
# require 'data_doc/store.rb'
|
16
|
+
# require 'data_doc/table.rb'
|
data/lib/data_doc/cli.rb
CHANGED
@@ -1,42 +1,103 @@
|
|
1
1
|
require 'optparse'
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
module DataDoc
|
5
|
+
|
6
|
+
#
|
7
|
+
# Manages command-line options and arguments.
|
8
|
+
#
|
4
9
|
class CLI
|
10
|
+
|
11
|
+
#
|
12
|
+
# Parses the command line and calls the main object.
|
13
|
+
#
|
14
|
+
# stdout:: IO to redirect output for testing.
|
15
|
+
# arguments:: contents of command line
|
16
|
+
#
|
5
17
|
def self.execute(stdout, arguments=[])
|
6
18
|
|
7
|
-
|
19
|
+
doc = DataDoc::Document.new
|
20
|
+
doc.output = stdout
|
8
21
|
|
9
|
-
|
10
|
-
:path => '~'
|
11
|
-
}
|
12
|
-
mandatory_options = %w( )
|
13
|
-
|
14
|
-
parser = OptionParser.new do |opts|
|
22
|
+
OptionParser.new do |opts|
|
15
23
|
opts.banner = <<-BANNER.gsub(/^ /,'')
|
16
|
-
|
24
|
+
#{DataDoc::DESCRIPTION}
|
17
25
|
|
18
|
-
Usage: #{File.basename($0)} [options]
|
26
|
+
Usage: #{File.basename($0)} [options] filename
|
19
27
|
|
20
28
|
Options are:
|
21
29
|
BANNER
|
30
|
+
|
22
31
|
opts.separator ""
|
23
|
-
opts.
|
24
|
-
"This is a sample message.",
|
25
|
-
"For multiple lines, add more strings.",
|
26
|
-
"Default: ~") { |arg| options[:path] = arg }
|
27
|
-
opts.on("-h", "--help",
|
28
|
-
"Show this help message.") { stdout.puts opts; exit }
|
29
|
-
opts.parse!(arguments)
|
32
|
+
opts.separator "Specific options:"
|
30
33
|
|
31
|
-
|
32
|
-
|
34
|
+
opts.on("-c", "--connection FILENAME",
|
35
|
+
"Override document connection settings with FILENAME") do |filename|
|
36
|
+
begin
|
37
|
+
doc.connection = YAML.load(File.read(filename))
|
38
|
+
rescue Exception => e
|
39
|
+
stdout.puts "ERROR with connection file (#{e.message})"
|
40
|
+
return 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("-r", "--read-only", "Use data already in database rather than document data") do |r|
|
45
|
+
doc.read_only = r
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("-d", "--data-only", "Use document data but do not change database schema") do |d|
|
49
|
+
doc.data_only = d
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("-o", "--output FILENAME",
|
53
|
+
"Put generated output in FILENAME") do |filename|
|
54
|
+
begin
|
55
|
+
doc.output = File.open(filename, 'w+')
|
56
|
+
rescue Exception => e
|
57
|
+
stdout.puts "ERROR with output file (#{e.message})"
|
58
|
+
return 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
type_list = DataDoc::Document::OUTPUT_TYPES.join(', ')
|
63
|
+
opts.on("-f", "--format TYPE", DataDoc::Document::OUTPUT_TYPES, "Select type of output from #{type_list} (default: #{doc.format})") do |format|
|
64
|
+
doc.format = format
|
65
|
+
end
|
66
|
+
|
67
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
68
|
+
doc.verbose = v
|
33
69
|
end
|
34
|
-
end
|
35
70
|
|
36
|
-
|
71
|
+
opts.separator ""
|
72
|
+
opts.separator "Common options:"
|
37
73
|
|
38
|
-
|
39
|
-
|
74
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
75
|
+
stdout.puts opts
|
76
|
+
return 0
|
77
|
+
end
|
78
|
+
|
79
|
+
opts.on_tail("--version", "Show version") do
|
80
|
+
stdout.puts DataDoc::VERSION
|
81
|
+
return 0
|
82
|
+
end
|
83
|
+
|
84
|
+
opts.parse!(arguments)
|
85
|
+
|
86
|
+
if arguments.length != 1
|
87
|
+
stdout.puts "ERROR missing input file"
|
88
|
+
return 1
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
begin
|
94
|
+
content = File.open(arguments.first, "r")
|
95
|
+
rescue Exception => e
|
96
|
+
stdout.puts "ERROR opening content file (#{e.message})"
|
97
|
+
return 1
|
98
|
+
end
|
99
|
+
|
100
|
+
doc.generate(content)
|
40
101
|
end
|
41
102
|
end
|
42
103
|
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'rdiscount'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module DataDoc
|
5
|
+
|
6
|
+
#
|
7
|
+
# Class for processing and rendering data_docs.
|
8
|
+
#
|
9
|
+
# Manages processing and formatting of the document.
|
10
|
+
#
|
11
|
+
class Document
|
12
|
+
|
13
|
+
#
|
14
|
+
# :section: 1. Options
|
15
|
+
#
|
16
|
+
# Allows access to set processing options prior to document generation.
|
17
|
+
#
|
18
|
+
|
19
|
+
#
|
20
|
+
# Sets up so that default options can be read.
|
21
|
+
#
|
22
|
+
def initialize
|
23
|
+
@format = 'html'
|
24
|
+
@output = STDOUT
|
25
|
+
@verbose = false
|
26
|
+
@read_only = false
|
27
|
+
@data_only = false
|
28
|
+
@connection = nil
|
29
|
+
@layout_filename = nil
|
30
|
+
|
31
|
+
@headers = Array.new
|
32
|
+
end
|
33
|
+
|
34
|
+
# MIME-type for output
|
35
|
+
attr_accessor :format
|
36
|
+
|
37
|
+
# Available mime types that can be generated.
|
38
|
+
OUTPUT_TYPES = ['html']
|
39
|
+
|
40
|
+
# output filename
|
41
|
+
attr_accessor :output
|
42
|
+
|
43
|
+
# display verbose output during processing
|
44
|
+
attr_accessor :verbose
|
45
|
+
|
46
|
+
# do not change schema or data
|
47
|
+
attr_accessor :read_only
|
48
|
+
|
49
|
+
# do not change schema; truncates tables
|
50
|
+
attr_accessor :data_only
|
51
|
+
|
52
|
+
#
|
53
|
+
# Sets the database connection that the stores will be using
|
54
|
+
#
|
55
|
+
def connection=(connection)
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Sets the layout file option.
|
60
|
+
#
|
61
|
+
# See #set_layout_file below for format.
|
62
|
+
#
|
63
|
+
def layout=(filename)
|
64
|
+
@layout_filename = filename
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# :section: 2. Main function
|
69
|
+
#
|
70
|
+
|
71
|
+
#
|
72
|
+
# Generate the output for the given input content.
|
73
|
+
#
|
74
|
+
def generate(content_io)
|
75
|
+
erb_content = content_io.read
|
76
|
+
begin
|
77
|
+
self.untrust
|
78
|
+
mark_down = ERB.new(erb_content, 4).result(binding.taint) # $SAFE = 4
|
79
|
+
ensure
|
80
|
+
self.trust
|
81
|
+
end
|
82
|
+
content_html = RDiscount.new(mark_down).to_html
|
83
|
+
html = wrap_in_layout(content_html)
|
84
|
+
@output.write(html)
|
85
|
+
0
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# :section: 3. DSL for layout file
|
90
|
+
#
|
91
|
+
|
92
|
+
#
|
93
|
+
# Set layout file (from the filename, not the template content itself)
|
94
|
+
#
|
95
|
+
# Content is html, with ERB placeholders to yield to add content at
|
96
|
+
# appropriate points.
|
97
|
+
#
|
98
|
+
# [ <%= yield :head %> ] marks where to place any headers defined (see #meta below for an example)
|
99
|
+
# [ <%= yield :content %> <em>or</em> <%= yield %> ] marks where to place the processed content from the input file.
|
100
|
+
#
|
101
|
+
def set_layout_file(filename)
|
102
|
+
self.layout=(filename)
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Default layout if no layout file provided.
|
107
|
+
#
|
108
|
+
# Simplistic valid html which accepts headers and puts content directly into body tag.
|
109
|
+
#
|
110
|
+
def self.default_layout
|
111
|
+
"<!DOCTYPE html>\n<html>\n<head><%= yield :head %></head>\n<body>\n<%= yield %>\n</body>\n</html>"
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# :section: 4. DSL for header tags
|
116
|
+
#
|
117
|
+
|
118
|
+
#
|
119
|
+
# Sets the title tag and emits the title in a classed div.title.
|
120
|
+
#
|
121
|
+
def title(text)
|
122
|
+
add_header "<title>#{text}</title>"
|
123
|
+
"<div class=\"title\">#{text}</div>"
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# Adds a meta tag to the headers
|
128
|
+
#
|
129
|
+
def meta(attrs = {})
|
130
|
+
add_header "<meta #{html_attrs(attrs)}>"
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Adds a script tag to the headers, yielding for body of tag.
|
135
|
+
#
|
136
|
+
def script(attrs = {})
|
137
|
+
add_header "<script #{html_attrs(attrs)}>#{"\n"+yield+"\n" if block_given?}</script>"
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# Adds a link tag to the headers
|
142
|
+
#
|
143
|
+
def link(attrs = {})
|
144
|
+
add_header "<link #{html_attrs(attrs)}>"
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# :section: 5. Protected
|
149
|
+
#
|
150
|
+
|
151
|
+
protected
|
152
|
+
|
153
|
+
#
|
154
|
+
# Isolates ERB for layout
|
155
|
+
#
|
156
|
+
class IsolatedLayoutContext
|
157
|
+
# captures binding including any block
|
158
|
+
def binding_with_block
|
159
|
+
binding
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# Wraps the default layout or a user provided layout around the content.
|
165
|
+
#
|
166
|
+
def wrap_in_layout(content)
|
167
|
+
@layout ||= @layout_filename.nil? ? DataDoc::Document.default_layout : File.read(@layout_filename)
|
168
|
+
block_binding = IsolatedLayoutContext.new.binding_with_block do |section|
|
169
|
+
case section.to_s
|
170
|
+
when 'head'
|
171
|
+
@headers.join("\n")
|
172
|
+
else
|
173
|
+
content
|
174
|
+
end
|
175
|
+
end
|
176
|
+
ERB.new(@layout, 4, '<>').result(block_binding.taint) # $SAFE = 4
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# Formats a hash as html attributes for insertion into a tag.
|
181
|
+
#
|
182
|
+
def html_attrs(attrs)
|
183
|
+
list = attrs.to_a.map {|k,v| "#{k}=\"#{v}\"" }
|
184
|
+
list.join(' ')
|
185
|
+
end
|
186
|
+
|
187
|
+
#
|
188
|
+
# Add another header to the array of headers.
|
189
|
+
#
|
190
|
+
def add_header(h)
|
191
|
+
# Can't use Array#push in $SAFE = 4
|
192
|
+
@headers = @headers + [h]
|
193
|
+
h
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
File without changes
|
File without changes
|
data/test/test_data_doc.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/test_helper.rb'
|
1
|
+
# require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
require_relative 'test_helper.rb'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
def setup
|
6
|
-
end
|
4
|
+
describe DataDoc do
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
describe "integration tests" do
|
7
|
+
|
10
8
|
end
|
9
|
+
|
11
10
|
end
|
data/test/test_data_doc_cli.rb
CHANGED
@@ -1,14 +1,99 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
require_relative 'test_helper.rb'
|
2
|
+
require_relative '../lib/data_doc/cli'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
describe DataDoc::CLI do
|
7
|
+
|
8
|
+
def execute_cli(*args)
|
9
|
+
DataDoc::CLI.execute(stdout_io = StringIO.new, args)
|
10
|
+
stdout_io.rewind
|
11
|
+
stdout_io.read.strip
|
9
12
|
end
|
13
|
+
|
14
|
+
describe "with no file" do
|
15
|
+
|
16
|
+
it "should present version" do
|
17
|
+
execute_cli('--version').must_equal DataDoc::VERSION
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should present help" do
|
21
|
+
result = execute_cli('--help')
|
22
|
+
result.must_match(/#{DataDoc::DESCRIPTION}/)
|
23
|
+
result.must_match(/Usage:/)
|
24
|
+
result.must_match(/--help/)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "with a file" do
|
30
|
+
|
31
|
+
describe "which is empty" do
|
32
|
+
|
33
|
+
before do
|
34
|
+
@filename = temp_file("")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return" do
|
38
|
+
execute_cli(@filename)
|
39
|
+
end
|
10
40
|
|
11
|
-
|
12
|
-
|
41
|
+
it "should require a filename for connection option" do
|
42
|
+
proc { execute_cli('--connection') }.must_raise OptionParser::MissingArgument
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "with connection settings file" do
|
46
|
+
|
47
|
+
before do
|
48
|
+
@db_filename = temp_file("")
|
49
|
+
connection_yaml = <<YAML
|
50
|
+
adapter: sqlite3
|
51
|
+
database: #{@db_filename}
|
52
|
+
YAML
|
53
|
+
@connection_filename = temp_file(connection_yaml)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should accept a connection option" do
|
57
|
+
execute_cli("--connection", "#{@connection_filename}")
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should accept a read-only option" do
|
63
|
+
execute_cli("--read-only", @filename)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should accept a data-only option" do
|
67
|
+
execute_cli("--data-only", @filename)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should accept an output file option" do
|
71
|
+
output_filename = temp_file("")
|
72
|
+
execute_cli("--output", output_filename, @filename)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should require a filename for output option" do
|
76
|
+
proc { execute_cli("--output") }.must_raise OptionParser::MissingArgument
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should accept an html format option" do
|
80
|
+
execute_cli("--format", 'html', @filename)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should require a format for format option" do
|
84
|
+
proc { execute_cli("--format") }.must_raise OptionParser::MissingArgument
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should require a valid format for format option" do
|
88
|
+
proc { execute_cli("--format", 'invalid') }.must_raise OptionParser::InvalidArgument
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should accept a verbose option" do
|
92
|
+
execute_cli("--verbose", @filename)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
13
97
|
end
|
98
|
+
|
14
99
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative 'test_helper.rb'
|
2
|
+
|
3
|
+
describe DataDoc::Document do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@doc = DataDoc::Document.new
|
7
|
+
@input = ""
|
8
|
+
@expected_output = ""
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
output = StringIO.new
|
13
|
+
@doc.output = output
|
14
|
+
@doc.generate(StringIO.new(@input))
|
15
|
+
output.rewind
|
16
|
+
output.read.strip.must_equal @expected_output.strip
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should process empty input" do
|
20
|
+
@input = ""
|
21
|
+
@doc.layout = temp_file('<%= yield %>')
|
22
|
+
@expected_output = ""
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should process markdown into html" do
|
26
|
+
@input = '# Introduction'
|
27
|
+
@doc.layout = temp_file('<%= yield %>')
|
28
|
+
@expected_output = '<h1>Introduction</h1>'
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "layout" do
|
32
|
+
|
33
|
+
it "should wrap the generated text in a layout" do
|
34
|
+
layout_filename = temp_file('layout:<%= yield %>:layout')
|
35
|
+
@input = "<% set_layout_file '#{layout_filename}' %>Some text."
|
36
|
+
@expected_output = "layout:<p>Some text.</p>\n:layout"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should wrap the content in a default html layout" do
|
40
|
+
@input = "<p>XXX</p>"
|
41
|
+
@expected_output = erb(DataDoc::Document.default_layout) do |section|
|
42
|
+
@input + "\n" if section.to_s != 'head'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "head tags" do
|
49
|
+
|
50
|
+
it "should insert meta tags into the head" do
|
51
|
+
@input = '<% meta author: "Author" %>'
|
52
|
+
@doc.layout = temp_file('<%= yield :head %>')
|
53
|
+
@expected_output = '<meta author="Author">'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should insert script tags into the head" do
|
57
|
+
@input = '<% script(src: "jquery.js") { "XXX" } %>'
|
58
|
+
@doc.layout = temp_file('<%= yield :head %>')
|
59
|
+
@expected_output = "<script src=\"jquery.js\">\nXXX\n</script>"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should insert link tags into the head" do
|
63
|
+
@input = '<% link rel: "stylesheet", type: "text/css", href: "mystyle.css" %>'
|
64
|
+
@doc.layout = temp_file('<%= yield :head %>')
|
65
|
+
@expected_output = '<link rel="stylesheet" type="text/css" href="mystyle.css">'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should set the html document title in the head and in a div.title in the content" do
|
69
|
+
@input = '<%= title "Title" %>'
|
70
|
+
@doc.layout = temp_file('Head:<%= yield :head %>Content:<%= yield %>')
|
71
|
+
@expected_output = 'Head:<title>Title</title>Content:<div class="title">Title</div>'
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
File without changes
|
File without changes
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,21 @@
|
|
1
1
|
require 'stringio'
|
2
|
-
require '
|
2
|
+
require 'set'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require 'minitest/mock'
|
6
|
+
|
3
7
|
require File.dirname(__FILE__) + '/../lib/data_doc'
|
8
|
+
|
9
|
+
def temp_file(content)
|
10
|
+
@temp_files ||= Set.new
|
11
|
+
f = Tempfile.new('test_data_doc')
|
12
|
+
@temp_files.add(f)
|
13
|
+
f.write(content)
|
14
|
+
f.rewind
|
15
|
+
f.path
|
16
|
+
end
|
17
|
+
|
18
|
+
# allows yield to call block
|
19
|
+
def erb(content)
|
20
|
+
ERB.new(content).result(binding)
|
21
|
+
end
|
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.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.0.2
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.0.2
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: rdoc
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -62,7 +78,7 @@ dependencies:
|
|
62
78
|
description: ! "Complex documents can be challenging to author, and time-consuming
|
63
79
|
to achieve \nhigh levels of internal consistency. This gem offers a Domain Specific
|
64
80
|
Language \nto embed structured data in a markdown document and then render it into
|
65
|
-
\nconfigurable tables."
|
81
|
+
\nconfigurable tables. \n\nNote: See security implications below."
|
66
82
|
email:
|
67
83
|
- gems@shortepic.com
|
68
84
|
executables:
|
@@ -71,27 +87,31 @@ extensions: []
|
|
71
87
|
extra_rdoc_files:
|
72
88
|
- History.txt
|
73
89
|
- Manifest.txt
|
74
|
-
- PostInstall.txt
|
75
90
|
- README.rdoc
|
76
91
|
files:
|
77
92
|
- History.txt
|
78
93
|
- Manifest.txt
|
79
|
-
- PostInstall.txt
|
80
94
|
- README.rdoc
|
81
95
|
- Rakefile
|
82
96
|
- bin/data_doc
|
83
97
|
- lib/data_doc.rb
|
84
98
|
- lib/data_doc/cli.rb
|
99
|
+
- lib/data_doc/document.rb
|
100
|
+
- lib/data_doc/store.rb
|
101
|
+
- lib/data_doc/present.rb
|
85
102
|
- script/console
|
86
103
|
- script/destroy
|
87
104
|
- script/generate
|
88
105
|
- test/test_data_doc.rb
|
106
|
+
- test/test_data_doc_document.rb
|
107
|
+
- test/test_data_doc_store.rb
|
108
|
+
- test/test_data_doc_present.rb
|
89
109
|
- test/test_data_doc_cli.rb
|
90
110
|
- test/test_helper.rb
|
91
111
|
- .gemtest
|
92
112
|
homepage: http://github.com/alilee/data_doc
|
93
113
|
licenses: []
|
94
|
-
post_install_message:
|
114
|
+
post_install_message:
|
95
115
|
rdoc_options:
|
96
116
|
- --main
|
97
117
|
- README.rdoc
|
@@ -105,7 +125,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
125
|
version: '0'
|
106
126
|
segments:
|
107
127
|
- 0
|
108
|
-
hash: -
|
128
|
+
hash: -2005409692758115623
|
109
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
130
|
none: false
|
111
131
|
requirements:
|
@@ -122,4 +142,7 @@ summary: Complex documents can be challenging to author, and time-consuming to a
|
|
122
142
|
test_files:
|
123
143
|
- test/test_data_doc.rb
|
124
144
|
- test/test_data_doc_cli.rb
|
145
|
+
- test/test_data_doc_document.rb
|
146
|
+
- test/test_data_doc_present.rb
|
147
|
+
- test/test_data_doc_store.rb
|
125
148
|
- test/test_helper.rb
|