asker-tool 2.1.5 → 2.1.6

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +0 -0
  3. data/README.md +2 -3
  4. data/bin/asker +1 -0
  5. data/lib/asker.rb +10 -6
  6. data/lib/asker/ai/ai.rb +4 -0
  7. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  8. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  9. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  10. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  11. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  12. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  13. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  14. data/lib/asker/ai/concept_ai.rb +1 -0
  15. data/lib/asker/ai/stages/stage_t.rb +76 -76
  16. data/lib/asker/application.rb +18 -2
  17. data/lib/asker/checker.rb +112 -30
  18. data/lib/asker/cli.rb +12 -25
  19. data/lib/asker/data/code.rb +73 -0
  20. data/lib/asker/data/column.rb +31 -21
  21. data/lib/asker/data/concept.rb +42 -45
  22. data/lib/asker/data/data_field.rb +14 -0
  23. data/lib/asker/data/row.rb +75 -52
  24. data/lib/asker/data/table.rb +89 -42
  25. data/lib/asker/data/world.rb +57 -33
  26. data/lib/asker/displayer/concept_ai_displayer.rb +56 -37
  27. data/lib/asker/displayer/concept_displayer.rb +7 -5
  28. data/lib/asker/displayer/stats_displayer.rb +4 -3
  29. data/lib/asker/exporter/concept_ai_gift_exporter.rb +5 -3
  30. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -3
  31. data/lib/asker/exporter/output_file_exporter.rb +1 -1
  32. data/lib/asker/files/config.ini +37 -0
  33. data/lib/asker/files/example-concept.haml +0 -1
  34. data/lib/asker/{lang/locales → files/language}/du/templates.yaml +0 -0
  35. data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
  36. data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
  37. data/lib/asker/{lang/locales → files/language}/en/templates.yaml +0 -0
  38. data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
  39. data/lib/asker/{lang/locales → files/language}/es/mistakes.yaml +0 -0
  40. data/lib/asker/{lang/locales → files/language}/es/templates.yaml +0 -0
  41. data/lib/asker/{lang/locales → files/language}/fr/connectors.yaml +0 -0
  42. data/lib/asker/{lang/locales → files/language}/fr/mistakes.yaml +0 -0
  43. data/lib/asker/{lang/locales → files/language}/fr/templates.yaml +0 -0
  44. data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
  45. data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
  46. data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
  47. data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
  48. data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
  49. data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
  50. data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
  51. data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
  52. data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
  53. data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
  54. data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
  55. data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
  56. data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
  57. data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
  58. data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
  59. data/lib/asker/lang/lang.rb +17 -10
  60. data/lib/asker/lang/lang_factory.rb +26 -5
  61. data/lib/asker/lang/text_actions.rb +87 -69
  62. data/lib/asker/loader/code_loader.rb +3 -3
  63. data/lib/asker/loader/content_loader.rb +9 -5
  64. data/lib/asker/loader/file_loader.rb +2 -11
  65. data/lib/asker/loader/haml_loader.rb +15 -0
  66. data/lib/asker/loader/image_url_loader.rb +5 -8
  67. data/lib/asker/loader/input_loader.rb +8 -9
  68. data/lib/asker/loader/project_loader.rb +10 -8
  69. data/lib/asker/logger.rb +3 -3
  70. data/lib/asker/project.rb +24 -50
  71. data/lib/asker/skeleton.rb +22 -13
  72. metadata +39 -37
  73. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  74. data/lib/asker/code/code.rb +0 -53
@@ -3,17 +3,18 @@ require_relative '../../lang/lang_factory'
3
3
  require_relative '../../ai/question'
4
4
  require_relative 'base_code_ai'
5
5
 
6
+ ##
7
+ # Class for RubyCodeAI objects
6
8
  class RubyCodeAI < BaseCodeAI
7
- def initialize(data_object)
8
- @data_object = data_object
9
- @lines = data_object.lines
10
- @lang = LangFactory.instance.get('ruby')
11
- @num = 0
12
- @questions = []
9
+ def initialize(code)
13
10
  @reduce = 1
14
- @reduce = 4 if @lines.size > 25
11
+ @reduce = 4 if code.lines.size > 25
12
+ @lang = LangFactory.instance.get('ruby')
13
+ super code
15
14
  end
