mumuki-sqlite-runner 3.3.0 → 3.3.4

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
  SHA256:
3
- metadata.gz: 3734b0af25cc1a8f563c7bfda8e13a7891f78421fbcda0710553bc3c5140ee8e
4
- data.tar.gz: 78b63bfb30f4f4ef26742db5e5b1f98deb80a9b89ff64d1eeddc2b0111b7ceb9
3
+ metadata.gz: fd53507ebff39f0daa4369c29adbc3b7fa0650eccc2f3ef7abd6de296ffbbe00
4
+ data.tar.gz: ec8829a963f3cbb38b2d18b904a60aff7d54c10ba269fa19333121a89d5b5b52
5
5
  SHA512:
6
- metadata.gz: eb05abd4833c0f3f7ab3a3d6125bbbfd6a1fceea140b9dead9be60a37c4030b562a2c0548614854b0afc1a3f4e2c4db9b42cca954fa8e81c48de5f6c73fa354b
7
- data.tar.gz: 30cd885678391688ff8fe2b0d3cea9a34cc51a4bf31d5bae8eee956102a7986b2f646f8db194ac4ef00bf3d883ded8418f77e4eaa4c2ca1749cdfac06fc52c82
6
+ metadata.gz: 6283b043775cc86885562d72c8d81430d4b395945f124d9e79d27f542f9737f476eaef3c3aab389e616f9df942219285df8d028ae72d9ae5ccc0b1814d2861be
7
+ data.tar.gz: 69843d6ede2fdf6be2213afecadc4f2b171c816bd32003c60f03e21c61656fada03cb3ab645eb01f5d3ee1bcfe325c27f35cebd56f68f2451c28a4d87cb16d74
data/lib/dataset.rb CHANGED
@@ -35,7 +35,7 @@ module Sqlite
35
35
  end
36
36
 
37
37
  def same_header(other_header)
38
- @header.eql? other_header
38
+ @header.map(&:downcase).eql? other_header.map(&:downcase)
39
39
  end
40
40
 
41
41
  def same_rows(other_rows)
data/lib/helpers.rb CHANGED
@@ -16,5 +16,8 @@ module Sqlite
16
16
  tests.map(&:to_struct)
17
17
  end
18
18
 
19
+ def fail!(*args)
20
+ raise Mumukit::RequestValidationError, I18n.t(*args)
21
+ end
19
22
  end
20
23
  end
data/lib/html_renderer.rb CHANGED
@@ -5,26 +5,30 @@ module Sqlite
5
5
 
6
6
  def render_success(result, message)
7
7
  @message = message
8
- @header = result[:dataset].header
9
- @rows = result[:dataset].rows
8
+ @table_name = result[:table_name]
9
+ @header = result[:dataset].header
10
+ @rows = result[:dataset].rows
11
+ @extra_message = extra_message result
10
12
  template_file_success.result binding
11
13
  end
12
14
 
13
15
  def render_error(result, solution, error)
14
16
  @error = error
17
+ @table_name = result[:table_name]
15
18
  @result = parse_dataset(result[:dataset].header, result[:dataset].rows)
16
19
  @solution = parse_dataset(solution[:dataset].header, solution[:dataset].rows)
17
-
20
+ @expected_message = expected_message result
21
+ @obtained_message = I18n.t 'obtained'
18
22
  template_file_error.result binding
19
23
  end
20
24
 
21
25
  protected
22
26
 
23
27
  def parse_dataset(header, rows)
24
- header_sign = header.shift
28
+ header_sign = first_column(header)
25
29
  rows = rows.map do |row|
26
30
  {
27
- sign: row.shift,
31
+ sign: first_column(row),
28
32
  row: row
29
33
  }
30
34
  end
@@ -37,7 +41,7 @@ module Sqlite
37
41
  },
38
42
  rows: rows.map do |row|
39
43
  {
40
- sign:row[:sign],
44
+ sign: row[:sign],
41
45
  class: diff_class_of(row[:sign]),
42
46
  fields: row[:row]
43
47
  }
@@ -46,6 +50,10 @@ module Sqlite
46
50
 
47
51
  end
48
52
 
53
+ def first_column(row)
54
+ row.first.present? && row.first =~ /^[+-]$/ ? row.shift : '✓'
55
+ end
56
+
49
57
  def diff_class_of(value)
50
58
  case value
