mumuki-sqlite-runner 3.3.0 → 3.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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