16
15
 
16
+ ##
17
+ # Make errors about comments
17
18
  def make_comment_error
18
19
  questions = []
19
20
  error_lines = []
@@ -43,6 +44,8 @@ class RubyCodeAI < BaseCodeAI
43
44
  questions.shuffle[0,@lines.size/@reduce]
44
45
  end
45
46
 
47
+ ##
48
+ # Make questions without errors
46
49
  def make_no_error_changes
47
50
  questions = []
48
51
  empty_lines = []
@@ -81,6 +84,8 @@ class RubyCodeAI < BaseCodeAI
81
84
  questions.shuffle[0,@lines.size/@reduce]
82
85
  end
83
86
 
87
+ ##
88
+ # Make questions with syntax errors
84
89
  def make_syntax_error
85
90
  questions = []
86
91
 
@@ -120,6 +125,8 @@ class RubyCodeAI < BaseCodeAI
120
125
  questions.shuffle[0,@lines.size/@reduce]
121
126
  end
122
127
 
128
+ ##
129
+ # Make questions with variable errors
123
130
  def make_variable_error
124
131
  questions = []
125
132
  error_lines = []
@@ -4,12 +4,9 @@ require_relative '../../ai/question'
4
4
  require_relative 'base_code_ai'
5
5
 
6
6
  class SQLCodeAI < BaseCodeAI
7
- def initialize(data_object)
8
- @data_object = data_object
9
- @lines = data_object.lines
7
+ def initialize(code)
10
8
  @lang = LangFactory.instance.get('sql')
11
- @num = 0
12
- @questions = []
9
+ super code
13
10
  end
14
11
 
15
12
  def make_comment_error
@@ -23,6 +23,7 @@ class ConceptAI
23
23
  @questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
24
24
  @excluded_questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
25
25
  @num = 0 # Used to add a unique number to every question
26
+ make_questions
26
27
  end
27
28
 
28
29
  def num
@@ -1,41 +1,42 @@
1
- # encoding: utf-8
2
1
 
3
2
  require 'set'
4
3
  require_relative 'base_stage'
5
4
  require_relative '../question'
6
5
 
6
+ ##
7
+ # StageT create questions based con Table data
7
8
  class StageT < BaseStage
8
- #range t1-t9...c1-c9
9
+ # range t1-t9
9
10
 
10
- def run(pTable, pRow, pList) #process_tableXfields
11
+ def run(pTable, pRow, pList) # process_tableXfields
11
12
  questions = []
12
- return questions unless type=="text"
13
+ return questions unless type == 'text'
13
14
 
14
- if pTable.fields.count>1 then
15
+ if pTable.fields.count > 1
15
16
  questions = questions + process_table2fields(pTable, pRow, pList, 0, 1)
16
- elsif pTable.fields.count>2 then
17
+ elsif pTable.fields.count > 2
17
18
  questions = questions + process_table2fields(pTable, pRow, pList, 0, 2)
18
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 2)
19
- elsif pTable.fields.count>3 then
19
+ # questions = questions + process_table2fields(pTable, pRow, pList, 1, 2)
20
+ elsif pTable.fields.count > 3
20
21
  questions = questions + process_table2fields(pTable, pRow, pList, 0, 3)
21
- questions = questions + process_table2fields(pTable, pRow, pList, 1, 3)
22
- questions = questions + process_table2fields(pTable, pRow, pList, 2, 3)
22
+ # questions = questions + process_table2fields(pTable, pRow, pList, 1, 3)
23
+ # questions = questions + process_table2fields(pTable, pRow, pList, 2, 3)
23
24
  end
24
25
 
25
- return questions
26
+ questions
26
27
  end
27
28
 
28
29
  private
29
30
  def process_table2fields(lTable, lRow, pList, pCol1, pCol2)
30
31
  questions = []
31
- #create gift questions
32
+ # create questions
32
33
 
33
34
  # Using the column #0
34
- s=Set.new [ lRow[:data][0] , lang.text_for(:none) ]
35
+ s = Set.new [ lRow[:data][0] , lang.text_for(:none) ]
35
36
  pList.each { |i| s.add( i[:data][0] ) }
36
- a=s.to_a
37
+ a = s.to_a
37
38
 