51
59
  when '+'
@@ -57,6 +65,18 @@ module Sqlite
57
65
  end
58
66
  end
59
67
 
68
+ def extra_message(result)
69
+ result[:show_query] ? I18n.t('message.success.show_query', query: result[:query]) : ''
70
+ end
71
+
72
+ def expected_message(result)
73
+ if result[:show_query]
74
+ I18n.t('message.failure.show_query', query: result[:query])
75
+ else
76
+ I18n.t 'expected'
77
+ end
78
+ end
79
+
60
80
  def template_file_success
61
81
  ERB.new File.read("#{__dir__}/view/rows_success.html.erb")
62
82
  end
data/lib/locales/en.yml CHANGED
@@ -1,9 +1,15 @@
1
1
  en:
2
2
  dataset: "Dataset %{number}"
3
+ default_table_name: 'Result'
4
+ expected: 'It was expected:'
5
+ obtained: 'It was obtained:'
3
6
  message:
4
7
  success:
5
8
  query: 'Correct Query!'
9
+ show_query: 'The query `%{query}` returns:'
6
10
  failure:
11
+ show_query: 'The query `%{query}` should return:'
12
+ semicolon_ending: 'You should finish each SQL statement with a semicolon (;)'
7
13
  columns: 'Columns do not match'
8
14
  rows: 'Rows do not match'
9
15
  query: 'Queries do not match'
@@ -0,0 +1,24 @@
1
+ es:
2
+ dataset: "Set de datos %{number}"
3
+ default_table_name: 'Resultado'
4
+ expected: 'Se esperaba:'
5
+ obtained: 'Se obtuvo:'
6
+ message:
7
+ success:
8
+ query: '¡Consulta correcta!'
9
+ show_query: 'La consulta `%{query}` devolvió:'
10
+ failure:
11
+ show_query: 'Se esperaba que la consulta `%{query}` devolviera:'
12
+ semicolon_ending: 'Tienes que terminar cada sentencia SQL con punto y coma (;)'
13
+ columns: 'Las columnas no coinciden'
14
+ rows: 'Las filas no coinciden'
15
+ query: 'Las consultas no coinciden'
16
+ tests:
17
+ lint: "¡Tests inválidos! No tienen el formato YAML correcto. Puedes probar en este validador http://www.yamllint.com/"
18
+ type: "tienes que declarar el campo type:"
19
+ types: "El test type '%{type}' no está soportado. Tienes que usar uno de éstos: datasets, query, display, final_dataset"
20
+ fields:
21
+ query: "Para el type:query deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), expected (requerido)"
22
+ datasets: "Para el type:datasets deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), expected (requerido)"
23
+ final_dataset: "Para el type:final_dataset, deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), final (requerido), expected (requerido)"
24
+ display: "Para el type:display deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), query (requerido)"
data/lib/locales/es.yml CHANGED
@@ -1,9 +1,15 @@
1
1
  es:
2
2
  dataset: "Set de datos %{number}"
3
+ default_table_name: 'Resultado'
4
+ expected: 'Se esperaba:'
5
+ obtained: 'Se obtuvo:'
3
6
  message:
4
7
  success:
5
8
  query: '¡Consulta correcta!'
9
+ show_query: 'La consulta `%{query}` devolvió:'
6
10
  failure:
11
+ show_query: 'Se esperaba que la consulta `%{query}` devolviera:'
12
+ semicolon_ending: 'Tenés que terminar cada sentencia SQL con punto y coma (;)'
7
13
  columns: 'Las columnas no coinciden'
8
14
  rows: 'Las filas no coinciden'
9
15
  query: 'Las consultas no coinciden'
@@ -26,6 +26,14 @@ module Sqlite
26
26
  ''
27
27
  end
28
28
 
29
+ def show_query?
30
+ false
31
+ end
32
+
33
+ def table_name
34
+ has?(:result_alias) ? get(:result_alias) : I18n.t('default_table_name')
35
+ end
36
+
29
37
  protected
30
38
 
31
39
  def transform_test
@@ -11,6 +11,10 @@ module Sqlite
11
11
  }
12
12
  end
13
13
 
14
+ def show_query?
15
+ true
16
+ end
17
+
14
18
  def get_final_query
15
19
  has?(:final) ? get(:final) : get(:query)
16
20
  end
