nandoc 0.0.1
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/README +124 -0
- data/Rakefile +53 -0
- data/bin/nandoc +6 -0
- data/doc/CREDITS.md +6 -0
- data/doc/FAQ/why-not-wiki.md +20 -0
- data/doc/FAQ.md +68 -0
- data/doc/TODOs-and-BUGs.md +15 -0
- data/doc/bar/baz.md +4 -0
- data/doc/bar/bliff.md +8 -0
- data/doc/foo.md +5 -0
- data/doc/getting-started.rb +13 -0
- data/doc/svg/less-fonts.svg +21 -0
- data/lib/nandoc/commands/create-nandoc-site.rb +225 -0
- data/lib/nandoc/commands/diff.rb +279 -0
- data/lib/nandoc/config.rb +58 -0
- data/lib/nandoc/cri-hacks.rb +13 -0
- data/lib/nandoc/data-source.rb +239 -0
- data/lib/nandoc/filters.rb +661 -0
- data/lib/nandoc/helpers/menu-bouncy.rb +109 -0
- data/lib/nandoc/helpers/site-map.rb +157 -0
- data/lib/nandoc/helpers/top-nav.rb +47 -0
- data/lib/nandoc/helpers.rb +42 -0
- data/lib/nandoc/item-class-hacks.rb +57 -0
- data/lib/nandoc/nandoc.persistent.json +3 -0
- data/lib/nandoc/parse-readme.rb +95 -0
- data/lib/nandoc/spec-doc/mini-test/spec-instance-methods.rb +0 -0
- data/lib/nandoc/spec-doc/mini-test.rb +105 -0
- data/lib/nandoc/spec-doc/mock-prompt.rb +121 -0
- data/lib/nandoc/spec-doc/support-modules.rb +158 -0
- data/lib/nandoc/spec-doc/test-case-agent.rb +57 -0
- data/lib/nandoc/spec-doc/test-framework-dispatcher.rb +15 -0
- data/lib/nandoc/spec-doc/test-framework-proxy.rb +78 -0
- data/lib/nandoc/spec-doc.rb +46 -0
- data/lib/nandoc/support/diff-proxy.rb +113 -0
- data/lib/nandoc/support/orphanage.rb +77 -0
- data/lib/nandoc/support/path-tardo.rb +85 -0
- data/lib/nandoc/support/regexp-enhance.rb +76 -0
- data/lib/nandoc/support/site-diff.rb +46 -0
- data/lib/nandoc/support/site-merge.rb +62 -0
- data/lib/nandoc/support/site-methods.rb +69 -0
- data/lib/nandoc/support/stream-colorizer.rb +203 -0
- data/lib/nandoc/support-modules.rb +270 -0
- data/lib/nandoc/test/diff-to-string.rb +251 -0
- data/lib/nandoc/test/minitest-extlib.rb +53 -0
- data/lib/nandoc/treebis/NOGIT-DOCS/NEWS.md +5 -0
- data/lib/nandoc/treebis/NOGIT-README.md +65 -0
- data/lib/nandoc/treebis/nandoc.persistent.json +3 -0
- data/lib/nandoc.rb +48 -0
- data/proto/README.md +31 -0
- data/proto/default/Rakefile +1 -0
- data/proto/default/Rules +46 -0
- data/proto/default/config.yaml +57 -0
- data/proto/default/content/css/nanoc-dist-altered.css +213 -0
- data/proto/default/content/css/trollop-subset.css +116 -0
- data/proto/default/content/js/menu-bouncy.js +126 -0
- data/proto/default/content/stylesheet.css.diff +20 -0
- data/proto/default/content/vendor/jquery-1.3.js +4241 -0
- data/proto/default/content/vendor/jquery.easing.1.3.js +205 -0
- data/proto/default/layouts/default.html +70 -0
- data/proto/default/lib/default.orig.rb +2 -0
- data/proto/default/lib/default.rb +5 -0
- data/proto/default/treebis-task.rb +28 -0
- data/proto/misc/orphan-surrogate.md +6 -0
- data/test/test.rb +102 -0
- metadata +166 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
module NanDoc::Helpers::NanDocHelpers
|
2
|
+
|
3
|
+
#
|
4
|
+
# render topnav with one level of menu dropdows
|
5
|
+
# with buggy animated opening and closing.
|
6
|
+
#
|
7
|
+
# usage example:
|
8
|
+
# nandoc_menu_bouncy(binding) do |it|
|
9
|
+
# it.separator = These['❧']
|
10
|
+
# it.tabs = 4
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
def nandoc_menu_bouncy binding, &block
|
14
|
+
MenuBouncy.new(binding, &block).render
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
#
|
20
|
+
class MenuBouncy
|
21
|
+
include NanDoc::StringFormatting
|
22
|
+
def initialize(binding, &block)
|
23
|
+
@separator_default = '>'
|
24
|
+
@tab = ' '
|
25
|
+
@tabs = 0
|
26
|
+
@item = eval('@item', binding)
|
27
|
+
block.call(self)
|
28
|
+
end
|
29
|
+
attr_accessor :separator_default, :tab, :tabs
|
30
|
+
alias_method :separator=, :separator_default=
|
31
|
+
alias_method :separator, :separator_default
|
32
|
+
alias_method :menu_item_bullet_right, :separator_default
|
33
|
+
def render
|
34
|
+
item = @item
|
35
|
+
chunks = []
|
36
|
+
if item.nandoc_sorted_visible_children.any?
|
37
|
+
chunks.push render_branch(item)
|
38
|
+
else
|
39
|
+
chunks.push render_leaf(item)
|
40
|
+
end
|
41
|
+
while item = item.parent
|
42
|
+
chunks.push render_branch(item)
|
43
|
+
end
|
44
|
+
html = chunks.reverse.join('')
|
45
|
+
html2 = reindent html
|
46
|
+
html2.strip
|
47
|
+
end
|
48
|
+
private
|
49
|
+
def render_branch item
|
50
|
+
[
|
51
|
+
render_branch_label(item),
|
52
|
+
render_branch_sep_hack(item)
|
53
|
+
].join
|
54
|
+
end
|
55
|
+
def render_branch_label item
|
56
|
+
<<-H
|
57
|
+
<div class='nanoc-sidebar-h2 nandoc-menu-lvl-1'>
|
58
|
+
#{render_link_or_label(item)}
|
59
|
+
</div>
|
60
|
+
H
|
61
|
+
end
|
62
|
+
def render_branch_sep_hack item
|
63
|
+
lines = [<<-H
|
64
|
+
<div class='bouncy-lvl1-sep'>#{separator}
|
65
|
+
<div class='bouncy-lvl2-menu'>
|
66
|
+
H
|
67
|
+
]
|
68
|
+
cx = item.nandoc_sorted_visible_children
|
69
|
+
hh = cx.map{ |x| render_level_2_item(x) }
|
70
|
+
lines.concat hh
|
71
|
+
lines.push <<-H
|
72
|
+
</div>
|
73
|
+
</div>
|
74
|
+
H
|
75
|
+
lines.join
|
76
|
+
end
|
77
|
+
def render_level_2_item item
|
78
|
+
<<-H
|
79
|
+
<div class='bouncy-lvl2-item'>
|
80
|
+
<span class='bouncy-lvl2-content'>
|
81
|
+
#{render_link_or_label(item)}
|
82
|
+
</span>
|
83
|
+
<span class='bouncy-lvl2-sep'>#{menu_item_bullet_right}</span>
|
84
|
+
</div>
|
85
|
+
H
|
86
|
+
end
|
87
|
+
def render_label item
|
88
|
+
item.nandoc_title
|
89
|
+
end
|
90
|
+
def render_leaf item
|
91
|
+
<<-H
|
92
|
+
<div class='nanoc-sidebar-h2 nandoc-menu-lvl-1'>
|
93
|
+
#{render_label(item)}
|
94
|
+
</div>
|
95
|
+
H
|
96
|
+
end
|
97
|
+
def render_link_default item
|
98
|
+
"<a href='#{item.identifier}'>#{item.nandoc_title}</a>"
|
99
|
+
end
|
100
|
+
alias_method :render_link, :render_link_default
|
101
|
+
def render_link_or_label item
|
102
|
+
if item == @item
|
103
|
+
render_label item
|
104
|
+
else
|
105
|
+
render_link item
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module NanDoc::Helpers::NanDocHelpers
|
2
|
+
|
3
|
+
#
|
4
|
+
# @see default.html for example usage.
|
5
|
+
#
|
6
|
+
def nandoc_sitemap binding, name=nil, &block
|
7
|
+
name ||= SiteMap.next_unique_name
|
8
|
+
SiteMap.singleton(name, binding, &block).render_parent
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
#
|
14
|
+
class SiteMap
|
15
|
+
extend BlockAttrAccessor, NanDoc::SharedAttrReader
|
16
|
+
include NanDoc::SecretParent
|
17
|
+
module Glyphs; end # forward declaration
|
18
|
+
include Glyphs
|
19
|
+
@singletons = {}
|
20
|
+
@next_unique_name = -1
|
21
|
+
class << self
|
22
|
+
def next_unique_name
|
23
|
+
@next_unique_name += 1
|
24
|
+
@next_unique_name
|
25
|
+
end
|
26
|
+
def singleton(name, binding, &block)
|
27
|
+
@singletons[name] ||= begin
|
28
|
+
sing = new
|
29
|
+
sing.init_root(binding, &block)
|
30
|
+
sing
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def initialize
|
35
|
+
@tab = ' '
|
36
|
+
end
|
37
|
+
attr_accessor :glyphs, :item, :is_first, :is_last,
|
38
|
+
:root_identifier, :tabs, :tab
|
39
|
+
attr_reader :level
|
40
|
+
block_attr_accessor :children, :render_child # defines *_proc
|
41
|
+
shared_attr_reader :children_proc, :glyphs, :tab, :render_child_proc,
|
42
|
+
:render_parent_proc # children will access root nodes's attrs for these
|
43
|
+
|
44
|
+
def init_root binding, &block
|
45
|
+
block.call(self)
|
46
|
+
@is_first = @is_last = true
|
47
|
+
@level = 0
|
48
|
+
@item = nil
|
49
|
+
@tabs ||= 0
|
50
|
+
root = eval('@items',binding).find{|x| x.identifier == root_identifier}
|
51
|
+
children_populate_recursive [root]
|
52
|
+
end
|
53
|
+
def init_child parent, item
|
54
|
+
self.parent = parent
|
55
|
+
@item = item
|
56
|
+
self.shared = parent.shared # this does a lot, see SharedAttrReader
|
57
|
+
@level = parent.level + 1
|
58
|
+
@tabs = parent.tabs + 1
|
59
|
+
cx = children_proc.call(@item)
|
60
|
+
children_populate_recursive cx
|
61
|
+
end
|
62
|
+
def children_populate_recursive cx
|
63
|
+
if cx.any? # keep our @children nil unless we have any children
|
64
|
+
last_idx = cx.size - 1
|
65
|
+
@children = cx.each.with_index.map do |item, idx|
|
66
|
+
map = self.class.new
|
67
|
+
map.is_first = idx == 0
|
68
|
+
map.is_last = idx == last_idx
|
69
|
+
map.init_child self, item
|
70
|
+
map
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def merge_opts opts
|
76
|
+
fail("just for setting tabs for now") unless opts.keys == [:tabs]
|
77
|
+
@tabs = opts[:tabs]
|
78
|
+
opts
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [String] <ul> for e.g. Sets block if given.
|
82
|
+
def render_parent &block
|
83
|
+
if block_given?
|
84
|
+
@render_parent_proc = block
|
85
|
+
class << self
|
86
|
+
attr_accessor :render_parent_proc
|
87
|
+
end
|
88
|
+
nil
|
89
|
+
elsif @children.nil?
|
90
|
+
nil
|
91
|
+
else
|
92
|
+
h1 = render_parent_proc.call(self)
|
93
|
+
h2 = reindent(h1).strip
|
94
|
+
h2
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [String] chunk of <li's> for eg.
|
99
|
+
def render_children opts={}
|
100
|
+
these = @children.map do |map|
|
101
|
+
map.merge_opts opts
|
102
|
+
h1 = render_child_proc.call(map)
|
103
|
+
h2 = map.reindent(h1)
|
104
|
+
h3 = h2.strip
|
105
|
+
h3
|
106
|
+
end
|
107
|
+
last = @children.last
|
108
|
+
hz = these.join("\n" + last.tab * last.tabs) if last
|
109
|
+
hz
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
module SiteMap::Glyphs
|
114
|
+
# http://www.alanwood.net/unicode/box_drawing.html
|
115
|
+
Blank = ' '
|
116
|
+
DownLf = '┐' # ┐
|
117
|
+
DownRt = '┌' # ┌
|
118
|
+
HvVtLf = '┫' # ┫
|
119
|
+
HvVert = '┃' # ┃
|
120
|
+
UpLeft = '┘' # ┘
|
121
|
+
UpRite = '└' # └
|
122
|
+
Vertic = '│' # │
|
123
|
+
VertLf = '┤' # ┤
|
124
|
+
VertRt = '├' # ├
|
125
|
+
VtHori = '┼' # ┼
|
126
|
+
ArcUpL = '╯' # ╯
|
127
|
+
DashQV =' ┊' # ┊
|
128
|
+
|
129
|
+
UseThisForBlanks = proc{|node| DashQV }
|
130
|
+
# DashQV is nice b/c fixed width
|
131
|
+
|
132
|
+
def glyphs_right_for_child
|
133
|
+
@glyphs_right_for_child ||= begin
|
134
|
+
case level
|
135
|
+
when 0; [] # e.g. the object that is rendering [home]
|
136
|
+
when 1; [] # e.g. home, the (lvl2) children have no inheirited
|
137
|
+
else
|
138
|
+
x = [ is_last ? UseThisForBlanks.call(self) : HvVert ]
|
139
|
+
x.concat(parent.glyphs_right_for_child) if parent
|
140
|
+
x
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def glyphs_right
|
146
|
+
case level
|
147
|
+
when 0; fail('never')
|
148
|
+
when 1; ''
|
149
|
+
else
|
150
|
+
these = [ is_last ? ArcUpL : HvVtLf ]
|
151
|
+
these.concat( parent.glyphs_right_for_child ) if parent
|
152
|
+
# these.concat Array.new([0, level-1].max, DashQV)
|
153
|
+
these.join('')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module NanDoc::Helpers::NanDocHelpers
|
2
|
+
|
3
|
+
#
|
4
|
+
# nandoc_topnav do |sm|
|
5
|
+
# sm.binding = binding
|
6
|
+
# sm.item { |i| <<-H
|
7
|
+
# <span class='nanoc-sidebar-h2'>#{i.nandoc_title}</span>
|
8
|
+
# H
|
9
|
+
# }
|
10
|
+
# sm.current_item { |i| <<-H
|
11
|
+
# <span class='nanoc-sidebar-h2'>#{i.nandoc_title}</span>
|
12
|
+
# H
|
13
|
+
# }
|
14
|
+
# sm.separator { <<-H
|
15
|
+
# <span class='nanoc-sep'>❧</span>
|
16
|
+
# H
|
17
|
+
# }
|
18
|
+
#
|
19
|
+
|
20
|
+
def nandoc_topnav &block
|
21
|
+
TopNav.new(&block).render
|
22
|
+
end
|
23
|
+
|
24
|
+
class TopNav
|
25
|
+
extend BlockAttrAccessor
|
26
|
+
def initialize(&b)
|
27
|
+
block_attr_accessor_init
|
28
|
+
@current_item = @items = @item = nil
|
29
|
+
b.call(self)
|
30
|
+
end
|
31
|
+
block_attr_accessor :current_item, :item, :separator
|
32
|
+
attr_accessor :binding
|
33
|
+
def render
|
34
|
+
item = eval('@item', @binding)
|
35
|
+
temdoz = [@current_item_proc.call(item)]
|
36
|
+
while item = item.parent
|
37
|
+
temdoz.concat [@separator_proc.call, @item_proc.call(item)]
|
38
|
+
end
|
39
|
+
temdoz.reverse
|
40
|
+
end
|
41
|
+
class << self
|
42
|
+
def home_page &b
|
43
|
+
@home_page ||= b.call
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module NanDoc::Helpers
|
2
|
+
module NanDocHelpers
|
3
|
+
# @todo-now test this
|
4
|
+
include NanDoc::StringFormatting # indent() unindent() no_blank_lines()
|
5
|
+
module BlockAttrAccessor
|
6
|
+
attr_accessor :block_attr_accessors
|
7
|
+
class << self
|
8
|
+
def extended mod
|
9
|
+
mod.instance_variable_set('@block_attr_accessors', []) unless
|
10
|
+
mod.instance_variable_defined?('@block_attr_accessors')
|
11
|
+
mod.send(:define_method, :block_attr_accessor_init) do
|
12
|
+
self.class.block_attr_accessors.each do |name|
|
13
|
+
instance_variable_set("@#{name}_proc",nil) unless
|
14
|
+
instance_variable_defined?("@#{name}_proc")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
def block_attr_accessor *names
|
20
|
+
names.each do |setter_name|
|
21
|
+
@block_attr_accessors.push(setter_name) # etc
|
22
|
+
attr_name = "@#{setter_name}_proc"
|
23
|
+
getter_name = "#{setter_name}_proc"
|
24
|
+
define_method(setter_name) do |&block|
|
25
|
+
raise ArgumentError.new(
|
26
|
+
"no block given for #{self.class}##{setter_name}"
|
27
|
+
) unless block
|
28
|
+
instance_variable_set attr_name, block
|
29
|
+
end
|
30
|
+
define_method(getter_name) do
|
31
|
+
instance_variable_get attr_name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
here = File.dirname(__FILE__)+'/helpers'
|
40
|
+
require here + '/menu-bouncy.rb'
|
41
|
+
require here + '/site-map.rb'
|
42
|
+
require here + '/top-nav.rb'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Nanoc3::Item
|
2
|
+
#
|
3
|
+
# hacks we use for stuff like sitemap and topnav generation
|
4
|
+
#
|
5
|
+
class << self
|
6
|
+
def sorted_visible_children
|
7
|
+
@svc ||= begin
|
8
|
+
proc do |node|
|
9
|
+
node.children.select{|c| c.nandoc_visible? }.sort_by(&:nandoc_title)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
include NanDoc::StringFormatting # basename_no_extension()
|
17
|
+
|
18
|
+
attr_accessor :identifier # know what you are doing if you set it
|
19
|
+
|
20
|
+
#
|
21
|
+
# come up with some title by any means necessary
|
22
|
+
#
|
23
|
+
def nandoc_title
|
24
|
+
if @attributes[:title]
|
25
|
+
@attributes[:title]
|
26
|
+
elsif ! nandoc_content_node?
|
27
|
+
identifier
|
28
|
+
elsif no_ext = basename_no_extension(@attributes[:content_filename])
|
29
|
+
no_ext.gsub(/[-_]/, ' ') # we could do wiki-name like crap
|
30
|
+
elsif ! (foo = File.basename(@attributes[:content_filename])).empty?
|
31
|
+
foo
|
32
|
+
else
|
33
|
+
identifier == '/' ? 'HOME' : identifier.gsub('/',' - ')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def nandoc_content_node?
|
38
|
+
/\A\/(?:css|js|vendor)\// !~ identifier # @todo will have to change!
|
39
|
+
end
|
40
|
+
|
41
|
+
def nandoc_content_leaf?
|
42
|
+
nandoc_content_node? # hm
|
43
|
+
end
|
44
|
+
|
45
|
+
def nandoc_content_branch?
|
46
|
+
false # hm
|
47
|
+
end
|
48
|
+
|
49
|
+
def nandoc_sorted_visible_children
|
50
|
+
self.class.sorted_visible_children.call(self)
|
51
|
+
end
|
52
|
+
|
53
|
+
def nandoc_visible?
|
54
|
+
!self[:hidden] && path && nandoc_content_node?
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module NanDoc
|
2
|
+
class ParseReadme
|
3
|
+
#
|
4
|
+
# If you are really really crazy then you don't like
|
5
|
+
# repeating yourself between your gemspec and your README with regard to
|
6
|
+
# the project summary and description.
|
7
|
+
#
|
8
|
+
# This is a quick and dirty hack to parse your README (or similary
|
9
|
+
# formatted file) in a really rough way for when you are building your
|
10
|
+
# gemspec -- it doesn't use a markdown parser or whatever. It scans the
|
11
|
+
# README file for a line like "## Summary" and reads the next line with
|
12
|
+
# content after it. (ditto "## Description" etc.)
|
13
|
+
#
|
14
|
+
# See the Rakefile of this project for example usage.
|
15
|
+
#
|
16
|
+
# @see note below near 'jeweler'
|
17
|
+
#
|
18
|
+
|
19
|
+
def initialize(path=nil, &block)
|
20
|
+
@parsed_content = {}
|
21
|
+
@lines = nil
|
22
|
+
@path = path and get_lines!
|
23
|
+
instance_eval(&block) if block_given?
|
24
|
+
end
|
25
|
+
class << self
|
26
|
+
alias_method :parse, :new
|
27
|
+
def description file
|
28
|
+
DeferredParse.new(file, :description)
|
29
|
+
end
|
30
|
+
def summary file
|
31
|
+
DeferredParse.new(file, :summary)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
attr_accessor :lines
|
35
|
+
def path name
|
36
|
+
@path = name
|
37
|
+
get_lines!
|
38
|
+
name
|
39
|
+
end
|
40
|
+
def parse_section *names
|
41
|
+
names.each do |name|
|
42
|
+
re = /\A#* ?#{Regexp.escape(name.to_s)}\Z/i
|
43
|
+
idx = (@lines.index{|x| re =~ x } or
|
44
|
+
fail("#{name.to_s.inspect} section not found in #{path}")) + 1
|
45
|
+
idx += 1 while @lines[idx] && /\A[[:space:]]+\Z/ =~ @lines[idx]
|
46
|
+
line = @lines[idx] or
|
47
|
+
fail("couldn't find content following #{name.to_s} section")
|
48
|
+
@parsed_content[name] = line.strip
|
49
|
+
class << self; self end.send(:define_method, name) do
|
50
|
+
@parsed_content[name]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
alias_method :parse_sections, :parse_section
|
56
|
+
private
|
57
|
+
def get_lines!
|
58
|
+
@lines = File.open(@path).lines.map
|
59
|
+
end
|
60
|
+
class DeferredParse
|
61
|
+
#
|
62
|
+
# This whole thing is a ridiculously fragile and secret hack
|
63
|
+
# that is maybe pointless @todo
|
64
|
+
# The point is to defer opening and parsing the README file unless
|
65
|
+
# necessary. (But it didn't work as intended, but no big deal.)
|
66
|
+
#
|
67
|
+
# If you use it is is recommended that you use jeweler and the
|
68
|
+
# gemspec:debug task to check its work.
|
69
|
+
#
|
70
|
+
|
71
|
+
@files = {}
|
72
|
+
class << self
|
73
|
+
attr_reader :files
|
74
|
+
end
|
75
|
+
def initialize path, section
|
76
|
+
@path, @section = path, section
|
77
|
+
@as_string = nil
|
78
|
+
end
|
79
|
+
def strip
|
80
|
+
as_string.strip
|
81
|
+
end
|
82
|
+
def to_s
|
83
|
+
as_string # can't simply alias it b/c it is private
|
84
|
+
end
|
85
|
+
private
|
86
|
+
def as_string
|
87
|
+
@as_string ||= begin
|
88
|
+
parse = (self.class.files[@path] ||= ParseReadme.new(@path))
|
89
|
+
parse.parse_section(@section) unless parse.respond_to?(@section)
|
90
|
+
parse.send(@section)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
File without changes
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require File.expand_path('../../test/minitest-extlib.rb', __FILE__)
|
3
|
+
|
4
|
+
module NanDoc::SpecDoc::MiniTest
|
5
|
+
class Proxy < ::NanDoc::SpecDoc::TestFrameworkProxy
|
6
|
+
|
7
|
+
def initialize(*a)
|
8
|
+
super(*a)
|
9
|
+
@hacked_minitest = false
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
#
|
15
|
+
# given
|
16
|
+
# @param [String] the natural sounding string name as it appears in
|
17
|
+
# documentation,
|
18
|
+
# @return [Array] a pair of strings: suite name and method name
|
19
|
+
#
|
20
|
+
def find_test str
|
21
|
+
meth_tail = str.gsub(/\W+/, '_').downcase
|
22
|
+
# i *think* we want *not* to escape it below
|
23
|
+
filter = /\Atest_\d{4}_#{meth_tail}\Z/
|
24
|
+
found_meths = []
|
25
|
+
found_pairs = []
|
26
|
+
::MiniTest::Unit::TestCase.test_suites.each do |suite|
|
27
|
+
if (foundfound = suite.test_methods.grep(filter)).any?
|
28
|
+
found_pairs.push [suite, foundfound]
|
29
|
+
found_meths.concat foundfound
|
30
|
+
end
|
31
|
+
end
|
32
|
+
case found_meths.size
|
33
|
+
when 0;
|
34
|
+
fail("no tests were found whose name matches the pattern #{filter}")
|
35
|
+
when 1;
|
36
|
+
ff = found_pairs.first
|
37
|
+
[ff[0], ff[1][0]] # suite and method name
|
38
|
+
else
|
39
|
+
fail("found more than one test matching the pattern for \"#{str}\""<<
|
40
|
+
" -- (#{found_meths.join(', ')})")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# do whatever you have to do to prepare minitest to run nandoc-enabled
|
46
|
+
# tests
|
47
|
+
#
|
48
|
+
def hack_minitest
|
49
|
+
return if @hacked_minitest
|
50
|
+
@testout = StringIO.new
|
51
|
+
::MiniTest::Unit.output = @testout
|
52
|
+
# this is set but ignored which is ok. it gets method names and dots
|
53
|
+
sing = class << ::MiniTest::Unit; self end
|
54
|
+
sing.send(:define_method, :autorun){ } # override it to do nothing!!
|
55
|
+
@hacked_minitest = true
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# given
|
60
|
+
# @param [String] testfile name (just semantic not formal)
|
61
|
+
# @param [String] testname (just semantic not formal)
|
62
|
+
# @param [String] a test case name and
|
63
|
+
# @param [String] a method name,
|
64
|
+
# run the test in question which will hopefully write to the recordings
|
65
|
+
# experimentally
|
66
|
+
# @return an exit status of 0 if everything's ok
|
67
|
+
#
|
68
|
+
def run_test_case_method testfile, testname, test_case, meth_name
|
69
|
+
hack_minitest unless @hacked_minitest
|
70
|
+
unambig_re = /\A#{Regexp.escape(meth_name)}\Z/
|
71
|
+
runner = ::MiniTest::Unit.new
|
72
|
+
runner.instance_variable_set('@verbose', true)
|
73
|
+
test_count, ass_count = runner.run_test_suites unambig_re
|
74
|
+
fail("didn't run any tests for #{unambig_re.source}") unless
|
75
|
+
test_count == 1
|
76
|
+
if runner.report.any?
|
77
|
+
return handle_failed_tests(runner, testfile, testname)
|
78
|
+
end
|
79
|
+
return 0
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
#
|
85
|
+
# These are the methods that will be available to nandoc-enhanced tests.
|
86
|
+
# For now it is recommended to leave this as just the one method nandoc(),
|
87
|
+
# which will return the TestCaseAgent.
|
88
|
+
#
|
89
|
+
module SpecInstanceMethods
|
90
|
+
class << self
|
91
|
+
def include_to mod
|
92
|
+
unless mod.ancestors.include?(::MiniTest::Spec)
|
93
|
+
fail(
|
94
|
+
"Sorry, for now SpecDoc can only extend MiniTest::Spec "<<
|
95
|
+
" tests. Couldn't extend #{mod}."
|
96
|
+
)
|
97
|
+
end
|
98
|
+
mod.send(:include, self)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
def nandoc
|
102
|
+
@nandoc_agent ||= ::NanDoc::SpecDoc::TestCaseAgent.new(self)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|