code_terminator 0.5.8 → 0.6.0
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.
- checksums.yaml +4 -4
- data/exercises/html/check_divs_different_attribute_exist.html +13 -0
- data/exercises/html/check_divs_different_attributes_exist_error.html +13 -0
- data/exercises/issue0.html +1 -0
- data/exercises/issue24.html +14 -0
- data/exercises/issue25.html +13 -0
- data/exercises/web_development/lesson1_1.html +1 -0
- data/exercises/web_development/lesson1_2.html +8 -0
- data/exercises/web_development/lesson1_3.html +12 -0
- data/exercises/web_development/lesson1_4.html +9 -0
- data/exercises/web_development/lesson1_5.html +12 -0
- data/exercises/web_development/lesson1_6.html +11 -0
- data/exercises/web_development/lesson1_7.html +13 -0
- data/exercises/web_development/lesson1_challenge.html +26 -0
- data/lib/code_terminator/css.rb +3 -23
- data/lib/code_terminator/html.rb +158 -402
- data/lib/code_terminator/html_deprecated.rb +742 -0
- data/lib/code_terminator/version.rb +1 -1
- metadata +16 -7
- data/exercises/css/lesson0.css +0 -5
- data/exercises/css/lesson0_w.css +0 -5
- data/exercises/css/lesson1_1.css +0 -1
- data/exercises/css/lesson1_2.css +0 -5
- data/exercises/css/lesson1_5.css +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 542fe230e1beb215c850d8ba716a683a370484d1
|
4
|
+
data.tar.gz: b8d7b6ed665073ffb799ed0671a9e250c44ec447
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25d291f5d0676fdaeb941f5fca83841dca82abe79e7e44a256a4cff69c98367d03088fc50d093d97f7fe62b77188f0b717fb268022a8578f360258ee8562f253
|
7
|
+
data.tar.gz: 5621cedfe8f2a56eba87a5c68b42daa820cb6598db7b7cbf0b2812f36e4862318ed3caf1a2df2c73954cf758ac9b9d3a9d519000de137d6661b78e3d734fb534
|
@@ -0,0 +1 @@
|
|
1
|
+
<p></p>
|
@@ -0,0 +1 @@
|
|
1
|
+
<p></p>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<!--This paragraph is Han speaking-->
|
8
|
+
<p>I love to fly my spaceship. My best friend is big and furry. Sometimes I get myself into sticky situations.</p>
|
9
|
+
<!--This paragraph is Chewbacca speaking-->
|
10
|
+
<p>Han is my best friend and he is the only one that understands me when I talk.</p>
|
11
|
+
</body>
|
12
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title></title>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<h1></h1>
|
8
|
+
<p></p>
|
9
|
+
<img src="">
|
10
|
+
|
11
|
+
<h1></h1>
|
12
|
+
<p></p>
|
13
|
+
<img src="">
|
14
|
+
|
15
|
+
<h1></h1>
|
16
|
+
<p></p>
|
17
|
+
<img src="">
|
18
|
+
|
19
|
+
<a href=""></a>
|
20
|
+
<a href=""></a>
|
21
|
+
<a href=""></a>
|
22
|
+
<a href=""></a>
|
23
|
+
<a href=""></a>
|
24
|
+
|
25
|
+
</body>
|
26
|
+
</html>
|
data/lib/code_terminator/css.rb
CHANGED
@@ -208,36 +208,16 @@ class CodeTerminator::Css
|
|
208
208
|
parser.load_string!(code)
|
209
209
|
elements.each do |e|
|
210
210
|
item = e[:selector]
|
211
|
-
if e[:property]
|
211
|
+
if !e[:property].nil?
|
212
212
|
property = e[:property]
|
213
213
|
parser_array = parser.find_by_selector(item)
|
214
214
|
if parser_array.any?
|
215
|
-
# p "array " + parser_array.to_s
|
216
215
|
parser_property = parser_array[0].split(";")
|
217
|
-
|
216
|
+
parser_property.each {|a| a.strip! if a.respond_to? :strip! }
|
218
217
|
|
219
|
-
search_results = parser_property.select { |key| key.include?(property) }
|
220
|
-
if search_results.empty?
|
221
|
-
css_errors << new_error(element: e, type: 111, description: "Make sure the property _#{property}_ is in the selector **#{item}**")
|
222
|
-
end
|
223
|
-
|
224
|
-
|
225
|
-
# parser_property.each do |pp|
|
226
|
-
# p "include " + pp.include?(property).to_s
|
227
|
-
# if !pp.include?(property)
|
228
|
-
# css_errors << new_error(element: e, type: 111, description: "Make sure the property _#{property}_ is in the selector **#{item}**")
|
229
|
-
# end
|
230
|
-
# end
|
231
|
-
|
232
|
-
|
233
|
-
parser_property.each {|a| a.strip! if a.respond_to? :strip! }
|
234
|
-
|
235
|
-
|
236
|
-
# p "value:" + e[:value]
|
237
218
|
if e[:value]==""
|
238
219
|
property = e[:property] + ": "
|
239
|
-
|
240
|
-
if parser_property.empty?
|
220
|
+
if parser_property.empty? { |s| s.include?(property) }
|
241
221
|
css_errors << new_error(element: e, type: 111, description: "Make sure the property _#{property}_ is in the selector **#{item}**")
|
242
222
|
end
|
243
223
|
else
|
data/lib/code_terminator/html.rb
CHANGED
@@ -12,30 +12,6 @@ class CodeTerminator::Html
|
|
12
12
|
@source_type = args[:source_type]
|
13
13
|
end
|
14
14
|
|
15
|
-
# Create a Html file with the code of the editor. Return a boolean that indicate if the file was created or not.
|
16
|
-
#
|
17
|
-
# Example:
|
18
|
-
# >> CodeTerminator::Html.new_file("hola_mundo.html", "<h1>Hola Mundo!</h1>")
|
19
|
-
# => true
|
20
|
-
#
|
21
|
-
# Arguments:
|
22
|
-
# source: (String)
|
23
|
-
# code: (String)
|
24
|
-
|
25
|
-
def new_file(source,code)
|
26
|
-
fileHtml = File.new(source, "w+")
|
27
|
-
result = true
|
28
|
-
begin
|
29
|
-
fileHtml.puts code
|
30
|
-
rescue
|
31
|
-
result = false
|
32
|
-
ensure
|
33
|
-
fileHtml.close unless fileHtml.nil?
|
34
|
-
end
|
35
|
-
#return true if file was succesfully created
|
36
|
-
result
|
37
|
-
end
|
38
|
-
|
39
15
|
|
40
16
|
# Get html elements of a html file. Return a list of Nokogiri XML objects.
|
41
17
|
#
|
@@ -56,16 +32,21 @@ class CodeTerminator::Html
|
|
56
32
|
end
|
57
33
|
#remove empty spaces from reader
|
58
34
|
reader = remove_empty_text(reader)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
35
|
+
if reader.css('html').any?
|
36
|
+
node = Hash.new
|
37
|
+
node[:parent] = ""
|
38
|
+
node[:tag] = "html"
|
39
|
+
node[:pointer] = reader.css('html').first.pointer_id
|
40
|
+
@elements << node
|
41
|
+
end
|
63
42
|
|
64
43
|
#search elements from body section
|
65
44
|
if reader.at('body')
|
66
45
|
node = Hash.new
|
67
46
|
node[:parent] = "html"
|
68
47
|
node[:tag] = "body"
|
48
|
+
node[:pointer] = reader.css('body').first.pointer_id
|
49
|
+
node[:parent_pointer] = reader.css('html').first.pointer_id
|
69
50
|
@elements << node
|
70
51
|
|
71
52
|
reader.at('body').attribute_nodes.each do |element_attribute|
|
@@ -75,6 +56,7 @@ class CodeTerminator::Html
|
|
75
56
|
node[:attribute] = element_attribute.name if element_attribute.name
|
76
57
|
node[:value] = element_attribute.value if element_attribute.value
|
77
58
|
node[:pointer] = element_attribute.pointer_id
|
59
|
+
node[:parent_pointer] = reader.css('html').first.pointer_id
|
78
60
|
@elements << node
|
79
61
|
end
|
80
62
|
end
|
@@ -85,7 +67,10 @@ class CodeTerminator::Html
|
|
85
67
|
node = Hash.new
|
86
68
|
node[:parent] = "html"
|
87
69
|
node[:tag] = "head"
|
70
|
+
node[:pointer] = reader.css('head').first.pointer_id
|
71
|
+
node[:parent_pointer] = reader.css('html').first.pointer_id
|
88
72
|
@elements << node
|
73
|
+
|
89
74
|
reader.at('head').children.each do |child|
|
90
75
|
if child.attribute_nodes.empty?
|
91
76
|
node = Hash.new
|
@@ -94,7 +79,6 @@ class CodeTerminator::Html
|
|
94
79
|
node[:content] = child.text if child.text or child.comment?
|
95
80
|
node[:pointer] = child.pointer_id
|
96
81
|
node[:parent_pointer] = child.parent.pointer_id
|
97
|
-
|
98
82
|
@elements << node
|
99
83
|
else
|
100
84
|
child.attribute_nodes.each do |element_attribute|
|
@@ -105,8 +89,7 @@ class CodeTerminator::Html
|
|
105
89
|
else
|
106
90
|
node[:tag] = child.name
|
107
91
|
end
|
108
|
-
|
109
|
-
node[:content] = child.text if !child.text.nil?
|
92
|
+
node[:content] = child.text if child.text
|
110
93
|
node[:attribute] = element_attribute.name if element_attribute.name
|
111
94
|
node[:value] = element_attribute.value if element_attribute.value
|
112
95
|
node[:pointer] = element_attribute.pointer_id
|
@@ -131,6 +114,13 @@ class CodeTerminator::Html
|
|
131
114
|
node[:parent_pointer] = child.parent.pointer_id
|
132
115
|
@elements << node
|
133
116
|
else
|
117
|
+
node = Hash.new
|
118
|
+
node[:parent] = "body"
|
119
|
+
node[:tag] = child.name
|
120
|
+
node[:content] = child.text if child.text? or child.comment?
|
121
|
+
node[:pointer] = child.pointer_id
|
122
|
+
node[:parent_pointer] = child.parent.pointer_id
|
123
|
+
@elements << node
|
134
124
|
child.attribute_nodes.each do |element_attribute|
|
135
125
|
node = Hash.new
|
136
126
|
node[:parent] = "body"
|
@@ -146,130 +136,9 @@ class CodeTerminator::Html
|
|
146
136
|
end
|
147
137
|
end
|
148
138
|
#end search elements
|
149
|
-
|
150
139
|
@elements
|
151
140
|
end
|
152
141
|
|
153
|
-
# Validate if the syntax is correct. Return an array with Nokogiri errors.
|
154
|
-
#
|
155
|
-
# Example:
|
156
|
-
# >> CodeTerminator::Html.validate_syntax("<h1>Hola Mundo!</h1")
|
157
|
-
# => [#<Nokogiri::XML::SyntaxError: expected '>'>]
|
158
|
-
#
|
159
|
-
# Arguments:
|
160
|
-
# code: (String)
|
161
|
-
|
162
|
-
def validate_syntax(code)
|
163
|
-
errors = Array.new
|
164
|
-
|
165
|
-
begin
|
166
|
-
Nokogiri::XML(code) { |config| config.strict }
|
167
|
-
|
168
|
-
#validate if html follow w3, uncomment when check all the page
|
169
|
-
#"<!DOCTYPE html>
|
170
|
-
# <html>
|
171
|
-
# <head>
|
172
|
-
# <h1>asdasd</h1>
|
173
|
-
# <title>asdasd</title>
|
174
|
-
# </head>
|
175
|
-
# <body>
|
176
|
-
# <h1>hola</h1>
|
177
|
-
# </body>
|
178
|
-
# </html>"
|
179
|
-
# @validator = Html5Validator::Validator.new
|
180
|
-
# @validator.validate_text(@html)
|
181
|
-
|
182
|
-
rescue Nokogiri::XML::SyntaxError => e
|
183
|
-
#errors[0] = "Check if you close your tags"
|
184
|
-
errors[0] = e
|
185
|
-
end
|
186
|
-
|
187
|
-
errors
|
188
|
-
end
|
189
|
-
|
190
|
-
# Read a html file. Return the text of the file.
|
191
|
-
#
|
192
|
-
# Example:
|
193
|
-
# >> CodeTerminator::Html.read_file("hola_mundo.html")
|
194
|
-
# => "<h1>Hola Mundo!</h1>\n"
|
195
|
-
#
|
196
|
-
# Arguments:
|
197
|
-
# source: (String)
|
198
|
-
|
199
|
-
def read_file(source)
|
200
|
-
if @source_type == "url"
|
201
|
-
fileHtml = open(source).read
|
202
|
-
else
|
203
|
-
fileHtml = File.open(source, "r")
|
204
|
-
end
|
205
|
-
|
206
|
-
text = ""
|
207
|
-
begin
|
208
|
-
fileHtml.each_line do |line|
|
209
|
-
text << line
|
210
|
-
end
|
211
|
-
fileHtml.close
|
212
|
-
rescue
|
213
|
-
text = false
|
214
|
-
ensure
|
215
|
-
#fileHtml.close unless fileHtml.nil?
|
216
|
-
end
|
217
|
-
|
218
|
-
text
|
219
|
-
end
|
220
|
-
|
221
|
-
# Get the elements of the code in html format. Return a string with elements in html.
|
222
|
-
#
|
223
|
-
# Example:
|
224
|
-
# >> CodeTerminator::Html.print_elements("exercises/hola_mundo.html" )
|
225
|
-
# => "name = h1<br><hr>name = text<br>content = hola mundo<br><hr>"
|
226
|
-
#
|
227
|
-
# Arguments:
|
228
|
-
# elements: (Array)
|
229
|
-
|
230
|
-
def print_elements(elements)
|
231
|
-
text = ""
|
232
|
-
elements.each do |child|
|
233
|
-
text << "parent = " + child[:parent] + "<br>" if child[:parent]
|
234
|
-
text << "tag = " + child[:tag] + "<br>" if child[:tag]
|
235
|
-
text << "attribute = " + child[:attribute] + "<br>" if child[:attribute]
|
236
|
-
text << "value = " + child[:value] + "<br>" if child[:value]
|
237
|
-
text << "content = " + child[:content] + "<br>" if child[:content]
|
238
|
-
text << "<hr>"
|
239
|
-
end
|
240
|
-
text
|
241
|
-
end
|
242
|
-
|
243
|
-
# Get the instructions to recreate the html code. Return an array with strings .
|
244
|
-
#
|
245
|
-
# Example:
|
246
|
-
# >> CodeTerminator::Html.get_instructions(file.get_elements("exercises/test.html"))
|
247
|
-
# => ["Add the tag h2 in body", "Add the tag text in h2 with content 'hola test' ", "Add the tag p in body"]
|
248
|
-
#
|
249
|
-
# Arguments:
|
250
|
-
# instructions: (Array)
|
251
|
-
|
252
|
-
def get_instructions(source)
|
253
|
-
elements = get_elements(source)
|
254
|
-
text = ""
|
255
|
-
instructions = Array.new
|
256
|
-
elements.each do |child|
|
257
|
-
if child[:tag]!="text"
|
258
|
-
text << "Add the tag " + child[:tag]
|
259
|
-
text << " in " + child[:parent] if !child[:parent].nil?
|
260
|
-
text << " with an attribute '" + child[:attribute] + "' " if !child[:attribute].nil?
|
261
|
-
text << " with value '" + child[:value] + "' " if !child[:value].nil?
|
262
|
-
elsif child[:tag] == "comment"
|
263
|
-
text << " In " + child[:tag]+ " add the text '" + child[:content] + "' " if !child[:content].nil?
|
264
|
-
else
|
265
|
-
text << " In " + child[:parent]+ " add the text '" + child[:content] + "' " if !child[:content].nil?
|
266
|
-
end
|
267
|
-
instructions.push(text)
|
268
|
-
text = ""
|
269
|
-
end
|
270
|
-
instructions
|
271
|
-
end
|
272
|
-
|
273
142
|
|
274
143
|
|
275
144
|
# Match if the code have the same elements than the exercise. Return an array with the mismatches.
|
@@ -288,214 +157,182 @@ class CodeTerminator::Html
|
|
288
157
|
|
289
158
|
def match(source, code)
|
290
159
|
@html_errors = Array.new
|
291
|
-
html_errors = @html_errors
|
292
|
-
|
293
160
|
code = Nokogiri::HTML(code)
|
161
|
+
@elements = get_elements(source)
|
294
162
|
|
295
|
-
elements
|
163
|
+
@elements.each do |e|
|
164
|
+
p css_string = build_css(e,'').strip
|
296
165
|
|
166
|
+
#search_attribute()
|
167
|
+
if e[:attribute]
|
168
|
+
# search_attribute = code.css(css_string).first
|
169
|
+
# if !search_attribute
|
170
|
+
# @html_errors << new_error(element: e, type: 334, description: "`<#{e[:tag]}>` should have an attribute named #{e[:attribute]} with the value #{e[:value]}")
|
171
|
+
# end
|
297
172
|
|
298
|
-
|
173
|
+
#search_text()
|
174
|
+
elsif e[:tag] == "text" || e[:tag] == "comment"
|
175
|
+
element_name = e[:tag]=="comment" ? "comment":e[:parent]
|
176
|
+
search_elements = code.css(css_string)
|
177
|
+
if e[:content].strip != ""
|
178
|
+
element = search_elements.select{|hash| hash.text.strip == e[:content].strip}
|
179
|
+
if element.empty?
|
180
|
+
@html_errors << new_error(element: e, type: 330, description: "The text inside `<#{element_name}>` should be #{e[:content]}")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
#search_element()
|
184
|
+
else
|
299
185
|
|
300
|
-
|
186
|
+
search_element = code.css(css_string).first
|
187
|
+
if !search_element
|
188
|
+
@html_errors << new_error(element: e[:tag], type: 404, description: "Remember to add the `<#{e[:tag]}>` tag in " + css_string.chomp(e[:tag]))
|
189
|
+
# else
|
190
|
+
# if !are_all_elements(code,e[:tag], css_string)
|
191
|
+
# # @html_errors << new_error(element: e[:tag], type: 404, description: "Remember to add the `<#{e[:tag]}>` tag.")
|
192
|
+
# end
|
193
|
+
end
|
301
194
|
|
302
|
-
|
195
|
+
end
|
303
196
|
|
304
|
-
|
197
|
+
end
|
305
198
|
|
306
|
-
|
307
|
-
|
199
|
+
count_elements(code)
|
200
|
+
search_attribute_value(code)
|
308
201
|
|
202
|
+
p @html_errors
|
203
|
+
end
|
309
204
|
|
310
|
-
elements.each do |e|
|
311
205
|
|
312
|
-
if elements_count.select {|element| element[:parent_pointer].to_s == e[:parent_pointer].to_s && element[:tag].to_s == e[:tag]}.count < 1
|
313
|
-
error_element = Hash.new
|
314
|
-
error_element[:tag] = e[:tag]
|
315
|
-
error_element[:pointer] = e[:pointer]
|
316
|
-
error_element[:parent_pointer] = e[:parent_pointer]
|
317
|
-
error_element[:count] = 0
|
318
|
-
elements_count << error_element
|
319
|
-
end
|
320
206
|
|
321
|
-
|
207
|
+
private
|
322
208
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
code.css(e[:tag]).each do |tag|
|
341
|
-
tag_element = nil
|
342
|
-
e_check = css_code_checked.select {|element| element[:original_pointer].to_s == e[:pointer].to_s }
|
343
|
-
# p "echeck " + e_check.to_s
|
344
|
-
e_check2 = css_code_checked.select {|element| element[:pointer].to_s == tag.pointer_id.to_s }
|
345
|
-
|
346
|
-
#original_pointer es el pointer del elemento e[]
|
347
|
-
#busca si el original_pointer esta en la lista de relaciones
|
348
|
-
#busca si el pointer del tag esta en la lista de relaciones
|
349
|
-
#cuando un original pointer o un pointer esta en la lista de relaciones, ya no puede volver a ser ingresado en la lista
|
350
|
-
#si el original pointer ya esta en la lista de relaciones, ya no es necesario volver a checarlo
|
351
|
-
check_original_pointer = css_code_checked.select {|element| element[:original_pointer].to_s == e[:pointer].to_s }
|
352
|
-
|
353
|
-
check_add_pointer = css_code_checked.select {|element| element[:pointer].to_s == tag.pointer_id.to_s }
|
354
|
-
|
355
|
-
#look for same tags in code
|
356
|
-
if check_original_pointer.count == 0
|
357
|
-
if check_add_pointer.count < 1
|
358
|
-
element_checked = Hash.new
|
359
|
-
element_checked[:pointer] = tag.pointer_id
|
360
|
-
element_checked[:tag] = e[:tag]
|
361
|
-
element_checked[:original_pointer] = e[:pointer]
|
362
|
-
element_checked[:original_parent_pointer] = e[:parent_pointer]
|
363
|
-
css_code_checked << element_checked
|
364
|
-
|
365
|
-
error_element = elements_count.select {|element| element[:tag].to_s == e[:tag].to_s && element[:parent_pointer].to_s == e[:parent_pointer].to_s}.first
|
366
|
-
error_element[:count] += 1
|
367
|
-
end
|
368
|
-
end
|
369
|
-
# end
|
370
|
-
# p "checked = " + elements_count.to_s
|
371
|
-
|
372
|
-
if code.css(e[:tag]).length > 0
|
373
|
-
|
374
|
-
#tag es el elemento reccorrido en el codigo
|
375
|
-
#e es el elemento original
|
376
|
-
#elementscount son los elementos que existen en codigo y original
|
377
|
-
|
378
|
-
# if tag_element
|
379
|
-
if e[:attribute]
|
380
|
-
|
381
|
-
# p "e --- " + e[:tag].to_s
|
382
|
-
# p "e pt--- " + e[:pointer].to_s
|
383
|
-
# p "e parent pt--- " + e[:parent_pointer].to_s
|
384
|
-
# p "e attribute --- " + e[:attribute].to_s
|
385
|
-
|
386
|
-
|
387
|
-
# if tag.attribute(e[:attribute])
|
388
|
-
# p "elements count = " + css_code_checked.to_s
|
389
|
-
tag_element = css_code_checked.select {|element| element[:pointer].to_s == tag.pointer_id.to_s && element[:original_pointer] == e[:pointer] }.first
|
390
|
-
# p "tag --" + tag.name.to_s
|
391
|
-
# p "tag --" + tag.to_s
|
392
|
-
# p "tag parent -- " + tag.parent.name.to_s
|
393
|
-
# p "tag pointer -- " + tag.pointer_id.to_s
|
394
|
-
# p "tag parent pointer -- " + tag.parent.pointer_id.to_s
|
395
|
-
# p "tag attribute -- " + tag.attribute(e[:attribute]).to_s
|
396
|
-
# p "parent_element --- " + tag_element.to_s
|
397
|
-
# else
|
398
|
-
# end
|
399
|
-
|
400
|
-
# Check the tag's attributes
|
401
|
-
if tag.attribute(e[:attribute]).nil?
|
402
|
-
if tag_element
|
403
|
-
# p "attribute element " + e[:attribute].to_s
|
404
|
-
# p "attribute tag " + tag.attribute(e[:attribute]).name.to_s
|
405
|
-
# if e[:attribute] != tag.attribute(e[:attribute]).name
|
406
|
-
html_errors << new_error(element: e, type: 334, description: "`<#{e[:tag]}>` should have an attribute named #{e[:attribute]}")
|
407
|
-
# end
|
408
|
-
end
|
409
|
-
else
|
410
|
-
if tag.attribute(e[:attribute]).value != e[:value]
|
411
|
-
exist_in_body << false
|
412
|
-
# p "type " + e[:tag] + " with attribute " + e[:attribute] + " value " + e[:value]
|
413
|
-
# Check if the img have attribute src and value is null, the user can write whatever image he wants
|
414
|
-
if !(e[:tag] == "img" && e[:attribute] == "src" && e[:value] == "")
|
415
|
-
error333 = new_error(element: e, type: 333, description: "Make sure that the attribute #{e[:attribute]} in `<#{e[:tag]}>` has the value #{e[:value]}")
|
416
|
-
end
|
417
|
-
else
|
418
|
-
# p "add code_checked"
|
419
|
-
# css_code_checked << element_checked
|
420
|
-
exist_in_body << true
|
421
|
-
end
|
422
|
-
end
|
423
|
-
# end
|
209
|
+
def build_css(element, css)
|
210
|
+
if !element[:parent].empty?
|
211
|
+
if !element[:attribute]
|
212
|
+
if element[:tag]=="comment"
|
213
|
+
css += "//comment()"
|
214
|
+
else
|
215
|
+
parent = @elements.select{|hash| hash[:pointer].to_s == element[:parent_pointer].to_s}.first
|
216
|
+
parent_css = parent[:tag].to_s if parent
|
217
|
+
css += parent_css
|
218
|
+
|
219
|
+
parent_attributes = @elements.select{|hash| hash[:parent_pointer].to_s == element[:parent_pointer].to_s && hash[:attribute]}
|
220
|
+
parent_attributes.each do |par_attr|
|
221
|
+
css += css_attribute_type(par_attr)
|
222
|
+
end
|
223
|
+
css += " "
|
224
|
+
css += element[:tag].to_s + " " if element[:tag] != "text"
|
225
|
+
end
|
424
226
|
|
227
|
+
else
|
425
228
|
|
426
|
-
|
427
|
-
|
428
|
-
|
229
|
+
search_attribute = @elements.select{|hash| hash[:parent_pointer].to_s == element[:parent_pointer].to_s && hash[:attribute].to_s == element[:attribute]}.first
|
230
|
+
css += search_attribute[:tag].to_s
|
231
|
+
attribute_css = css_attribute_type(search_attribute) if search_attribute
|
232
|
+
css += attribute_css
|
429
233
|
|
430
|
-
|
234
|
+
end
|
235
|
+
else
|
236
|
+
css += element[:tag].to_s + " " if element[:tag] != "text"
|
237
|
+
end
|
238
|
+
css
|
239
|
+
end
|
240
|
+
|
241
|
+
def css_attribute_type(element)
|
242
|
+
case element[:attribute]
|
243
|
+
when "id"
|
244
|
+
css_symbol = '#'
|
245
|
+
css = css_symbol.to_s + element[:value].to_s
|
246
|
+
when "class"
|
247
|
+
css_symbol = '.'
|
248
|
+
css = css_symbol.to_s + element[:value].to_s
|
249
|
+
when "src"
|
250
|
+
css_symbol = "[src]"
|
251
|
+
css = css_symbol.to_s
|
252
|
+
when "href"
|
253
|
+
css_symbol = "[href]"
|
254
|
+
css = css_symbol.to_s
|
255
|
+
when "alt"
|
256
|
+
css_symbol = "[alt]"
|
257
|
+
css = css_symbol.to_s
|
258
|
+
else
|
259
|
+
css_symbol = element[:attribute]
|
260
|
+
css = css_symbol.to_s
|
261
|
+
end
|
262
|
+
css
|
263
|
+
end
|
431
264
|
|
432
|
-
|
433
|
-
|
265
|
+
def are_all_elements(code, tag, css_string)
|
266
|
+
element_count = @elements.select{|hash| hash[:tag] == tag && !hash[:attribute]}.count
|
267
|
+
code_count = code.css(css_string).count
|
268
|
+
element_count > code_count ? false:true
|
269
|
+
end
|
434
270
|
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
271
|
+
def count_elements(code)
|
272
|
+
uniq_elements = @elements.group_by{|h| h[:tag]}
|
273
|
+
uniq_elements.each do |e|
|
274
|
+
if e[0] != "text"
|
275
|
+
# "element " + e[0].to_s
|
276
|
+
element_count = e[1].select{|hash| !hash[:attribute]}.count
|
277
|
+
if e[0] != "comment"
|
278
|
+
code_count = code.css(e[0]).count
|
439
279
|
else
|
440
|
-
|
441
|
-
|
442
|
-
exist_in_parent = true if code_css.parent.name == e[:parent]
|
443
|
-
end
|
444
|
-
html_errors << new_error(element: e, type: 440, description: "Remember to add the `<#{e[:tag]}>` tag inside `<#{e[:parent]}>`") if !exist_in_parent
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
end
|
280
|
+
code_count = code.css("//comment()").count
|
281
|
+
end
|
449
282
|
|
283
|
+
if element_count > code_count
|
284
|
+
@html_errors << new_error(element: e[0], type: 404, description: "Remember to add the `<#{e[0]}>` tag.")
|
285
|
+
end
|
450
286
|
end
|
287
|
+
end
|
288
|
+
end
|
451
289
|
|
452
|
-
|
290
|
+
# def search_comments(code)
|
291
|
+
# comment_elements = code.css('//comment()')
|
292
|
+
#
|
293
|
+
# end
|
453
294
|
|
454
|
-
|
295
|
+
def search_attribute_value(code)
|
296
|
+
uniq_elements = @elements.group_by{|h| h[:tag]}
|
297
|
+
uniq_elements.each do |e|
|
455
298
|
|
299
|
+
element_with_attributes = e[1].select{|hash| hash[:attribute]}
|
300
|
+
element_with_attributes.each do |ewa|
|
456
301
|
|
457
|
-
|
458
|
-
html_errors << error333
|
459
|
-
end
|
460
|
-
exist_in_body = []
|
302
|
+
css_string = build_css(ewa, '')
|
461
303
|
|
462
|
-
|
304
|
+
if code.css(css_string).empty?
|
305
|
+
@html_errors << new_error(element: ewa, type: 334, description: "`<#{ewa[:tag]}>` should have an attribute named #{ewa[:attribute]}")
|
306
|
+
else
|
463
307
|
|
464
|
-
|
308
|
+
if ewa[:value] != "" && code.css(css_string).select{|x| x[ewa[:attribute]].to_s == ewa[:value].to_s}.empty?
|
309
|
+
@html_errors << new_error(element: ewa, type: 333, description: "Make sure that the attribute #{ewa[:attribute]} in `<#{ewa[:tag]}>` has the value #{ewa[:value]}")
|
310
|
+
end
|
465
311
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
#filtrar por parent
|
470
|
-
# tag_count = code.css(x[:tag]).length
|
471
|
-
tag_count = elements.select {|element| element[:parent_pointer].to_s == x[:parent_pointer].to_s && element[:tag].to_s == x[:tag]}.count
|
472
|
-
# p x[:tag]!="body"
|
473
|
-
if tag_count >= 1 && !(x[:tag]=="body" || x[:tag]=="head" || x[:tag]=="text" || x[:tag]=="comment" || x[:tag]=="img")
|
474
|
-
# if tag_count >= 1 && !(x[:tag]!="div")
|
475
|
-
if x[:count] < tag_count
|
476
|
-
html_errors << new_error(element: x[:tag], type: 404, description: "Remember to add the `<#{x[:tag]}>` tag")
|
477
|
-
end
|
478
|
-
end
|
479
|
-
end
|
312
|
+
if code.css(css_string).select{|x| x[ewa[:attribute]].to_s == ""}.any?
|
313
|
+
@html_errors << new_error(element: ewa, type: 335, description: "`<#{ewa[:attribute]}>` in `<#{ewa[:tag]}>` can't be empty")
|
314
|
+
end
|
480
315
|
|
481
|
-
|
316
|
+
end
|
482
317
|
|
483
|
-
|
318
|
+
end
|
319
|
+
|
320
|
+
end
|
484
321
|
|
485
|
-
|
322
|
+
|
323
|
+
end
|
486
324
|
|
487
325
|
def add_children(parent)
|
488
326
|
parent.children.each do |child|
|
489
327
|
if child.attribute_nodes.empty?
|
490
328
|
node = Hash.new
|
491
329
|
node[:parent] = parent.name
|
492
|
-
# node[:tag] = child.name
|
493
330
|
if child.name == "#cdata-section"
|
494
331
|
node[:tag] = "text"
|
495
332
|
else
|
496
333
|
node[:tag] = child.name
|
497
334
|
end
|
498
|
-
node[:content] = child.text if
|
335
|
+
node[:content] = child.text.strip if child.text and child.class != Nokogiri::XML::Element
|
499
336
|
node[:pointer] = child.pointer_id
|
500
337
|
node[:parent_pointer] = child.parent.pointer_id
|
501
338
|
@elements << node
|
@@ -503,16 +340,13 @@ class CodeTerminator::Html
|
|
503
340
|
child.attribute_nodes.each do |element_attribute|
|
504
341
|
node = Hash.new
|
505
342
|
node[:parent] = parent.name
|
506
|
-
# node[:tag] = child.namecode
|
507
343
|
if element_attribute.name == "#cdata-section"
|
508
344
|
node[:tag] = "text"
|
509
|
-
elsif element_attribute.name == "href"
|
510
|
-
node[:tag] = child.name
|
511
345
|
else
|
512
|
-
node[:tag] =
|
346
|
+
node[:tag] = child.name
|
513
347
|
end
|
514
|
-
node[:attribute] = element_attribute.name if
|
515
|
-
node[:value] = element_attribute.value if
|
348
|
+
node[:attribute] = element_attribute.name if element_attribute.name
|
349
|
+
node[:value] = element_attribute.value if element_attribute.value
|
516
350
|
node[:pointer] = element_attribute.pointer_id
|
517
351
|
node[:parent_pointer] = child.pointer_id
|
518
352
|
@elements << node
|
@@ -564,82 +398,4 @@ class CodeTerminator::Html
|
|
564
398
|
end
|
565
399
|
|
566
400
|
|
567
|
-
#methods of match
|
568
|
-
def look_comment_or_text(code,e)
|
569
|
-
error330 = nil
|
570
|
-
text_found = false
|
571
|
-
@comment_found = false if e[:tag] == "comment"
|
572
|
-
|
573
|
-
#look for comments or text in code
|
574
|
-
#code, e
|
575
|
-
if code.css(e[:parent]).children.any?
|
576
|
-
#look for comments and text in children of body
|
577
|
-
# code, e
|
578
|
-
#save
|
579
|
-
#return
|
580
|
-
code.css(e[:parent]).children.each do |node_child|
|
581
|
-
#if class of the node is a comment, look in the code
|
582
|
-
# @e, node_child
|
583
|
-
#save error330
|
584
|
-
#return true (flag)
|
585
|
-
if node_child.class == Nokogiri::XML::Comment
|
586
|
-
error330 = new_error(element: e, type: 330, description: "The text inside the comment should be #{e[:content]}") if e[:content].strip != "" && node_child.text.strip! != e[:content].strip!
|
587
|
-
@comment_found = true
|
588
|
-
end
|
589
|
-
|
590
|
-
#if class of node is text and element is not a comment
|
591
|
-
#@e, node_child
|
592
|
-
#save a error330, text_found
|
593
|
-
#return true (flag)
|
594
|
-
if node_child.class == Nokogiri::XML::Text && e[:tag] != "comment"
|
595
|
-
node_child.text.strip != e[:content].strip ? error330 = new_error(element: e, type: 330, description: "The text inside `<#{e[:parent]}>` should be #{e[:content]}") : text_found = true
|
596
|
-
end
|
597
|
-
end #each
|
598
|
-
|
599
|
-
else
|
600
|
-
#validate if comment exist and has the expected content in body
|
601
|
-
#code, @e
|
602
|
-
#save @comment_found, text_found
|
603
|
-
if code.css(e[:parent]).text.strip != e[:content].strip
|
604
|
-
if e[:tag] == "comment"
|
605
|
-
error330 = new_error(element: e, type: 330, description: "The text inside the comment should be #{e[:content]}")
|
606
|
-
@comment_found = true
|
607
|
-
else
|
608
|
-
error330 = new_error(element: e, type: 330, description: "The text inside `<#{e[:parent]}>` should be #{e[:content]}")
|
609
|
-
end
|
610
|
-
else
|
611
|
-
text_found = true
|
612
|
-
end
|
613
|
-
end #end if parent has children
|
614
|
-
|
615
|
-
#throw errors of comment or text
|
616
|
-
#if comment not found, throw error
|
617
|
-
if (defined? @comment_found) && !@comment_found
|
618
|
-
@html_errors << new_error(element: e, type: 404, description: "Remember to add the comment tag")
|
619
|
-
remove_instance_variable(:@comment_found) if !@comment_found
|
620
|
-
end
|
621
|
-
|
622
|
-
if !text_found && error330
|
623
|
-
@html_errors << error330
|
624
|
-
error330 = nil
|
625
|
-
end
|
626
|
-
#end throw errors
|
627
|
-
end #end look_comment_or_text
|
628
|
-
|
629
|
-
def look_parent_text(code,e)
|
630
|
-
exist = false
|
631
|
-
#look for text in parent, if found check flag true
|
632
|
-
code.css(e[:parent]).each do |code_css|
|
633
|
-
if code_css.text == e[:content]
|
634
|
-
exist = true
|
635
|
-
end
|
636
|
-
end
|
637
|
-
if !exist
|
638
|
-
@html_errors << new_error(element: e, type: 330, description: "The text inside `<#{e[:parent]}>` should be #{e[:content]}")
|
639
|
-
end
|
640
|
-
end
|
641
|
-
|
642
|
-
|
643
|
-
#end
|
644
|
-
|
645
401
|
end
|