data/lib/sqlite_runner.rb CHANGED
@@ -16,7 +16,7 @@ require_relative './version_hook'
16
16
  require_relative './metadata_hook'
17
17
  require_relative './html_renderer'
18
18
  require_relative './multiple_executions_runner'
19
- require_relative './parsers/general_parser'
19
+ require_relative './parsers/base_parser'
20
20
  require_relative './parsers/query_parser'
21
21
  require_relative './parsers/display_parser'
22
22
  require_relative './parsers/datasets_parser'
data/lib/test_hook.rb CHANGED
@@ -19,9 +19,10 @@ class SqliteTestHook < Mumukit::Templates::FileHook
19
19
  # Transform Mumuki Request into Docker file style
20
20
  def compile_file_content(request)
21
21
  parse_tests request.test
22
+ student_code = parse_student_code "#{request.content&.strip}#{get_final_query}"
22
23
  {
23
24
  init: "#{request.extra&.strip}",
24
- student: "#{request.content&.strip}#{get_final_query}",
25
+ student: student_code,
25
26
  tests: get_tests
26
27
  }.to_json
27
28
  end
@@ -48,13 +49,24 @@ class SqliteTestHook < Mumukit::Templates::FileHook
48
49
  expected.map!.with_index do |expect, i|
49
50
  @tests[i].choose_solution expect
50
51
  end
52
+ student = normalize_headers(student)
53
+ expected = normalize_headers(expected)
51
54
  diff(expected, student)
52
55
  end
53
56
 
57
+ def normalize_headers(results)
58
+ results.map do |result|
59
+ headers, *rows = result.split("\n")
60
+
61
+ headers.downcase!
62
+ [headers, *rows].join("\n")
63
+ end
64
+ end
65
+
54
66
  # Make diff between expected and student dataset result and mark each line one according comparision
55
67
  def diff(expected, student)
56
68
  zipped = expected.zip(student).map do |expected_i, student_i|
57
- diff = Diffy::SplitDiff.new student_i << "\n", expected_i << "\n"
69
+ diff = Diffy::SplitDiff.new expected_i << "\n", student_i << "\n"
58
70
  choose_left_right(diff, expected_i, student_i).map { |e| post_process_diff e }
59
71
  end
60
72
  zipped.transpose.map { |dataset| post_process_datasets dataset }
@@ -66,22 +78,38 @@ class SqliteTestHook < Mumukit::Templates::FileHook
66
78
  [expected, student]
67
79
  end
68
80
 
81
+ # split lines grouping by diff mark & data content
82
+ # then append mark as dataset column & re join
69
83
  def post_process_diff(data)
70
- data.scan(/^(\s|-|\+)(.+)/)
71
- .map { |mark, content| mark << '|' << content }
84
+ data.scan(/^(\s|-|\+)*(.+)/)
85
+ .map { |mark, content| "#{proper_mark(mark)}#{content}" }
72
86
  .join("\n")
73
87
  end
74
88
 
89
+ def proper_mark(mark)
90
+ mark = mark.to_s
91
+ "#{mark}|" unless mark.blank?
92
+ end
93
+
75
94
  # Transforms array datasets into hash with :id & :rows
76
95
  def post_process_datasets(datasets)
77
96
  datasets.map.with_index do |dataset, i|
78
97
  {
79
98
  id: i + 1,
80
- dataset: Sqlite::Dataset.new(dataset)
99
+ dataset: Sqlite::Dataset.new(dataset),
100
+ table_name: @tests[i].table_name,
101
+ show_query: @tests[i].show_query?,
102
+ query: @tests[i].get_final_query
81
103
  }
82
104
  end
83
105
  end
84
106
 
107
+ def parse_student_code(code)
108
+ code = code&.strip
109
+ fail! 'message.failure.semicolon_ending' unless code&.end_with? ';'
110
+ code
111
+ end
112
+
85
113
  # This method receives a list of test cases and transforms each one according it parser
86
114
  def parse_tests(tests)
87
115
  @tests = collect_tests(tests).map do |test|
@@ -29,8 +29,4 @@ class SqliteValidationHook < Mumukit::Hook
29
29
  fail! "message.failure.tests.fields.#{test.type}" unless parser.test_has_valid_fields? test
30
30
  end
31
31
  end
32
-
33
- def fail!(*args)
34
- raise Mumukit::RequestValidationError, I18n.t(*args)
35
- end
36
32
  end
