jsus 0.3.1 → 0.3.2
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/.document +1 -1
- data/.travis.yml +1 -1
- data/.yardopts +9 -0
- data/CHANGELOG +21 -0
- data/Gemfile +3 -2
- data/{README → README.md} +10 -4
- data/TODO +1 -3
- data/VERSION +1 -1
- data/bin/jsus +33 -10
- data/jsus.gemspec +12 -7
- data/lib/jsus.rb +31 -9
- data/lib/jsus/container.rb +96 -24
- data/lib/jsus/middleware.rb +160 -43
- data/lib/jsus/package.rb +65 -25
- data/lib/jsus/packager.rb +15 -10
- data/lib/jsus/pool.rb +54 -40
- data/lib/jsus/source_file.rb +105 -80
- data/lib/jsus/tag.rb +65 -39
- data/lib/jsus/util.rb +8 -6
- data/lib/jsus/util/code_generator.rb +21 -0
- data/lib/jsus/util/documenter.rb +34 -6
- data/lib/jsus/util/file_cache.rb +16 -5
- data/lib/jsus/util/inflection.rb +9 -2
- data/lib/jsus/util/tree.rb +54 -18
- data/lib/jsus/util/validator/base.rb +13 -5
- data/lib/jsus/util/validator/mooforge.rb +8 -2
- data/markup/stylesheet.css +84 -16
- data/spec/data/ChainDependencies/app/javascripts/Class/package.yml +2 -2
- data/spec/jsus/middleware_spec.rb +25 -0
- data/spec/jsus/pool_spec.rb +9 -4
- metadata +23 -7
data/lib/jsus/util/tree.rb
CHANGED
@@ -6,8 +6,7 @@ module Jsus
|
|
6
6
|
# structure (with node names like /namespace/inner/item) and supporting
|
7
7
|
# lookups via #glob method.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# @example
|
11
10
|
# tree = Jsus::Tree.new
|
12
11
|
# tree["/folder/item_0"] = "Hello"
|
13
12
|
# tree["/folder/item_1"] = "World"
|
@@ -29,6 +28,7 @@ module Jsus
|
|
29
28
|
|
30
29
|
# Splits path into components
|
31
30
|
# Jsus::Tree.components_from_path("/hello/world") # => ["hello", "world"]
|
31
|
+
# @api semipublic
|
32
32
|
def components_from_path(path)
|
33
33
|
raise "Empty path given: #{path.inspect}" if !path || path == ""
|
34
34
|
path = path.to_s.dup
|
@@ -68,23 +68,31 @@ module Jsus
|
|
68
68
|
attr_reader :name
|
69
69
|
# Assigns node's full path and automatically deduces path components,
|
70
70
|
# basename etc.
|
71
|
+
# @api semipublic
|
71
72
|
def full_path=(full_path)
|
72
73
|
@full_path = full_path
|
73
74
|
@path_components = Tree.get_path_components(full_path)
|
74
75
|
@name = @path_components[-1]
|
75
76
|
end
|
76
77
|
|
77
|
-
#
|
78
|
+
# @return [Array] node's direct descendants
|
79
|
+
# @api public
|
78
80
|
def children
|
79
81
|
@children ||= []
|
80
82
|
end
|
81
83
|
|
82
|
-
#
|
84
|
+
# @param [String] basename
|
85
|
+
# @return [Jsus::Util::Tree::Node] direct node child with given basename
|
86
|
+
# @api public
|
83
87
|
def find_child(name)
|
84
88
|
children.detect {|child| child.name == name }
|
85
89
|
end
|
86
90
|
|
87
91
|
# Creates a child with given name and value
|
92
|
+
# @param [String] node name
|
93
|
+
# @param [Object] value
|
94
|
+
# @return [Jsus::Util::Tree::Node]
|
95
|
+
# @api public
|
88
96
|
def create_child(name, value = nil)
|
89
97
|
full_path = Tree.path_from_components(path_components + [name])
|
90
98
|
node = Node.new(full_path, value)
|
@@ -94,7 +102,11 @@ module Jsus
|
|
94
102
|
end
|
95
103
|
|
96
104
|
# Finds a child with given name or creates a child with given name and
|
97
|
-
# value
|
105
|
+
# value.
|
106
|
+
#
|
107
|
+
# @param [String] name
|
108
|
+
# @param [Object] value
|
109
|
+
# @api public
|
98
110
|
def find_or_create_child(name, value = nil)
|
99
111
|
find_child(name) || create_child(name, value)
|
100
112
|
end
|
@@ -105,7 +117,10 @@ module Jsus
|
|
105
117
|
# 'smth*' -- nodes beginning with smth
|
106
118
|
# 'smth*else' -- nodes beginning with smth and ending with else
|
107
119
|
# <string without asterisks> -- plain node lookup by name
|
108
|
-
#
|
120
|
+
#
|
121
|
+
# @param [String] pathspec
|
122
|
+
# @return [Array] array with search results
|
123
|
+
# @api public
|
109
124
|
def find_children_matching(pathspec)
|
110
125
|
case pathspec
|
111
126
|
when "**"
|
@@ -118,18 +133,23 @@ module Jsus
|
|
118
133
|
end
|
119
134
|
end
|
120
135
|
|
121
|
-
#
|
136
|
+
# @return [Boolean] whether this node has children
|
137
|
+
# @api public
|
122
138
|
def has_children?
|
123
139
|
!children.empty?
|
124
140
|
end
|
125
141
|
end
|
126
142
|
|
127
|
-
#
|
143
|
+
# @return [Jsus::Util::Tree::Node] root node of the tree
|
144
|
+
# @api public
|
128
145
|
def root
|
129
146
|
@root ||= Node.new("/", nil)
|
130
147
|
end
|
131
148
|
|
132
149
|
# Looks up a node by direct path. Does not support wildcards
|
150
|
+
# @param [String] path
|
151
|
+
# @return [Jsus::Util::Tree::Node]
|
152
|
+
# @api public
|
133
153
|
def lookup(path)
|
134
154
|
path_components = self.class.get_path_components(path)
|
135
155
|
path_components.inject(root) do |result, component|
|
@@ -139,6 +159,11 @@ module Jsus
|
|
139
159
|
end
|
140
160
|
end
|
141
161
|
|
162
|
+
# @see lookup
|
163
|
+
# @param [String] path
|
164
|
+
# @return [Jsus::Util::Tree::Node]
|
165
|
+
# @note returns nil when node has no assigned value
|
166
|
+
# @api public
|
142
167
|
def [](path)
|
143
168
|
node = lookup(path)
|
144
169
|
node ? node.value : nil
|
@@ -147,20 +172,28 @@ module Jsus
|
|
147
172
|
|
148
173
|
|
149
174
|
# Searches for nodes by a given pathspec
|
150
|
-
#
|
175
|
+
# @see Jsus::Util::Tree::Node#find_children_matching for more details
|
176
|
+
# @param [String] pathspec
|
177
|
+
# @return [Array] nodes for given pathspec
|
178
|
+
# @api semipublic
|
151
179
|
def find_nodes_matching(pathspec)
|
152
180
|
self.class.get_path_components(pathspec).inject([root]) do |nodes, component|
|
153
181
|
nodes.map {|node| node.find_children_matching(component) }.flatten
|
154
182
|
end
|
155
183
|
end
|
156
184
|
|
157
|
-
#
|
158
|
-
#
|
185
|
+
# @param [String] pathspec
|
186
|
+
# @return [Array] values for nodes matching given pathspec
|
187
|
+
# @see Jsus::Util::Tree::Node#find_children_matching for more details
|
188
|
+
# @api public
|
159
189
|
def glob(pathspec)
|
160
190
|
find_nodes_matching(pathspec).map {|node| node.value }
|
161
191
|
end
|
162
192
|
|
163
193
|
# Inserts a node with given value into the tree
|
194
|
+
# @param [String] full node path
|
195
|
+
# @param [Object] value
|
196
|
+
# @api public
|
164
197
|
def insert(full_path, value = nil)
|
165
198
|
node = create_all_nodes_if_needed(full_path)
|
166
199
|
node.value = value
|
@@ -168,9 +201,10 @@ module Jsus
|
|
168
201
|
end
|
169
202
|
alias_method :[]=, :insert
|
170
203
|
|
171
|
-
# Traverses the tree.
|
172
|
-
#
|
173
|
-
#
|
204
|
+
# Traverses the tree (BFS).
|
205
|
+
# @param [Boolean] whether to traverse non-leaves nodes
|
206
|
+
# @yield traversed node
|
207
|
+
# @api public
|
174
208
|
def traverse(all_nodes = false)
|
175
209
|
node_list = [root]
|
176
210
|
while !node_list.empty?
|
@@ -180,8 +214,9 @@ module Jsus
|
|
180
214
|
end
|
181
215
|
end
|
182
216
|
|
183
|
-
#
|
184
|
-
#
|
217
|
+
# @param [Boolean] whether to return only leaves with values
|
218
|
+
# @return [Array] list of leaves
|
219
|
+
# @api public
|
185
220
|
def leaves(only_with_value = true)
|
186
221
|
result = []
|
187
222
|
traverse {|node| result << node if !only_with_value || node.value }
|
@@ -190,7 +225,8 @@ module Jsus
|
|
190
225
|
|
191
226
|
protected
|
192
227
|
|
193
|
-
|
228
|
+
# @api private
|
229
|
+
def create_all_nodes_if_needed(full_path)
|
194
230
|
self.class.get_path_components(full_path).inject(root) do |result, component|
|
195
231
|
result.find_or_create_child(component)
|
196
232
|
end
|
@@ -198,4 +234,4 @@ module Jsus
|
|
198
234
|
|
199
235
|
end
|
200
236
|
end
|
201
|
-
end
|
237
|
+
end
|
@@ -5,17 +5,21 @@ module Jsus
|
|
5
5
|
class Base
|
6
6
|
# Constructor accepts pool or array or container and adds every file
|
7
7
|
# to its source files set.
|
8
|
+
# @param [Jsus::Pool, Jsus::Container, Array] source files to validate
|
9
|
+
# @api public
|
8
10
|
def initialize(pool_or_array_or_container)
|
9
11
|
self.source_files = pool_or_array_or_container
|
10
12
|
end
|
11
13
|
|
12
|
-
#
|
14
|
+
# @return [Array] source files for validation
|
15
|
+
# @api public
|
13
16
|
def source_files
|
14
17
|
@source_files ||= []
|
15
18
|
end
|
16
19
|
alias_method :sources, :source_files
|
17
20
|
|
18
|
-
#
|
21
|
+
# @param [Jsus::Pool, Jsus::Container, Array] source files for validation
|
22
|
+
# @api public
|
19
23
|
def source_files=(pool_or_array_or_container)
|
20
24
|
case pool_or_array_or_container
|
21
25
|
when Pool
|
@@ -28,21 +32,25 @@ module Jsus
|
|
28
32
|
end
|
29
33
|
alias_method :sources=, :source_files=
|
30
34
|
|
31
|
-
#
|
35
|
+
# @return [Boolean] whether or not given sources conform to given set of rules
|
36
|
+
# @api public
|
32
37
|
def validate
|
33
38
|
validation_errors.empty?
|
34
39
|
end
|
35
40
|
|
36
|
-
#
|
41
|
+
# @return [Array] list of validation errors
|
42
|
+
# @override
|
37
43
|
def validation_errors
|
38
44
|
[]
|
39
45
|
end
|
40
46
|
|
41
47
|
# Shortcut for creating and validating a list of items
|
48
|
+
# @param [*Array] args for #new
|
49
|
+
# @api public
|
42
50
|
def self.validate(*args)
|
43
51
|
new(*args).validate
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end # Util
|
48
|
-
end
|
56
|
+
end
|
@@ -6,7 +6,13 @@ module Jsus
|
|
6
6
|
# * Presence of authors field
|
7
7
|
# * Presence of license field
|
8
8
|
class Mooforge < Base
|
9
|
-
|
9
|
+
# Mooforge validator checks every file for the following:
|
10
|
+
# * Presence of header
|
11
|
+
# * Presence of authors field
|
12
|
+
# * Presence of license field
|
13
|
+
# @return [Array] list oferrors
|
14
|
+
# @api public
|
15
|
+
def validation_errors
|
10
16
|
@validation_errors ||= sources.inject([]) do |result, sf|
|
11
17
|
if !sf.header
|
12
18
|
result << "#{sf.filename} is missing header"
|
@@ -22,4 +28,4 @@ module Jsus
|
|
22
28
|
end
|
23
29
|
end
|
24
30
|
end # Util
|
25
|
-
end
|
31
|
+
end
|
data/markup/stylesheet.css
CHANGED
@@ -6,6 +6,10 @@ p, h1, h2, h3, ol, li, ul, dt, dd, dl, body, html {
|
|
6
6
|
padding: 0;
|
7
7
|
margin: 0; }
|
8
8
|
|
9
|
+
p + br {
|
10
|
+
display: none;
|
11
|
+
}
|
12
|
+
|
9
13
|
body {
|
10
14
|
width: 40%;
|
11
15
|
padding-left: 2.5%;
|
@@ -27,7 +31,7 @@ body > * {
|
|
27
31
|
padding-right: 6%; }
|
28
32
|
|
29
33
|
html {
|
30
|
-
background: #
|
34
|
+
background: #FFC873; }
|
31
35
|
|
32
36
|
header {
|
33
37
|
background: rgba(255, 255, 255, 0.1);
|
@@ -41,10 +45,23 @@ header {
|
|
41
45
|
width: 5em;
|
42
46
|
font-weight: bold; }
|
43
47
|
|
44
|
-
section
|
48
|
+
section {
|
45
49
|
float: left;
|
46
50
|
clear: both;
|
47
|
-
width:
|
51
|
+
width: 85%; }
|
52
|
+
|
53
|
+
section iframe {
|
54
|
+
width: 260%;
|
55
|
+
height: 250px;
|
56
|
+
border: 1px solid #333;
|
57
|
+
margin-bottom: 1em;
|
58
|
+
margin-top: 1.5em;
|
59
|
+
}
|
60
|
+
|
61
|
+
section iframe.high {
|
62
|
+
height: 300px;
|
63
|
+
}
|
64
|
+
|
48
65
|
|
49
66
|
p, dl, li {
|
50
67
|
color: #665504;
|
@@ -57,12 +74,42 @@ a {
|
|
57
74
|
a:visited {
|
58
75
|
color: #A64E00; }
|
59
76
|
|
60
|
-
p {
|
77
|
+
p + p, h2 + p, h1 + p, ul + p, ol + p{
|
61
78
|
margin-top: 1.5em; }
|
62
79
|
|
80
|
+
p code {
|
81
|
+
background-color: rgba(200, 220, 200, 0.2);
|
82
|
+
display: inline-block;
|
83
|
+
-moz-border-radius: 4px;
|
84
|
+
-webkit-border-radius: 4px;
|
85
|
+
border-radius: 4px;
|
86
|
+
padding: 0 0.2em;
|
87
|
+
font-family: "monaco", "Courier New", Courier, monospace, serif;
|
88
|
+
font-size:0.8em;
|
89
|
+
line-height:1.5em;
|
90
|
+
}
|
91
|
+
p:last-child {
|
92
|
+
margin-bottom: 1.5em;
|
93
|
+
}
|
94
|
+
|
63
95
|
h1 {
|
64
96
|
font-size: 2em; }
|
65
97
|
|
98
|
+
h1 + ul {
|
99
|
+
float: right;
|
100
|
+
width: 140%;
|
101
|
+
margin-right: -160%;
|
102
|
+
margin-top: -2em;
|
103
|
+
}
|
104
|
+
|
105
|
+
h1 + ul li {
|
106
|
+
display: inline;
|
107
|
+
}
|
108
|
+
|
109
|
+
h1 + ul li + li{
|
110
|
+
margin-left: 1em;
|
111
|
+
}
|
112
|
+
|
66
113
|
h2 {
|
67
114
|
font-size: 1em; }
|
68
115
|
|
@@ -72,13 +119,18 @@ h1, h2, h3 {
|
|
72
119
|
ol, li {
|
73
120
|
margin-left: 1em; }
|
74
121
|
|
75
|
-
body > p, body > h1
|
122
|
+
body > p, body > h1 {
|
76
123
|
clear: left; }
|
77
124
|
|
125
|
+
body > h2 {
|
126
|
+
clear: both;
|
127
|
+
}
|
128
|
+
|
78
129
|
header {
|
79
130
|
padding-bottom: 1em;
|
80
131
|
overflow: hidden; }
|
81
132
|
|
133
|
+
|
82
134
|
dl {
|
83
135
|
clear: left; }
|
84
136
|
dl dt, dl dd {
|
@@ -91,29 +143,45 @@ dl {
|
|
91
143
|
figure {
|
92
144
|
display: block;
|
93
145
|
float: right;
|
94
|
-
margin-right: -
|
146
|
+
margin-right: -135%;
|
95
147
|
width: 122.75%;
|
96
148
|
clear: right;
|
97
|
-
|
149
|
+
margin-top: -0.1em;
|
150
|
+
padding: 0 0 3em; }
|
98
151
|
figure > ol {
|
99
|
-
|
100
|
-
|
101
|
-
-
|
152
|
+
font-family: 0.75em/2.25em Arial;
|
153
|
+
text-shadow: 0 1px 0 #eee;
|
154
|
+
-moz-text-shadow: 0 1px 0 #eee;
|
155
|
+
-webkit-text-shadow: 0 1px 0 #eee;
|
156
|
+
box-shadow: 0 1px 2px #333;
|
157
|
+
-moz-box-shadow: 0 1px 2px #333;
|
158
|
+
-webkit-box-shadow: 0 1px 2px #333;
|
102
159
|
width: 7.5%;
|
103
160
|
text-align: right;
|
104
161
|
float: left;
|
105
|
-
|
162
|
+
-moz-border-radius: 0.2em;
|
106
163
|
-webkit-border-radius: 0.2em;
|
107
|
-
|
108
|
-
border: 1px solid rgba(0, 0, 0, 0.
|
164
|
+
border-radius: 0.2em;
|
165
|
+
border: 1px solid rgba(0, 0, 0, 0.5);
|
109
166
|
list-style: none;
|
110
167
|
margin-left: -9.25%; }
|
111
168
|
figure > ol li {
|
169
|
+
background: rgba(125, 125, 125, 0.4);
|
112
170
|
margin: 0; }
|
113
|
-
|
114
|
-
|
115
|
-
|
171
|
+
figure > ol li:first-child {
|
172
|
+
border-top-left-radius: 0.2em;
|
173
|
+
border-top-right-radius: 0.2em; }
|
174
|
+
figure > ol li:last-child {
|
175
|
+
border-bottom-left-radius: 0.2em;
|
176
|
+
border-bottom-right-radius: 0.2em; }
|
177
|
+
figure > ol li.new {
|
178
|
+
background: #98B72E; }
|
179
|
+
figure > ol li.changed {
|
180
|
+
background: #FFBD40; }
|
116
181
|
figure > code {
|
182
|
+
font-size: 1em;
|
183
|
+
line-height: 1.5em;
|
184
|
+
font-family: "monaco", "Courier New", Courier, monospace, serif;
|
117
185
|
white-space: pre; }
|
118
186
|
|
119
187
|
body .hll {
|
@@ -205,6 +205,31 @@ describe Jsus::Middleware do
|
|
205
205
|
body.index("script: Color.js").should > body.index("script: Core.js")
|
206
206
|
end
|
207
207
|
end
|
208
|
+
|
209
|
+
describe "using /include/ pattern" do
|
210
|
+
let(:path) { "/javascripts/jsus/include/Package:Input.Color.js" }
|
211
|
+
|
212
|
+
it "should be successful" do
|
213
|
+
get(path).should be_successful
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should respond with type text/javascript" do
|
217
|
+
get(path).content_type.should == "text/javascript"
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should contain filenames for required files" do
|
221
|
+
get(path).body.should include("/Color.js")
|
222
|
+
get(path).body.should include("/Input.js")
|
223
|
+
get(path).body.should include("/Input.Color.js")
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should respect :includes_root setting" do
|
227
|
+
old_settings = Jsus::Middleware.settings
|
228
|
+
Jsus::Middleware.settings = {:includes_root => File.expand_path("../../data/ComplexDependencies/Mootools/Source", __FILE__)}
|
229
|
+
get(path).body.should include("../../Source/Library/Color.js")
|
230
|
+
Jsus::Middleware.settings = old_settings
|
231
|
+
end
|
232
|
+
end
|
208
233
|
end
|
209
234
|
|
210
235
|
describe "for invalid paths" do
|