mumuki-sqlite-runner 3.2.0 → 3.3.3
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 +4 -4
- data/lib/dataset.rb +1 -1
- data/lib/helpers.rb +10 -8
- data/lib/html_renderer.rb +26 -6
- data/lib/locales/en.yml +12 -0
- data/lib/locales/es-CL.yml +24 -0
- data/lib/locales/es.yml +12 -0
- data/lib/parsers/base_parser.rb +62 -0
- data/lib/parsers/datasets_parser.rb +33 -0
- data/lib/parsers/display_parser.rb +21 -0
- data/lib/parsers/final_dataset_parser.rb +29 -0
- data/lib/parsers/query_parser.rb +17 -0
- data/lib/sqlite_runner.rb +5 -6
- data/lib/test_hook.rb +34 -19
- data/lib/validation_hook.rb +15 -14
- data/lib/version_hook.rb +1 -1
- data/lib/view/rows_error.html.erb +49 -87
- data/lib/view/rows_success.html.erb +23 -39
- metadata +13 -14
- data/lib/parsers/common_test_parser.rb +0 -45
- data/lib/parsers/dataset_test_parser.rb +0 -29
- data/lib/parsers/display_test_parser.rb +0 -18
- data/lib/parsers/final_dataset_test_parser.rb +0 -14
- data/lib/parsers/invalid_test_parser.rb +0 -10
- data/lib/parsers/query_test_parser.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d47ec94e08c7d9c855d17bfedc35b1a7709d5d0e22682a2b129ad5425e14d17e
|
4
|
+
data.tar.gz: 4ffe138556f5a890a71e3cdcd816fdf596917a40527472a07d15907013abac6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 558a62973b1078fc23e3ad1ddeb668cc1738d5560229b3c76c2d8b775a659df22192dd8534054a3ad7db50a49d208b5075b3f610c1b41459e5cc34a8041717e2
|
7
|
+
data.tar.gz: '0187ab08320aa59793522521a3063f7aeb75ea18cc41684782d847249c11771d7aa28c452131b4562e3efbdef991c13ae07bc98088e2b84c1cb5d435782f91b1'
|
data/lib/dataset.rb
CHANGED
data/lib/helpers.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
module Sqlite
|
2
2
|
module TestHelper
|
3
3
|
|
4
|
-
def
|
5
|
-
@
|
6
|
-
query: Sqlite::
|
7
|
-
display: Sqlite::
|
8
|
-
datasets: Sqlite::
|
9
|
-
final_dataset: Sqlite::
|
4
|
+
def parsers
|
5
|
+
@parsers ||= {
|
6
|
+
query: Sqlite::QueryParser,
|
7
|
+
display: Sqlite::DisplayParser,
|
8
|
+
datasets: Sqlite::DatasetsParser,
|
9
|
+
final_dataset: Sqlite::FinalDatasetParser,
|
10
10
|
}
|
11
|
-
@test_parsers.default = Sqlite::InvalidTestParser
|
12
11
|
end
|
13
12
|
|
14
|
-
def
|
13
|
+
def collect_tests(test)
|
15
14
|
tests = YAML.load test
|
16
15
|
tests = [tests] unless tests.kind_of? Array
|
17
16
|
tests.map(&:to_struct)
|
18
17
|
end
|
19
18
|
|
19
|
+
def fail!(*args)
|
20
|
+
raise Mumukit::RequestValidationError, I18n.t(*args)
|
21
|
+
end
|
20
22
|
end
|
21
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
|
-
@
|
9
|
-
@
|
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
|
28
|
+
header_sign = first_column(header)
|
25
29
|
rows = rows.map do |row|
|
26
30
|
{
|
27
|
-
sign: row
|
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,12 +1,24 @@
|
|
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'
|
10
16
|
tests:
|
11
17
|
lint: "Invalid tests, It should be a valid YAML format. Try with this validator http://www.yamllint.com/"
|
18
|
+
type: "You need to declare field type:"
|
12
19
|
types: "Unsupported test type '%{type}'. Use one of these: datasets, query, display, final_dataset"
|
20
|
+
fields:
|
21
|
+
query: "For type:query you should use ONLY these fields: type (required), seed (optional), expected (required)"
|
22
|
+
datasets: "For type:datasets you should use ONLY these fields: type (required), seed (optional), expected (required)"
|
23
|
+
final_dataset: "For type:final_dataset you should use ONLY these fields: type (required), seed (optional), final (required), expected (required)"
|
24
|
+
display: "For type:display you should use ONLY these fields: type (required), seed (optional), query (required)"
|
@@ -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,12 +1,24 @@
|
|
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'
|
10
16
|
tests:
|
11
17
|
lint: "¡Tests inválidos! No tienen el formato YAML correcto. Podés probar en este validador http://www.yamllint.com/"
|
18
|
+
type: "Tenés que declarar el campo type:"
|
12
19
|
types: "El test type '%{type}' no está soportado. Tenés 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)"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Sqlite
|
2
|
+
class BaseParser
|
3
|
+
|
4
|
+
COMMENT = '-- NONE'
|
5
|
+
attr_reader :test_result
|
6
|
+
|
7
|
+
def parse_test(test)
|
8
|
+
@test = test
|
9
|
+
@test_result = transform_test
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_has_valid_fields?(test)
|
13
|
+
required = @fields[:required].sort
|
14
|
+
optional = @fields[:optional]
|
15
|
+
keys = process_alias test.to_h.keys.map(&:to_sym).sort
|
16
|
+
(keys - optional).eql? required
|
17
|
+
end
|
18
|
+
|
19
|
+
# A Parser can choose it's own solution or just return which is passed.
|
20
|
+
# This is default choice
|
21
|
+
def choose_solution(solution)
|
22
|
+
solution
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_final_query
|
26
|
+
''
|
27
|
+
end
|
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
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def transform_test
|
40
|
+
{
|
41
|
+
seed: get_seed,
|
42
|
+
expected: get_expected
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def has?(key)
|
47
|
+
!@test[key.to_sym].blank?
|
48
|
+
end
|
49
|
+
|
50
|
+
def get(key)
|
51
|
+
@test[key.to_sym]
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_seed
|
55
|
+
has?(:seed) ? get(:seed).strip : ''
|
56
|
+
end
|
57
|
+
|
58
|
+
def process_alias(keys)
|
59
|
+
keys
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Sqlite
|
2
|
+
class DatasetsParser < BaseParser
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@fields = {
|
6
|
+
required: [:type, :expected],
|
7
|
+
optional: [:seed]
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def choose_solution(_solution)
|
12
|
+
@solutions
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def transform_test
|
18
|
+
@solutions = strip_lines get(:expected)
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_expected
|
23
|
+
COMMENT
|
24
|
+
end
|
25
|
+
|
26
|
+
def strip_lines(array)
|
27
|
+
array.to_s
|
28
|
+
.split("\n")
|
29
|
+
.map(&:strip)
|
30
|
+
.join("\n")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Sqlite
|
2
|
+
class DisplayParser < BaseParser
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@fields = {
|
6
|
+
required: [:type, :query],
|
7
|
+
optional: [:seed]
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_final_query
|
12
|
+
get(:query)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def get_expected
|
18
|
+
get_final_query
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Sqlite
|
2
|
+
class FinalDatasetParser < DatasetsParser
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@fields = {
|
6
|
+
required: [:type, :final, :expected],
|
7
|
+
optional: [:seed]
|
8
|
+
}
|
9
|
+
@alias = {
|
10
|
+
query: :final
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def show_query?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_final_query
|
19
|
+
has?(:final) ? get(:final) : get(:query)
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def process_alias(keys)
|
25
|
+
keys.map { |item| @alias.include?(item) ? @alias[item] : item }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/sqlite_runner.rb
CHANGED
@@ -16,12 +16,11 @@ 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/
|
20
|
-
require_relative './parsers/
|
21
|
-
require_relative './parsers/
|
22
|
-
require_relative './parsers/
|
23
|
-
require_relative './parsers/
|
24
|
-
require_relative './parsers/invalid_test_parser'
|
19
|
+
require_relative './parsers/base_parser'
|
20
|
+
require_relative './parsers/query_parser'
|
21
|
+
require_relative './parsers/display_parser'
|
22
|
+
require_relative './parsers/datasets_parser'
|
23
|
+
require_relative './parsers/final_dataset_parser'
|
25
24
|
require_relative './helpers'
|
26
25
|
require_relative './test_hook'
|
27
26
|
require_relative './validation_hook'
|
data/lib/test_hook.rb
CHANGED
@@ -8,11 +8,6 @@ class SqliteTestHook < Mumukit::Templates::FileHook
|
|
8
8
|
isolated
|
9
9
|
include Sqlite::TestHelper
|
10
10
|
|
11
|
-
def initialize(config = nil)
|
12
|
-
super(config)
|
13
|
-
set_test_parsers_hash
|
14
|
-
end
|
15
|
-
|
16
11
|
def tempfile_extension
|
17
12
|
'.json'
|
18
13
|
end
|
@@ -23,12 +18,12 @@ class SqliteTestHook < Mumukit::Templates::FileHook
|
|
23
18
|
|
24
19
|
# Transform Mumuki Request into Docker file style
|
25
20
|
def compile_file_content(request)
|
26
|
-
|
27
|
-
|
21
|
+
parse_tests request.test
|
22
|
+
student_code = parse_student_code "#{request.content&.strip}#{get_final_query}"
|
28
23
|
{
|
29
24
|
init: "#{request.extra&.strip}",
|
30
|
-
student:
|
31
|
-
tests:
|
25
|
+
student: student_code,
|
26
|
+
tests: get_tests
|
32
27
|
}.to_json
|
33
28
|
end
|
34
29
|
|
@@ -52,7 +47,7 @@ class SqliteTestHook < Mumukit::Templates::FileHook
|
|
52
47
|
student = output['student']
|
53
48
|
expected = output['expected']
|
54
49
|
expected.map!.with_index do |expect, i|
|
55
|
-
@tests[i].
|
50
|
+
@tests[i].choose_solution expect
|
56
51
|
end
|
57
52
|
diff(expected, student)
|
58
53
|
end
|
@@ -60,7 +55,7 @@ class SqliteTestHook < Mumukit::Templates::FileHook
|
|
60
55
|
# Make diff between expected and student dataset result and mark each line one according comparision
|
61
56
|
def diff(expected, student)
|
62
57
|
zipped = expected.zip(student).map do |expected_i, student_i|
|
63
|
-
diff = Diffy::SplitDiff.new
|
58
|
+
diff = Diffy::SplitDiff.new expected_i << "\n", student_i << "\n"
|
64
59
|
choose_left_right(diff, expected_i, student_i).map { |e| post_process_diff e }
|
65
60
|
end
|
66
61
|
zipped.transpose.map { |dataset| post_process_datasets dataset }
|
@@ -72,33 +67,53 @@ class SqliteTestHook < Mumukit::Templates::FileHook
|
|
72
67
|
[expected, student]
|
73
68
|
end
|
74
69
|
|
70
|
+
# split lines grouping by diff mark & data content
|
71
|
+
# then append mark as dataset column & re join
|
75
72
|
def post_process_diff(data)
|
76
|
-
data.scan(/^(\s|-|\+)(.+)/)
|
77
|
-
.map { |mark, content| mark
|
73
|
+
data.scan(/^(\s|-|\+)*(.+)/)
|
74
|
+
.map { |mark, content| "#{proper_mark(mark)}#{content}" }
|
78
75
|
.join("\n")
|
79
76
|
end
|
80
77
|
|
78
|
+
def proper_mark(mark)
|
79
|
+
mark = mark.to_s
|
80
|
+
"#{mark}|" unless mark.blank?
|
81
|
+
end
|
82
|
+
|
81
83
|
# Transforms array datasets into hash with :id & :rows
|
82
84
|
def post_process_datasets(datasets)
|
83
85
|
datasets.map.with_index do |dataset, i|
|
84
86
|
{
|
85
87
|
id: i + 1,
|
86
|
-
dataset: Sqlite::Dataset.new(dataset)
|
88
|
+
dataset: Sqlite::Dataset.new(dataset),
|
89
|
+
table_name: @tests[i].table_name,
|
90
|
+
show_query: @tests[i].show_query?,
|
91
|
+
query: @tests[i].get_final_query
|
87
92
|
}
|
88
93
|
end
|
89
94
|
end
|
90
95
|
|
96
|
+
def parse_student_code(code)
|
97
|
+
code = code&.strip
|
98
|
+
fail! 'message.failure.semicolon_ending' unless code&.end_with? ';'
|
99
|
+
code
|
100
|
+
end
|
101
|
+
|
91
102
|
# This method receives a list of test cases and transforms each one according it parser
|
92
103
|
def parse_tests(tests)
|
93
|
-
@tests =
|
94
|
-
|
104
|
+
@tests = collect_tests(tests).map do |test|
|
105
|
+
parser = parsers[test.type.to_sym].new
|
106
|
+
parser.parse_test test
|
107
|
+
parser
|
95
108
|
end
|
96
|
-
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_tests
|
112
|
+
@tests.map(&:test_result)
|
97
113
|
end
|
98
114
|
|
99
115
|
def get_final_query
|
100
|
-
|
101
|
-
tests.empty? ? '' : tests.first.get_final
|
116
|
+
@tests.map{ |t| t.get_final_query.to_s }.reject(&:empty?).join
|
102
117
|
end
|
103
118
|
|
104
119
|
# Initialize Metatest Framework with Checker & Runner
|
data/lib/validation_hook.rb
CHANGED
@@ -2,30 +2,31 @@ class SqliteValidationHook < Mumukit::Hook
|
|
2
2
|
|
3
3
|
include Sqlite::TestHelper
|
4
4
|
|
5
|
-
def initialize(config = nil)
|
6
|
-
super(config)
|
7
|
-
set_test_parsers_hash
|
8
|
-
end
|
9
|
-
|
10
5
|
def validate!(request)
|
11
6
|
lint_tests request.test
|
12
7
|
types_tests request.test
|
8
|
+
fields_of_test_types request.test
|
13
9
|
end
|
14
10
|
|
15
11
|
def lint_tests(tests)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
raise Mumukit::RequestValidationError, I18n.t('message.failure.tests.lint')
|
20
|
-
end
|
12
|
+
YAML.load tests
|
13
|
+
rescue
|
14
|
+
fail! 'message.failure.tests.lint'
|
21
15
|
end
|
22
16
|
|
23
17
|
def types_tests(tests)
|
24
|
-
# Assumes
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
# Assumes pass lint_tests
|
19
|
+
collect_tests(tests).each do |test|
|
20
|
+
fail! 'message.failure.tests.type' if test.type.blank?
|
21
|
+
fail!('message.failure.tests.types', type: test.type) unless parsers.has_key? test.type.to_sym
|
28
22
|
end
|
29
23
|
end
|
30
24
|
|
25
|
+
def fields_of_test_types(tests)
|
26
|
+
# Assumes pass types_tests
|
27
|
+
collect_tests(tests).each do |test|
|
28
|
+
parser = parsers[test.type.to_sym].new
|
29
|
+
fail! "message.failure.tests.fields.#{test.type}" unless parser.test_has_valid_fields? test
|
30
|
+
end
|
31
|
+
end
|
31
32
|
end
|
data/lib/version_hook.rb
CHANGED
@@ -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
|
63
|
-
|
64
|
-
|
65
|
-
<
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
-
|
71
|
-
</
|
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
|
89
|
-
|
90
|
-
|
91
|
-
<
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
97
|
-
</
|
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
|
-
|
25
|
-
<
|
26
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
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.
|
4
|
+
version: 3.3.3
|
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:
|
11
|
+
date: 2021-11-23 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: '
|
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: '
|
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
|
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
|
166
|
+
version: '3.1'
|
167
167
|
description:
|
168
168
|
email:
|
169
169
|
- leandro.jdl@gmail.com
|
@@ -177,15 +177,15 @@ 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
|
183
|
-
- lib/parsers/
|
184
|
-
- lib/parsers/
|
185
|
-
- lib/parsers/
|
186
|
-
- lib/parsers/
|
187
|
-
- lib/parsers/
|
188
|
-
- lib/parsers/query_test_parser.rb
|
184
|
+
- lib/parsers/base_parser.rb
|
185
|
+
- lib/parsers/datasets_parser.rb
|
186
|
+
- lib/parsers/display_parser.rb
|
187
|
+
- lib/parsers/final_dataset_parser.rb
|
188
|
+
- lib/parsers/query_parser.rb
|
189
189
|
- lib/sqlite_runner.rb
|
190
190
|
- lib/test_hook.rb
|
191
191
|
- lib/validation_hook.rb
|
@@ -211,8 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
211
211
|
- !ruby/object:Gem::Version
|
212
212
|
version: '0'
|
213
213
|
requirements: []
|
214
|
-
|
215
|
-
rubygems_version: 2.7.3
|
214
|
+
rubygems_version: 3.0.3
|
216
215
|
signing_key:
|
217
216
|
specification_version: 4
|
218
217
|
summary: SQLite Runner for Mumuki
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Sqlite
|
2
|
-
module CommonTestParser
|
3
|
-
|
4
|
-
COMMENT = '-- NONE'
|
5
|
-
attr_reader :result, :final
|
6
|
-
required :parse, 'You need to implement parse method when use CommonTestParse mixin!'
|
7
|
-
|
8
|
-
def initialize(test)
|
9
|
-
@test = test
|
10
|
-
@result = parse test
|
11
|
-
end
|
12
|
-
|
13
|
-
def choose(solution)
|
14
|
-
solution
|
15
|
-
end
|
16
|
-
|
17
|
-
def has?(key)
|
18
|
-
!@test[key.to_sym].blank?
|
19
|
-
end
|
20
|
-
|
21
|
-
def get(key)
|
22
|
-
@test[key.to_sym]
|
23
|
-
end
|
24
|
-
|
25
|
-
def has_final?
|
26
|
-
# Only FinalDataset should have final query
|
27
|
-
false
|
28
|
-
end
|
29
|
-
|
30
|
-
def get_final
|
31
|
-
''
|
32
|
-
end
|
33
|
-
|
34
|
-
protected
|
35
|
-
|
36
|
-
def final_parse(test, override = {})
|
37
|
-
seed = test[:seed].blank? ? '' : test[:seed].strip
|
38
|
-
{
|
39
|
-
seed: override[:seed] || seed,
|
40
|
-
expected: override[:expected] || test[:expected].strip
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Sqlite
|
2
|
-
class DatasetTestParser
|
3
|
-
|
4
|
-
include Sqlite::CommonTestParser
|
5
|
-
|
6
|
-
# test = {
|
7
|
-
# type: dataset,
|
8
|
-
# seed: INSERT INTO ...,
|
9
|
-
# expected: |
|
10
|
-
# id|field
|
11
|
-
# 1|row 1
|
12
|
-
# ...
|
13
|
-
# }
|
14
|
-
#
|
15
|
-
# return {
|
16
|
-
# seed: INSERT INTO ...,
|
17
|
-
# expected: -- NONE
|
18
|
-
# }
|
19
|
-
def parse(test)
|
20
|
-
@solutions = test[:expected].to_s.split("\n").map(&:strip).join("\n")
|
21
|
-
final_parse test, {expected: '-- NONE'}
|
22
|
-
end
|
23
|
-
|
24
|
-
def choose(_solution)
|
25
|
-
@solutions
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Sqlite
|
2
|
-
class DisplayTestParser
|
3
|
-
include Sqlite::CommonTestParser
|
4
|
-
|
5
|
-
def has_final?
|
6
|
-
has?(:query)
|
7
|
-
end
|
8
|
-
|
9
|
-
def get_final
|
10
|
-
# Assume has_final? is true
|
11
|
-
get(:query)
|
12
|
-
end
|
13
|
-
|
14
|
-
def parse(test)
|
15
|
-
final_parse test, { expected: get_final }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Sqlite
|
2
|
-
class QueryTestParser
|
3
|
-
|
4
|
-
include Sqlite::CommonTestParser
|
5
|
-
|
6
|
-
# test = {
|
7
|
-
# type: query,
|
8
|
-
# seed: INSERT INTO ...,
|
9
|
-
# expected: SELECT * FROM ...
|
10
|
-
# }
|
11
|
-
#
|
12
|
-
# return {
|
13
|
-
# seed: INSERT INTO ...,
|
14
|
-
# expected: SELECT * FROM ...
|
15
|
-
# }
|
16
|
-
def parse(test)
|
17
|
-
final_parse test
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|