data/lib/version_hook.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module SqliteVersionHook
2
- VERSION = '3.3.0'
2
+ VERSION = '3.3.4'
3
3
  end
@@ -1,29 +1,4 @@
1
1
  <style>
2
- table.sqlite_error {
3
- width: auto;
4
- }
5
- table.sqlite_result {
6
- border: none;
7
- }
8
- table.sqlite_solution {
9
- border: none;
10
- }
11
- table.sqlite_error tr:nth-child(even) {
12
- background-color: #EEEEEE;
13
- }
14
- table.sqlite_error tr:nth-child(odd) {
15
- background-color: #FFFFFF;
16
- }
17
- table.sqlite_error th {
18
- color: white;
19
- font-weight: bold;
20
- background-color: #2E2F30;
21
- }
22
- table.sqlite_error td {
23
- width: auto;
24
- text-align: left;
25
- }
26
-
27
2
  .required {
28
3
  color: #5cb85c;
29
4
  font-style: italic;
@@ -32,25 +7,6 @@
32
7
  color: #d9534f;
33
8
  font-style: italic;
34
9
  }
35
-
36
- .required :first-child,
37
- .errored :first-child,
38
- .nothing :first-child {
39
- font-style: normal;
40
- padding-left: 2px;
41
- padding-right: 2px;
42
- background-color: white;
43
- border-left: none;
44
- border-bottom: 1px solid white;
45
- }
46
- .required :first-child {
47
- color: white;
48
- background-color: #5cb85c;
49
- }
50
- .errored :first-child {
51
- color: white;
52
- background-color: #d9534f;
53
- }
54
10
  </style>
55
11
 
56
12
  <h5><%= @error %></h5>
@@ -59,55 +15,61 @@
59
15
 
60
16
  <!-- Result -->
61
17
  <div class="col-md-6">
62
- <h6>Se esperaba:</h6>
63
- <table class="table table-bordered sqlite_error sqlite_result">
64
- <thead>
65
- <tr class="<%= @result[:header][:class] %>">
66
- <th><%= @result[:header][:sign] %></th>
67
- <% @result[:header][:fields].each do |field| %>
68
- <th><%= field %></th>
18
+ <h6><%= @expected_message %></h6>
19
+
20
+ <div class="mu-sql-table-rendered">
21
+ <header><%= @table_name %></header>
22
+ <table>
23
+ <thead>
24
+ <tr class="<%= @result[:header][:class] %>">
25
+ <th><%= @result[:header][:sign] %></th>
26
+ <% @result[:header][:fields].each do |field| %>
27
+ <th><%= field %></th>
28
+ <% end %>
29
+ </tr>
30
+ </thead>
31
+ <tbody>
32
+ <% @result[:rows].each do |row| %>
33
+ <tr class="<%= row[:class] %>">
34
+ <td><%= row[:sign] %></td>
35
+ <% row[:fields].each do |field| %>
36
+ <td><%= field %></td>
37
+ <% end %>
38
+ </tr>
69
39
  <% end %>
70
- </tr>
71
- </thead>
40
+ </tbody>
41
+ </table>
42
+ </div>
43
+
72
44
 
73
- <tbody>
74
- <% @result[:rows].each do |row| %>
75
- <tr class="<%= row[:class] %>">
76
- <td><%= row[:sign] %></td>
77
- <% row[:fields].each do |field| %>
78
- <td><%= field %></td>
79
- <% end %>
80
- </tr>
81
- <% end %>
82
- </tbody>
83
- </table>
84
45
  </div>
85
46
 
86
47
  <!-- Solution -->
87
48
  <div class="col-md-6">
88
- <h6>Se obtuvo:</h6>
89
- <table class="table table-bordered sqlite_error sqlite_solution">
90
- <thead>
91
- <tr class="<%= @result[:header][:class] %>">
92
- <th><%= @result[:header][:sign] %></th>
93
- <% @solution[:header][:fields].each do |field| %>
94
- <th><%= field %></th>
49
+ <h6><%= @obtained_message %></h6>
50
+
51
+ <div class="mu-sql-table-rendered">
52
+ <header><%= @table_name %></header>
53
+ <table>
54
+ <thead>
55
+ <tr class="<%= @result[:header][:class] %>">
56
+ <th><%= @result[:header][:sign] %></th>
57
+ <% @solution[:header][:fields].each do |field| %>
58
+ <th><%= field %></th>
59
+ <% end %>
60
+ </tr>
61
+ </thead>
62
+ <tbody>
63
+ <% @solution[:rows].each do |row| %>
64
+ <tr class="<%= row[:class] %>">
65
+ <td><%= row[:sign] %></td>
66
+ <% row[:fields].each do |field| %>
67
+ <td><%= field %></td>
68
+ <% end %>
69
+ </tr>
95
70
  <% end %>
