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