38
- if s.count>3 then
39
+ if s.count > 3
39
40
  q=Question.new
40
41
  q.name="#{name}-#{num.to_s}-t1table-#{lTable.name}"
41
42
  q.text=lang.text_for(:t1table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
@@ -46,15 +47,15 @@ private
46
47
  questions << q
47
48
  end
48
49
 
49
- s=Set.new [ lRow[:data][0], lang.text_for(:none) ]
50
+ s = Set.new [ lRow[:data][0], lang.text_for(:none) ]
50
51
  pList.each { |i| s.add( i[:data][0] ) }
51
- a=s.to_a
52
+ a = s.to_a
52
53
 
53
- if s.count>4 then
54
- q=Question.new
55
- q.name="#{name}-#{num.to_s}-t2table-#{lTable.name}"
56
- q.text=lang.text_for(:t2table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
57
- q.good=lang.text_for(:none)
54
+ if s.count > 4
55
+ q = Question.new
56
+ q.name = "#{name}-#{num.to_s}-t2table-#{lTable.name}"
57
+ q.text = lang.text_for(:t2table, name, lTable.fields[0].capitalize, lTable.fields[1].capitalize, lRow[:data][1])
58
+ q.good = lang.text_for(:none)
58
59
  q.bads << a[2]
59
60
  q.bads << a[3]
60
61
  q.bads << a[4]
@@ -62,30 +63,30 @@ private
62
63
  end
63
64
 
64
65
  # Using the column #1
65
- s=Set.new [ lRow[:data][1], lang.text_for(:none) ]
66
+ s = Set.new [ lRow[:data][1], lang.text_for(:none) ]
66
67
  pList.each { |i| s.add( i[:data][1] ) }
67
- a=s.to_a
68
+ a = s.to_a
68
69
 
69
- if s.count>3 then
70
- q=Question.new
71
- q.name="#{name}-#{num.to_s}-t3table-#{lTable.name}"
72
- q.text=lang.text_for(:t3table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
73
- q.good=a[0]
70
+ if s.count > 3
71
+ q = Question.new
72
+ q.name = "#{name}-#{num.to_s}-t3table-#{lTable.name}"
73
+ q.text = lang.text_for(:t3table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
74
+ q.good = a[0]
74
75
  q.bads << lang.text_for(:none)
75
76
  q.bads << a[2]
76
77
  q.bads << a[3]
77
78
  questions << q
78
79
  end
79
80
 
80
- s=Set.new [ lRow[:data][1], lang.text_for(:none) ]
81
+ s = Set.new [ lRow[:data][1], lang.text_for(:none) ]
81
82
  pList.each { |i| s.add( i[:data][1] ) }
82
- a=s.to_a
83
+ a = s.to_a
83
84
 
84
- if s.count>4 then
85
- q=Question.new
86
- q.name="#{name}-#{num.to_s}-t4table-#{lTable.name}"
87
- q.text=lang.text_for(:t4table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
88
- q.good=lang.text_for(:none)
85
+ if s.count > 4
86
+ q = Question.new
87
+ q.name = "#{name}-#{num.to_s}-t4table-#{lTable.name}"
88
+ q.text = lang.text_for(:t4table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
89
+ q.good = lang.text_for(:none)
89
90
  q.bads << a[2]
90
91
  q.bads << a[3]
91
92
  q.bads << a[4]
@@ -93,78 +94,77 @@ private
93
94
  end
94
95
 
95
96
  # Boolean association TRUE
96
- q=Question.new
97
+ q = Question.new
97
98
  q.set_boolean
98
- q.name="#{name}-#{num.to_s}t5table-#{lTable.name}"
99
- q.text=lang.text_for(:t5table, name, lTable.fields[0].capitalize, lRow[:data][0] ,lTable.fields[1].capitalize, lRow[:data][1] )
100
- q.good="TRUE"
99
+ q.name = "#{name}-#{num.to_s}t5table-#{lTable.name}"
100
+ q.text = lang.text_for(:t5table, name, lTable.fields[0].capitalize, lRow[:data][0] ,lTable.fields[1].capitalize, lRow[:data][1] )
101
+ q.good = "TRUE"
101
102
  questions << q
102
103
 
103
104
  # Boolean association FALSE
104
- s=Set.new [ lRow[:data][1] ]
105
+ s = Set.new [ lRow[:data][1] ]
105
106
  pList.each { |i| s.add( i[:data][1] ) }
106
- a=s.to_a
107
+ a = s.to_a
107
108
 
108
- if s.count>1 then
109
- q=Question.new
109
+ if s.count > 1
110
+ q = Question.new
110
111
  q.set_boolean
111
- q.name="#{name}-#{num.to_s}-t6table-#{lTable.name}"
112
- q.text=lang.text_for(:t6table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, a[1] )
113
- q.good="FALSE"
112
+ q.name = "#{name}-#{num.to_s}-t6table-#{lTable.name}"
113
+ q.text = lang.text_for(:t6table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, a[1] )
114
+ q.good = "FALSE"
114
115
  questions << q
115
116
  end
116
117
 
117
- s=Set.new [ lRow[:data][0] ]
118
+ s = Set.new [ lRow[:data][0] ]
118
119
  pList.each { |i| s.add( i[:data][0] ) }
119
- a=s.to_a
120
+ a = s.to_a
120
121
 
121
- if s.count>1 then
122
- q=Question.new
122
+ if s.count > 1
123
+ q = Question.new
123
124
  q.set_boolean
124
- q.name="#{name}-#{num.to_s}t7table-#{lTable.name}"
125
- q.text=lang.text_for(:t7table, name, lTable.fields[0].capitalize, a[1], lTable.fields[1].capitalize, lRow[:data][1] )
126
- q.good="FALSE"
125
+ q.name = "#{name}-#{num.to_s}t7table-#{lTable.name}"
126
+ q.text = lang.text_for(:t7table, name, lTable.fields[0].capitalize, a[1], lTable.fields[1].capitalize, lRow[:data][1] )
127
+ q.good = "FALSE"
127
128
  questions << q
128
129
  end
129
130
 
130
131
  # Short answer with column #0, 1 word
131
- if lang.count_words(lRow[:data][0])==1 then
132
- q=Question.new
132
+ if lang.count_words(lRow[:data][0]) == 1
133
+ q = Question.new
133
134
  q.set_short
134
- q.name="#{name}-#{num.to_s}t8table-#{lTable.name}"
135
- q.text=lang.text_for(:t8table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize)
135
+ q.name = "#{name}-#{num.to_s}t8table-#{lTable.name}"
136
+ q.text = lang.text_for(:t8table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize)
136
137
  q.shorts << lRow[:data][0]
137
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
138
+ q.shorts << lRow[:data][0].gsub('-', ' ').gsub('_', ' ')
138
139
  questions << q
139
- elsif lang.count_words(lRow[:data][0])==2 then
140
- q=Question.new
140
+ elsif lang.count_words(lRow[:data][0]) == 2
141
+ q = Question.new
141
142
  q.set_short
142
- q.name="#{name}-#{num.to_s}t9table-#{lTable.name}"
143
- q.text=lang.text_for(:t9table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize, "[#{lang.hide_text(lRow[:data][0])}]", lang.count_words(lRow[:data][0]) )
143
+ q.name = "#{name}-#{num.to_s}t9table-#{lTable.name}"
144
+ q.text = lang.text_for(:t9table, name, lTable.fields[1].capitalize, lRow[:data][1], lTable.fields[0].capitalize, "[#{lang.hide_text(lRow[:data][0])}]", lang.count_words(lRow[:data][0]) )
144
145
  q.shorts << lRow[:data][0]
145
- q.shorts << lRow[:data][0].gsub("-"," ").gsub("_"," ")
146
+ q.shorts << lRow[:data][0].gsub('-', ' ').gsub('_', ' ')
146
147
  questions << q
147
148
  end
148
149
 
149
150
  # Short answer with column #1, 1 word
150
- if lang.count_words(lRow[:data][1])==1 then
151
- q=Question.new
151
+ if lang.count_words(lRow[:data][1]) == 1
152
+ q = Question.new
152
153
  q.set_short
153
- q.name="#{name}-#{num.to_s}t8table-#{lTable.name}"
154
- q.text=lang.text_for(:t8table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
154
+ q.name = "#{name}-#{num.to_s}t8table-#{lTable.name}"
155
+ q.text = lang.text_for(:t8table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize)
155
156
  q.shorts << lRow[:data][1]
156
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
157
+ q.shorts << lRow[:data][1].gsub('-', ' ').gsub('_', ' ')
157
158
  questions << q
158
- elsif lang.count_words(lRow[:data][1])==2 then
159
- q=Question.new
159
+ elsif lang.count_words(lRow[:data][1]) == 2
160
+ q = Question.new
160
161
  q.set_short
161
- q.name="#{name}-#{num.to_s}t9table-#{lTable.name}"
162
- q.text=lang.text_for(:t9table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, "[#{lang.hide_text(lRow[:data][1])}]", lang.count_words(lRow[:data][1]) )
162
+ q.name = "#{name}-#{num.to_s}t9table-#{lTable.name}"
163
+ q.text = lang.text_for(:t9table, name, lTable.fields[0].capitalize, lRow[:data][0], lTable.fields[1].capitalize, "[#{lang.hide_text(lRow[:data][1])}]", lang.count_words(lRow[:data][1]) )
163
164
  q.shorts << lRow[:data][1]
164
- q.shorts << lRow[:data][1].gsub("-"," ").gsub("_"," ")
165
+ q.shorts << lRow[:data][1].gsub('-', ' ').gsub('_', ' ')
165
166
  questions << q
166
167
  end
167
- return questions
168
+ questions
168
169
  end
169
-
170
170
  end
@@ -2,12 +2,13 @@
2
2
 
3
3
  require 'singleton'
4
4
  require 'inifile'
5
+ require 'rainbow'
5
6
 
6
7
  # Global parameters
7
8
  class Application
8
9
  include Singleton
9
10
 
10
- VERSION = '2.1.5' # Application version
11
+ VERSION = '2.1.6' # Application version
11
12
  NAME = 'asker' # Application name
12
13
  GEM = 'asker-tool' # Gem name
13
14
  attr_reader :config
@@ -20,11 +21,26 @@ class Application
20
21
 
21
22
  ##
22
23
  # Initialize config values from external "config.ini" file.
24
+ # rubocop:disable Metrics/AbcSize
25
+ # rubocop:disable Metrics/MethodLength
23
26
  def reset
24
27
  filename = File.join(Dir.pwd, 'config.ini')
25
28
  unless File.exist? filename
26
29
  filename = File.join(File.dirname(__FILE__), 'files', 'config.ini')
27
30
  end
28
- @config = IniFile.load(filename)
31
+ begin
32
+ @config = IniFile.load(filename)
33
+ rescue StandardError => e
34
+ puts e.display
35
+ puts Rainbow('[ERROR] Revise configuration file:').red.bright
36
+ puts Rainbow(" #{filename}").red.bright
37
+ exit 1
38
+ end
39
+ stages = @config['questions']['stages'].split(',')
40
+ @config['questions']['stages'] = stages.map(&:to_sym)
41
+ Rainbow.enabled = false
42
+ Rainbow.enabled = true if @config['global']['color'].downcase == 'yes'
29
43
  end
44
+ # rubocop:enable Metrics/MethodLength
45
+ # rubocop:enable Metrics/AbcSize
30
46
  end
data/lib/asker/checker.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require 'rainbow'
3
4
 
@@ -12,11 +13,11 @@ module Checker
12
13
  # @param filepath (String)
13
14
  def self.check(filepath)
14
15
  unless File.exist? filepath
15
- puts Rainbow("File not found!").red.bright
16
+ puts Rainbow('File not found!').red.bright
16
17
  return false
17
18
  end
18
19
  unless File.extname(filepath) == '.haml'
19
- puts Rainbow("Only check HAML files!").yellow.bright
20
+ puts Rainbow('Only check HAML files!').yellow.bright
20
21
  return false
21
22
  end
22
23
  check_filepath(filepath)
@@ -29,12 +30,17 @@ module Checker
29
30
  data = Data.new(filepath)
30
31
  data.check
31
32
  data.show_errors
32
- data.is_ok?
33
+ data.ok?
33
34
  end
34
35
 
36
+ ##
37
+ # Internal class that revise syntax
38
+ # rubocop:disable Metrics/ClassLength
35
39
  class Data
36
40
  attr_reader :inputs
37
41
  attr_reader :outputs
42
+
43
+ # rubocop:disable Metrics/MethodLength
38
44
  def initialize(filepath)
39
45
  @inputs = File.read(filepath).split("\n")
40
46
  @outputs = []
@@ -49,8 +55,9 @@ module Checker
49
55
  end
50
56
  @ok = false
51
57
  end
58
+ # rubocop:enable Metrics/MethodLength
52
59
 
53
- def is_ok?
60
+ def ok?
54
61
  @ok
55
62
  end
56
63
 
@@ -60,18 +67,33 @@ module Checker
60
67
  end
61
68
  end
62
69
 
70
+ # rubocop:disable Metrics/AbcSize
71
+ # rubocop:disable Metrics/MethodLength
63
72
  def show_errors
64
73
  errors = 0
74
+ # puts "Line : Error description"
65
75
  @outputs.each do |i|
66
76
  next if i[:state] == :ok
77
+
67
78
  errors += 1
68
- puts "%02d" % i[:id] + ": %s." % i[:msg] + " => #{i[:source][0,40]}" if errors < 11
69
- puts "..." if errors == 11
79
+ if errors < 11
80
+ data = { id: i[:id], msg: i[:msg], source: i[:source][0, 40] }
81
+ puts format(' %<id>03d : %<msg>s. => %<source>s', data)
82
+ end
83
+ puts '...' if errors == 11
70
84
  end
71
- puts Rainbow("[ERROR] #{errors} errors from #{@inputs.size} lines!").red.bright if errors > 0
72
- puts Rainbow("Syntax OK!").green if errors == 0
85
+
86
+ if errors.positive?
87
+ puts Rainbow("[ERROR] #{errors} errors " \
88
+ "from #{@inputs.size} lines!").red.bright
89
+ end
90
+ puts Rainbow('Syntax OK!').green if errors.zero?
73
91
  end
92
+ # rubocop:enable Metrics/AbcSize
93
+ # rubocop:enable Metrics/MethodLength
74
94
 
95
+ # rubocop:disable Metrics/MethodLength
96
+ # rubocop:disable Metrics/AbcSize
75
97
  def check
76
98
  @ok = true
77
99
  @inputs.each_with_index do |line, index|
@@ -95,19 +117,22 @@ module Checker
95
117
  end
96
118
  @ok
97
119
  end
120
+ # rubocop:enable Metrics/MethodLength
121
+ # rubocop:enable Metrics/AbcSize
98
122
 
99
123
  private
100
124
 
101
125
  def check_empty_lines(line, index)
102
- if line.strip.size.zero? or line.start_with? '#'
103
- @outputs[index][:type] = :empty
104
- @outputs[index][:level] = -1
105
- @outputs[index][:state] = :ok
106
- end
126
+ return unless line.strip.size.zero? || line.start_with?('#')
127
+
128
+ @outputs[index][:type] = :empty
129
+ @outputs[index][:level] = -1
130
+ @outputs[index][:state] = :ok
107
131
  end
108
132
 
133
+ # rubocop:disable Metrics/MethodLength
109
134
  def check_map(line, index)
110
- if index == 0
135
+ if index.zero?
111
136
  @outputs[index][:type] = :map
112
137
  if line.start_with?('%map{')
113
138
  @outputs[index][:state] = :ok
@@ -115,13 +140,15 @@ module Checker
115
140
  @outputs[index][:state] = :err
116
141
  @outputs[index][:msg] = 'Start with %map{'
117
142
  end
118
- elsif index > 0 and line.include?('%map{')
143
+ elsif index.positive? && line.include?('%map{')
119
144
  @outputs[index][:state] = :err
120
145
  @outputs[index][:type] = :map
121
146
  @outputs[index][:msg] = 'Write %map on line 0'
122
147
  end
123
148
  end
149
+ # rubocop:enable Metrics/MethodLength
124
150
 
151
+ # rubocop:disable Metrics/MethodLength
125
152
  def check_concept(line, index)
126
153
  return unless @outputs[index][:state] == :none
127
154
  return unless line.include? '%concept'
@@ -137,7 +164,10 @@ module Checker
137
164
  @outputs[index][:msg] = 'Write 2 spaces before %concept'
138
165
  end
139
166
  end
167
+ # rubocop:enable Metrics/MethodLength
140
168
 
169
+ # rubocop:disable Metrics/AbcSize
170
+ # rubocop:disable Metrics/MethodLength
141
171
  def check_names(line, index)
142
172
  return unless @outputs[index][:state] == :none
143
173
  return unless line.include? '%names'
@@ -153,7 +183,11 @@ module Checker
153
183
  @outputs[index][:msg] = 'Write 4 spaces before %names'
154
184
  end
155
185
  end
186
+ # rubocop:enable Metrics/AbcSize
187
+ # rubocop:enable Metrics/MethodLength
156
188
 
189
+ # rubocop:disable Metrics/AbcSize
190
+ # rubocop:disable Metrics/MethodLength
157
191
  def check_tags(line, index)
158
192
  return unless @outputs[index][:state] == :none
159
193
  return unless line.include? '%tags'
@@ -169,7 +203,11 @@ module Checker
169
203
  @outputs[index][:msg] = 'Write 4 spaces before %tags'
170
204
  end
171
205
  end
206
+ # rubocop:enable Metrics/AbcSize
207
+ # rubocop:enable Metrics/MethodLength
172
208
 
209
+ # rubocop:disable Metrics/AbcSize
210
+ # rubocop:disable Metrics/MethodLength
173
211
  def check_def(line, index)
174
212
  return unless @outputs[index][:state] == :none
175
213
  return unless line.include? '%def'
@@ -185,7 +223,11 @@ module Checker
185
223
  @outputs[index][:msg] = 'Write 4 spaces before %def'
186
224
  end
187
225
  end
226
+ # rubocop:enable Metrics/AbcSize
227
+ # rubocop:enable Metrics/MethodLength
188
228
 
229
+ # rubocop:disable Metrics/AbcSize
230
+ # rubocop:disable Metrics/MethodLength
189
231
  def check_table(line, index)
190
232
  return unless @outputs[index][:state] == :none
191
233
  return unless line.include? '%table'
@@ -201,7 +243,13 @@ module Checker
201
243
  @outputs[index][:msg] = 'Write 4 spaces before %table'
202
244
  end
203
245
  end
246
+ # rubocop:enable Metrics/AbcSize
247
+ # rubocop:enable Metrics/MethodLength
204
248
 
249
+ # rubocop:disable Metrics/AbcSize
250
+ # rubocop:disable Metrics/CyclomaticComplexity
251
+ # rubocop:disable Metrics/MethodLength
252
+ # rubocop:disable Metrics/PerceivedComplexity
205
253
  def check_row(line, index)
206
254
  return unless @outputs[index][:state] == :none
207
255
  return unless line.include? '%row'
@@ -212,7 +260,7 @@ module Checker
212
260
  if count_spaces(line) == 6
213
261
  @outputs[index][:level] = 3
214
262
  parent = find_parent(index)
215
- unless [:table, :features].include? parent
263
+ unless %i[table features].include? parent
216
264
  @outputs[index][:state] = :err
217
265
  @outputs[index][:msg] = 'Parent(table/features) not found!'
218
266
  end
@@ -227,7 +275,15 @@ module Checker
227
275
  @outputs[index][:msg] = 'Write 6 or 8 spaces before %row'
228
276
  end
229
277
  end
230
-
278
+ # rubocop:enable Metrics/AbcSize
279
+ # rubocop:enable Metrics/CyclomaticComplexity
280
+ # rubocop:enable Metrics/MethodLength
281
+ # rubocop:enable Metrics/PerceivedComplexity
282
+
283
+ # rubocop:disable Metrics/AbcSize
284
+ # rubocop:disable Metrics/CyclomaticComplexity
285
+ # rubocop:disable Metrics/MethodLength
286
+ # rubocop:disable Metrics/PerceivedComplexity
231
287
  def check_col(line, index)
232
288
  return unless @outputs[index][:state] == :none
233
289
  return unless line.include? '%col'
@@ -250,8 +306,28 @@ module Checker
250
306
  @outputs[index][:state] = :err
251
307
  @outputs[index][:msg] = 'Write 8 or 10 spaces before %col'
252
308
  end
309
+ check_text(line, index)
310
+ end
311
+ # rubocop:enable Metrics/AbcSize
312
+ # rubocop:enable Metrics/CyclomaticComplexity
313
+ # rubocop:enable Metrics/MethodLength
314
+ # rubocop:enable Metrics/PerceivedComplexity
315
+
316
+ def check_text(line, index)
317
+ return unless @outputs[index][:state] == :ok
318
+
319
+ ok = ''
320
+ %w[< >].each do |char|
321
+ ok = char if line.include? char
322
+ end
323
+ return if ok == ''
324
+
325
+ @outputs[index][:state] = :err
326
+ @outputs[index][:msg] = "Char #{ok} not allow!"
253
327
  end
254
328
 
329
+ # rubocop:disable Metrics/MethodLength
330
+ # rubocop:disable Metrics/AbcSize
255
331
  def check_template(line, index)
256
332
  return unless @outputs[index][:state] == :none
257
333
  return unless line.include? '%template'
@@ -267,7 +343,10 @@ module Checker
267
343
  @outputs[index][:msg] = 'Write 6 spaces before %template'
268
344
  end
269
345
  end
346
+ # rubocop:enable Metrics/AbcSize
347
+ # rubocop:enable Metrics/MethodLength
270
348
 
349
+ # rubocop:disable Metrics/MethodLength
271
350
  def check_code(line, index)
272
351
  return unless @outputs[index][:state] == :none
273
352
  return unless line.include? '%code'
@@ -283,7 +362,10 @@ module Checker
283
362
  @outputs[index][:msg] = 'Write 2 spaces before %code'
284
363
  end
285
364
  end
365
+ # rubocop:enable Metrics/MethodLength
286
366
 
367
+ # rubocop:disable Metrics/MethodLength
368
+ # rubocop:disable Metrics/AbcSize
287
369
  def check_type(line, index)
288
370
  return unless @outputs[index][:state] == :none
289
371
  return unless line.include? '%type'
@@ -299,7 +381,11 @@ module Checker
299
381
  @outputs[index][:msg] = 'Write 4 spaces before %type'
300
382
  end
301
383
  end
384
+ # rubocop:enable Metrics/AbcSize
385
+ # rubocop:enable Metrics/MethodLength
302
386
 
387
+ # rubocop:disable Metrics/MethodLength
388
+ # rubocop:disable Metrics/AbcSize
303
389
  def check_path(line, index)
304
390
  return unless @outputs[index][:state] == :none
305
391
  return unless line.include? '%path'
@@ -315,7 +401,11 @@ module Checker
315
401
  @outputs[index][:msg] = 'Write 4 spaces before %type'
316
402
  end
317
403
  end
404
+ # rubocop:enable Metrics/AbcSize
405
+ # rubocop:enable Metrics/MethodLength
318
406
 
407
+ # rubocop:disable Metrics/MethodLength
408
+ # rubocop:disable Metrics/AbcSize
319
409
  def check_features(line, index)
320
410
  return unless @outputs[index][:state] == :none
321
411
  return unless line.include? '%features'
@@ -331,6 +421,8 @@ module Checker
331
421
  @outputs[index][:msg] = 'Write 4 spaces before %features'
332
422
  end
333
423
  end
424
+ # rubocop:enable Metrics/AbcSize
425
+ # rubocop:enable Metrics/MethodLength
334
426
 
335
427
  def check_unknown(line, index)
336
428
  return unless @outputs[index][:state] == :none
@@ -355,19 +447,9 @@ module Checker
355
447
  end
356
448
 
357
449
  def count_spaces(line)
358
- return 0 if line.start_with? '%'
359
- return 1 if line.start_with? ' %'
360
- return 2 if line.start_with? ' %'
361
- return 3 if line.start_with? ' %'
362
- return 4 if line.start_with? ' %'
363
- return 5 if line.start_with? ' %'
364
- return 6 if line.start_with? ' %'
365
- return 7 if line.start_with? ' %'
366
- return 8 if line.start_with? ' %'
367
- return 9 if line.start_with? ' %'
368
- return 10 if line.start_with? ' %'
369
-
370
- -1
450
+ a = line.split('%')
451
+ a[0].count(' ')
371
452
  end
372
453
  end
454
+ # rubocop:enable Metrics/ClassLength
373
455
  end