96
- </tr>
97
- </thead>
98
-
99
- <tbody>
100
- <% @solution[:rows].each do |row| %>
101
- <tr class="<%= row[:class] %>">
102
- <td><%= row[:sign] %></td>
103
- <% row[:fields].each do |field| %>
104
- <td><%= field %></td>
105
- <% end %>
106
- </tr>
107
- <% end %>
108
- </tbody>
109
- </table>
71
+ </tbody>
72
+ </table>
73
+ </div>
110
74
  </div>
111
75
  </div>
112
-
113
-
@@ -1,42 +1,26 @@
1
- <style>
2
- table.sqlite_success {
3
- width: auto;
4
- border: none;
5
- }
6
- table.sqlite_success tr:nth-child(even) {
7
- background-color: #DDDDDD;
8
- }
9
- table.sqlite_success tr:nth-child(odd) {
10
- background-color: #FFFFFF;
11
- }
12
- table.sqlite_success th {
13
- color: white;
14
- font-weight: bold;
15
- background-color: #BBBBBB;
16
- }
17
- table.sqlite_success td {
18
- width: auto;
19
- text-align: left;
20
- }
21
- </style>
22
-
23
1
  <h5><%= message %></h5>
24
- <table class="table table-bordered sqlite_success">
25
- <thead>
26
- <tr>
27
- <% @header.each do |field| %>
28
- <th><%= field %></th>
29
- <% end %>
30
- </tr>
31
- </thead>
2
+ <% if @extra_message %>
3
+ <h6><%= @extra_message %></h6>
4
+ <% end %>
32
5
 
33
- <tbody>
34
- <% @rows.each do |row| %>
35
- <tr>
36
- <% row.each do |field| %>
37
- <td><%= field %></td>
6
+ <div class="mu-sql-table-rendered">
7
+ <header><%= @table_name %></header>
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <% @header.each do |field| %>
12
+ <th><%= field %></th>
38
13
  <% end %>
39
- </tr>
40
- <% end %>
41
- </tbody>
42
- </table>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% @rows.each do |row| %>
18
+ <tr>
19
+ <% row.each do |field| %>
20
+ <td><%= field %></td>
21
+ <% end %>
22
+ </tr>
23
+ <% end %>
24
+ </tbody>
25
+ </table>
26
+ </div>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumuki-sqlite-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Di Lorenzo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-03 00:00:00.000000000 Z
11
+ date: 2021-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mumukit
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.7'
61
+ version: '2.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.7'
68
+ version: '2.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +156,14 @@ dependencies:
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: '1.3'
159
+ version: '3.1'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: '1.3'
166
+ version: '3.1'
167
167
  description:
168
168
  email:
169
169
  - leandro.jdl@gmail.com
@@ -177,13 +177,14 @@ files:
177
177
  - lib/helpers.rb
178
178
  - lib/html_renderer.rb
179
179
  - lib/locales/en.yml
180
+ - lib/locales/es-CL.yml
180
181
  - lib/locales/es.yml
181
182
  - lib/metadata_hook.rb
182
183
  - lib/multiple_executions_runner.rb
184
+ - lib/parsers/base_parser.rb
183
185
  - lib/parsers/datasets_parser.rb
184
186
  - lib/parsers/display_parser.rb
185
187
  - lib/parsers/final_dataset_parser.rb
186
- - lib/parsers/general_parser.rb
187
188
  - lib/parsers/query_parser.rb
188
189
  - lib/sqlite_runner.rb
189
190
  - lib/test_hook.rb
@@ -210,8 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
211
  - !ruby/object:Gem::Version
211
212
  version: '0'
212
213
  requirements: []
213
- rubyforge_project:
214
- rubygems_version: 2.7.4
214
+ rubygems_version: 3.0.3
215
215
  signing_key:
216
216
  specification_version: 4
217
217
  summary: SQLite Runner for Mumuki