mumuki-sqlite-runner 3.2.0 → 3.3.0
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/helpers.rb +7 -8
- data/lib/locales/en.yml +6 -0
- data/lib/locales/es.yml +6 -0
- data/lib/parsers/datasets_parser.rb +33 -0
- data/lib/parsers/display_parser.rb +21 -0
- data/lib/parsers/final_dataset_parser.rb +25 -0
- data/lib/parsers/general_parser.rb +54 -0
- data/lib/parsers/query_parser.rb +17 -0
- data/lib/sqlite_runner.rb +5 -6
- data/lib/test_hook.rb +13 -15
- data/lib/validation_hook.rb +19 -14
- data/lib/version_hook.rb +1 -1
- metadata +8 -9
- 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: 3734b0af25cc1a8f563c7bfda8e13a7891f78421fbcda0710553bc3c5140ee8e
|
4
|
+
data.tar.gz: 78b63bfb30f4f4ef26742db5e5b1f98deb80a9b89ff64d1eeddc2b0111b7ceb9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb05abd4833c0f3f7ab3a3d6125bbbfd6a1fceea140b9dead9be60a37c4030b562a2c0548614854b0afc1a3f4e2c4db9b42cca954fa8e81c48de5f6c73fa354b
|
7
|
+
data.tar.gz: 30cd885678391688ff8fe2b0d3cea9a34cc51a4bf31d5bae8eee956102a7986b2f646f8db194ac4ef00bf3d883ded8418f77e4eaa4c2ca1749cdfac06fc52c82
|
data/lib/helpers.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
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)
|
data/lib/locales/en.yml
CHANGED
@@ -9,4 +9,10 @@ en:
|
|
9
9
|
query: 'Queries do not match'
|
10
10
|
tests:
|
11
11
|
lint: "Invalid tests, It should be a valid YAML format. Try with this validator http://www.yamllint.com/"
|
12
|
+
type: "You need to declare field type:"
|
12
13
|
types: "Unsupported test type '%{type}'. Use one of these: datasets, query, display, final_dataset"
|
14
|
+
fields:
|
15
|
+
query: "For type:query you should use ONLY these fields: type (required), seed (optional), expected (required)"
|
16
|
+
datasets: "For type:datasets you should use ONLY these fields: type (required), seed (optional), expected (required)"
|
17
|
+
final_dataset: "For type:final_dataset you should use ONLY these fields: type (required), seed (optional), final (required), expected (required)"
|
18
|
+
display: "For type:display you should use ONLY these fields: type (required), seed (optional), query (required)"
|
data/lib/locales/es.yml
CHANGED
@@ -9,4 +9,10 @@ es:
|
|
9
9
|
query: 'Las consultas no coinciden'
|
10
10
|
tests:
|
11
11
|
lint: "¡Tests inválidos! No tienen el formato YAML correcto. Podés probar en este validador http://www.yamllint.com/"
|
12
|
+
type: "Tenés que declarar el campo type:"
|
12
13
|
types: "El test type '%{type}' no está soportado. Tenés que usar uno de éstos: datasets, query, display, final_dataset"
|
14
|
+
fields:
|
15
|
+
query: "Para el type:query deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), expected (requerido)"
|
16
|
+
datasets: "Para el type:datasets deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), expected (requerido)"
|
17
|
+
final_dataset: "Para el type:final_dataset, deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), final (requerido), expected (requerido)"
|
18
|
+
display: "Para el type:display deberías usar ÚNICAMENTE estos campos: type (requerido), seed (opcional), query (requerido)"
|
@@ -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,25 @@
|
|
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 get_final_query
|
15
|
+
has?(:final) ? get(:final) : get(:query)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def process_alias(keys)
|
21
|
+
keys.map { |item| @alias.include?(item) ? @alias[item] : item }
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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
|
+
protected
|
30
|
+
|
31
|
+
def transform_test
|
32
|
+
{
|
33
|
+
seed: get_seed,
|
34
|
+
expected: get_expected
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def has?(key)
|
39
|
+
!@test[key.to_sym].blank?
|
40
|
+
end
|
41
|
+
|
42
|
+
def get(key)
|
43
|
+
@test[key.to_sym]
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_seed
|
47
|
+
has?(:seed) ? get(:seed).strip : ''
|
48
|
+
end
|
49
|
+
|
50
|
+
def process_alias(keys)
|
51
|
+
keys
|
52
|
+
end
|
53
|
+
end
|
54
|
+
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/general_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,11 @@ 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
|
-
final = get_final_query
|
21
|
+
parse_tests request.test
|
28
22
|
{
|
29
23
|
init: "#{request.extra&.strip}",
|
30
|
-
student: "#{request.content&.strip}#{
|
31
|
-
tests:
|
24
|
+
student: "#{request.content&.strip}#{get_final_query}",
|
25
|
+
tests: get_tests
|
32
26
|
}.to_json
|
33
27
|
end
|
34
28
|
|
@@ -52,7 +46,7 @@ class SqliteTestHook < Mumukit::Templates::FileHook
|
|
52
46
|
student = output['student']
|
53
47
|
expected = output['expected']
|
54
48
|
expected.map!.with_index do |expect, i|
|
55
|
-
@tests[i].
|
49
|
+
@tests[i].choose_solution expect
|
56
50
|
end
|
57
51
|
diff(expected, student)
|
58
52
|
end
|
@@ -90,15 +84,19 @@ class SqliteTestHook < Mumukit::Templates::FileHook
|
|
90
84
|
|
91
85
|
# This method receives a list of test cases and transforms each one according it parser
|
92
86
|
def parse_tests(tests)
|
93
|
-
@tests =
|
94
|
-
|
87
|
+
@tests = collect_tests(tests).map do |test|
|
88
|
+
parser = parsers[test.type.to_sym].new
|
89
|
+
parser.parse_test test
|
90
|
+
parser
|
95
91
|
end
|
96
|
-
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_tests
|
95
|
+
@tests.map(&:test_result)
|
97
96
|
end
|
98
97
|
|
99
98
|
def get_final_query
|
100
|
-
|
101
|
-
tests.empty? ? '' : tests.first.get_final
|
99
|
+
@tests.map{ |t| t.get_final_query.to_s }.reject(&:empty?).join
|
102
100
|
end
|
103
101
|
|
104
102
|
# Initialize Metatest Framework with Checker & Runner
|
data/lib/validation_hook.rb
CHANGED
@@ -2,30 +2,35 @@ 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
|
32
|
+
|
33
|
+
def fail!(*args)
|
34
|
+
raise Mumukit::RequestValidationError, I18n.t(*args)
|
35
|
+
end
|
31
36
|
end
|
data/lib/version_hook.rb
CHANGED
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.0
|
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: 2018-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mumukit
|
@@ -180,12 +180,11 @@ files:
|
|
180
180
|
- lib/locales/es.yml
|
181
181
|
- lib/metadata_hook.rb
|
182
182
|
- 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
|
183
|
+
- lib/parsers/datasets_parser.rb
|
184
|
+
- lib/parsers/display_parser.rb
|
185
|
+
- lib/parsers/final_dataset_parser.rb
|
186
|
+
- lib/parsers/general_parser.rb
|
187
|
+
- lib/parsers/query_parser.rb
|
189
188
|
- lib/sqlite_runner.rb
|
190
189
|
- lib/test_hook.rb
|
191
190
|
- lib/validation_hook.rb
|
@@ -212,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
212
211
|
version: '0'
|
213
212
|
requirements: []
|
214
213
|
rubyforge_project:
|
215
|
-
rubygems_version: 2.7.
|
214
|
+
rubygems_version: 2.7.4
|
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
|