asker-tool 2.1.5 → 2.1.6

Sign up to get free protection for your applications and to get access to all the features.
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