code_terminator 0.5.8 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e23d5114a50f4fcb74e546366e5bdf65655a305
4
- data.tar.gz: 8714cc7e061a6801689914d2ba9267460abbefce
3
+ metadata.gz: 542fe230e1beb215c850d8ba716a683a370484d1
4
+ data.tar.gz: b8d7b6ed665073ffb799ed0671a9e250c44ec447
5
5
  SHA512:
6
- metadata.gz: 400084dbc2cb543c3b6c1633fd145db9a370bc6c872ed6dfb08785ffffef4dbcf80ef360ac76eca50ed7154055a1948c41bdcd824044238a29dad74aa6ba3695
7
- data.tar.gz: 9f08fb9e06ddab835cea3c21ea71f3db4941eea24a64773773fe47855214ee47e9c73acde299b9d22bf4b220b18153f42c08dc18727bf24eaf2b498e61a0c89a
6
+ metadata.gz: 25d291f5d0676fdaeb941f5fca83841dca82abe79e7e44a256a4cff69c98367d03088fc50d093d97f7fe62b77188f0b717fb268022a8578f360258ee8562f253
7
+ data.tar.gz: 5621cedfe8f2a56eba87a5c68b42daa820cb6598db7b7cbf0b2812f36e4862318ed3caf1a2df2c73954cf758ac9b9d3a9d519000de137d6661b78e3d734fb534
@@ -0,0 +1,13 @@
1
+ <html>
2
+ <head>
3
+ <title>My Favorite Book</title>
4
+ </head>
5
+ <body>
6
+ <div id='title'>
7
+ <h1></h1>
8
+ </div>
9
+ <div class='about'>
10
+ <p></p>
11
+ </div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,13 @@
1
+ <html>
2
+ <head>
3
+ <title>My Favorite Book</title>
4
+ </head>
5
+ <body>
6
+ <div id='t'>
7
+ <h1></h1>
8
+ </div>
9
+ <div class='a'>
10
+ <p></p>
11
+ </div>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <p></p>
@@ -0,0 +1,14 @@
1
+ <html>
2
+ <head>
3
+ </head>
4
+ <body>
5
+ <div id="logo">
6
+ <p>hola</p>
7
+ <img alt="">
8
+ </div>
9
+ <div id="catalog">
10
+ <img src="banana" alt="">
11
+ <img src="pear" alt="">
12
+ </div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,13 @@
1
+ <html>
2
+ <head>
3
+ </head>
4
+ <body>
5
+ <img src="">
6
+ <div class="col-md-12">
7
+ <img>
8
+ <img>
9
+ <h1>hola</h1>
10
+ </div>
11
+ <img>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <p></p>
@@ -0,0 +1,8 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ </head>
5
+ <body>
6
+ <p></p>
7
+ </body>
8
+ </html>
@@ -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,9 @@
1
+ <!DOCTYPE html><html>
2
+ <head>
3
+ <title></title>
4
+ </head>
5
+ <body>
6
+ <h1></h1>
7
+ <p></p>
8
+ </body>
9
+ </html>
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>
5
+ </title>
6
+ </head>
7
+ <body>
8
+ <img src="">
9
+ <img src="">
10
+ <img src="">
11
+ </body>
12
+ </html>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title></title>
5
+ </head>
6
+ <body>
7
+ <ul>
8
+ <li></li>
9
+ </ul>
10
+ </body>
11
+ </html>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title></title>
5
+ </head>
6
+ <body>
7
+ <a href=""></a>
8
+ <a href=""></a>
9
+ <a href=""></a>
10
+ <a href=""></a>
11
+ <a href=""></a>
12
+ </body>
13
+ </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>
@@ -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
- # p "array split" + parser_property.to_s
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
- # p "parser property: " + parser_property.to_s
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
@@ -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
- node = Hash.new
60
- node[:parent] = ""
61
- node[:tag] = "html"
62
- @elements << node
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
- # node[:tag] = ( ? "text", child.name)
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 = get_elements(source)
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
- exist_in_body = Array.new
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
- error_elements = Array.new
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
- elements_count = Array.new
195
+ end
303
196
 
304
- error333 = nil
197
+ end
305
198
 
306
- #lista de relaciones entre tags y elementos
307
- css_code_checked = Array.new
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
- item = e[:tag]
207
+ private
322
208
 
323
- if item == "text" or item == "comment"
324
- # Check the text
325
- if e[:content]
326
- if code.css(e[:parent]).count < 2
327
- if code.css(e[:parent]).class == Nokogiri::XML::NodeSet
328
- #look for children elements with texts or comments
329
- look_comment_or_text(code,e)
330
- end
331
- else
332
- #check if parent tag of the user code has text apart from the children tags
333
- look_parent_text(code,e)
334
- end
335
- end
336
- #end if content is null
337
- else
338
- #item class is different to text or comment
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
- # p "respond" + tag.parent.to_s
427
- # Check that tags exist within parent tags
428
- if tag.first.respond_to? :parent
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
- p "check if exists in parent tags"
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
- # e_check4 = css_code_checked.select {|element| element[:pointer].to_s == e[:pointer].to_s }
433
- # e_check5 = css_code_checked.select {|element| element[:target_parent_pointer].to_s == e[:parent_pointer].to_s }
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
- if (tag.count < 2 && tag.first)
436
- if tag.first.parent.name != e[:parent]
437
- html_errors << new_error(element: e, type: 440, description: "Remember to add the `<#{e[:tag]}>` tag inside `<#{e[:parent]}>`")
438
- end
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
- exist_in_parent = false
441
- tag.each do |code_css|
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
- end
290
+ # def search_comments(code)
291
+ # comment_elements = code.css('//comment()')
292
+ #
293
+ # end
453
294
 
454
- # end #end tag
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
- if exist_in_body && !exist_in_body.include?(true) && error333
458
- html_errors << error333
459
- end
460
- exist_in_body = []
302
+ css_string = build_css(ewa, '')
461
303
 
462
- end
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
- end
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
- # p elements_count.to_s
467
-
468
- elements_count.each do |x|
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
- html_errors
316
+ end
482
317
 
483
- end
318
+ end
319
+
320
+ end
484
321
 
485
- private
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 !child.text.nil? and child.class!=Nokogiri::XML::Element
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] = element_attribute.name
346
+ node[:tag] = child.name
513
347
  end
514
- node[:attribute] = element_attribute.name if !element_attribute.name.nil?
515
- node[:value] = element_attribute.value if !element_attribute.value.nil?
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