mumukit 2.4.0 → 2.17.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 +5 -5
- data/lib/locales/en.yml +11 -0
- data/lib/locales/es.yml +11 -0
- data/lib/mumukit/compilation_error.rb +4 -0
- data/lib/mumukit/cookie.rb +19 -0
- data/lib/mumukit/defaults/default_try_hook.rb +9 -0
- data/lib/mumukit/defaults/default_version_hook.rb +3 -0
- data/lib/mumukit/defaults.rb +2 -0
- data/lib/mumukit/explainer.rb +23 -0
- data/lib/mumukit/hook.rb +7 -0
- data/lib/mumukit/isolated_environment.rb +24 -12
- data/lib/mumukit/metatest/checker.rb +6 -6
- data/lib/mumukit/metatest/interactive_checker.rb +59 -0
- data/lib/mumukit/metatest.rb +1 -0
- data/lib/mumukit/runner.rb +18 -0
- data/lib/mumukit/runtime/info.rb +2 -1
- data/lib/mumukit/runtime/runtime.rb +4 -2
- data/lib/mumukit/runtime/symbol.rb +2 -2
- data/lib/mumukit/server/app.rb +4 -0
- data/lib/mumukit/server/response_builder.rb +4 -0
- data/lib/mumukit/server/test_pipeline.rb +30 -0
- data/lib/mumukit/server/test_server.rb +27 -36
- data/lib/mumukit/server.rb +1 -0
- data/lib/mumukit/templates/file_hook.rb +33 -3
- data/lib/mumukit/templates/mulang_expectations_hook.rb +62 -20
- data/lib/mumukit/templates/try_hook.rb +17 -0
- data/lib/mumukit/templates/with_cookie.rb +10 -0
- data/lib/mumukit/templates/with_line_number_offset.rb +19 -0
- data/lib/mumukit/templates/with_mashup_file_content.rb +5 -1
- data/lib/mumukit/templates/with_metatest.rb +14 -0
- data/lib/mumukit/templates/with_metatest_results.rb +31 -0
- data/lib/mumukit/templates/with_structured_results.rb +13 -2
- data/lib/mumukit/templates.rb +5 -0
- data/lib/mumukit/version.rb +1 -1
- data/lib/mumukit/with_tempfile.rb +3 -0
- data/lib/mumukit.rb +6 -10
- metadata +76 -11
- data/bin/mulang +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b678748b9bbd865a42951a22eb71244968362faf551452fdfe4d0a9f14889fda
|
|
4
|
+
data.tar.gz: 42ea663c41b564d65222f11d7baa5b7447a2e49b053eb8579b4ec2d8ad814268
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bbb8f3d2905dc3b02b600efb96609bbfb888410228822d40ad55977e59aee51683d1842afb8faa5816b3c76a846639bd4de364f707bc0600d4817c8184b6f785
|
|
7
|
+
data.tar.gz: 0cfadb4c1dc8c55e3ed8b903c0d3d05c2217f56d39845bca17fcc97ac6888b8d5bfa7ca2c48f87f714849ed52a86302eb2893d3168b64c553d915bb975331ba5
|
data/lib/locales/en.yml
CHANGED
|
@@ -2,3 +2,14 @@ en:
|
|
|
2
2
|
mumukit:
|
|
3
3
|
memory_exceeded: Memory limit exceeded. Is your program trying to allocate to much memory?
|
|
4
4
|
time_exceeded: Execution time limit of %{limit}s exceeded. Is your program performing an infinite loop or recursion?
|
|
5
|
+
masked_tempfile_basename: solution
|
|
6
|
+
interactive:
|
|
7
|
+
check_last_query_equals: "query should be '%{expected}' but was '%{actual}'"
|
|
8
|
+
check_last_query_fails: "query should fail but it passed"
|
|
9
|
+
check_last_query_matches: "query does not match regex %{regex}"
|
|
10
|
+
check_last_query_outputs: "query output should be '%{expected}' but was '%{actual}'"
|
|
11
|
+
check_last_query_passes: "query should pass but it failed"
|
|
12
|
+
check_query_fails: "query '%{query}' should fail but it passed"
|
|
13
|
+
check_query_outputs: "query '%{query}' output should be '%{expected}' but was '%{actual}'"
|
|
14
|
+
check_query_passes: "query '%{query}' should pass but it failed"
|
|
15
|
+
goal_passed: "goal was met successfully"
|
data/lib/locales/es.yml
CHANGED
|
@@ -2,3 +2,14 @@ es:
|
|
|
2
2
|
mumukit:
|
|
3
3
|
memory_exceeded: Limite de memoria excedido. ¿Tu programa está alocando demasiada memoria?
|
|
4
4
|
time_exceeded: Limite de tiempo de ejecución de %{limit}s excedido. ¿Tu programa tiene recursión o bucle infinito?
|
|
5
|
+
masked_tempfile_basename: solucion
|
|
6
|
+
interactive:
|
|
7
|
+
check_last_query_equals: "La consulta debería ser '%{expected}' pero fue '%{actual}'"
|
|
8
|
+
check_last_query_fails: "La consulta debería fallar pero pasó"
|
|
9
|
+
check_last_query_matches: "La consulta no cumple con la expresión regular %{regex}"
|
|
10
|
+
check_last_query_outputs: "La consulta debería devolver '%{expected}' pero devolvió '%{actual}'"
|
|
11
|
+
check_last_query_passes: "La consulta debería pasar pero falló"
|
|
12
|
+
check_query_fails: "La consulta '%{query}' debería fallar pero pasó"
|
|
13
|
+
check_query_outputs: "La consulta '%{query}' debería devolver '%{expected}' pero devolvió '%{actual}'"
|
|
14
|
+
check_query_passes: "La consulta '%{query}' debería pasar pero falló"
|
|
15
|
+
goal_passed: "El objetivo se cumplió exitosamente"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Mumukit::Cookie
|
|
2
|
+
attr_accessor :statements
|
|
3
|
+
|
|
4
|
+
def initialize(statements)
|
|
5
|
+
@statements = statements || []
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def code
|
|
9
|
+
"#{statements_code}\n#{stdout_separator_code}\n"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def trim(output)
|
|
13
|
+
output.split("#{stdout_separator}\n")[1]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def stdout_separator
|
|
17
|
+
'!!!!MUMUKI-COOKIE-STDOUT-SEPARATOR-END!!!!'
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/mumukit/defaults.rb
CHANGED
|
@@ -3,9 +3,11 @@ module Mumukit
|
|
|
3
3
|
end
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
+
require_relative './defaults/default_version_hook'
|
|
6
7
|
require_relative './defaults/default_expectations_hook'
|
|
7
8
|
require_relative './defaults/default_query_hook'
|
|
8
9
|
require_relative './defaults/default_feedback_hook'
|
|
9
10
|
require_relative './defaults/default_validation_hook'
|
|
10
11
|
require_relative './defaults/default_test_hook'
|
|
12
|
+
require_relative './defaults/default_try_hook'
|
|
11
13
|
require_relative './defaults/default_metadata_hook'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Mumukit::Explainer
|
|
2
|
+
def explain(content, test_results)
|
|
3
|
+
explain_methods
|
|
4
|
+
.map { |selector, key| eval_explain(selector, key, content, test_results) }
|
|
5
|
+
.compact
|
|
6
|
+
.map { |explain| I18n.t(explain[:key], explain[:binding]) }
|
|
7
|
+
.map { |it| "* #{it}" }
|
|
8
|
+
.join("\n")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def eval_explain(selector, key, content, test_results)
|
|
12
|
+
send(selector, content, test_results).try do |it|
|
|
13
|
+
{key: key, binding: it}
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def explain_methods
|
|
18
|
+
self.class
|
|
19
|
+
.instance_methods(false)
|
|
20
|
+
.flat_map { |it| it.to_s.captures(/explain_(.*)/).map { [it, $1] } }
|
|
21
|
+
.compact
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/mumukit/hook.rb
CHANGED
|
@@ -27,4 +27,11 @@ class Mumukit::Hook
|
|
|
27
27
|
def should_forward_to_config?(args, name)
|
|
28
28
|
args.length == 0 && !block_given? && @config[name]
|
|
29
29
|
end
|
|
30
|
+
|
|
31
|
+
def self.stateful_through(cookie_clazz)
|
|
32
|
+
include Mumukit::Templates::WithCookie
|
|
33
|
+
define_method :cookie_class do
|
|
34
|
+
cookie_clazz
|
|
35
|
+
end
|
|
36
|
+
end
|
|
30
37
|
end
|
|
@@ -16,21 +16,22 @@ module Mumukit
|
|
|
16
16
|
|
|
17
17
|
command = yield(*filenames).split
|
|
18
18
|
|
|
19
|
+
configure_container! command, binds, volumes
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def configure_container!(command, binds, volumes)
|
|
19
23
|
self.container = Docker::Container.create(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
'Image' => Mumukit.config.docker_image,
|
|
25
|
+
'Cmd' => command,
|
|
26
|
+
'NetworkDisabled' => true,
|
|
27
|
+
'HostConfig' => {
|
|
28
|
+
'Binds' => binds},
|
|
29
|
+
'Volumes' => volumes)
|
|
26
30
|
end
|
|
27
31
|
|
|
28
32
|
def run!
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
exit = container.json['State']['ExitCode']
|
|
33
|
-
out = container.streaming_logs(stdout: true, stderr: true)
|
|
33
|
+
run_container!
|
|
34
|
+
exit, out = fetch_container_state!
|
|
34
35
|
|
|
35
36
|
if exit == 0
|
|
36
37
|
[out, :passed]
|
|
@@ -41,6 +42,17 @@ module Mumukit
|
|
|
41
42
|
[I18n.t('mumukit.time_exceeded', limit: Mumukit.config.command_time_limit), :aborted]
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
def run_container!
|
|
46
|
+
container.start
|
|
47
|
+
container.wait(Mumukit.config.command_time_limit)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def fetch_container_state!
|
|
51
|
+
exit = container.json['State']['ExitCode']
|
|
52
|
+
out = container.streaming_logs(stdout: true, stderr: true)
|
|
53
|
+
[exit, out]
|
|
54
|
+
end
|
|
55
|
+
|
|
44
56
|
def destroy!
|
|
45
57
|
if container
|
|
46
58
|
container.stop
|
|
@@ -48,4 +60,4 @@ module Mumukit
|
|
|
48
60
|
end
|
|
49
61
|
end
|
|
50
62
|
end
|
|
51
|
-
end
|
|
63
|
+
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
module Mumukit::Metatest
|
|
2
2
|
class Checker
|
|
3
|
-
def check(
|
|
4
|
-
example[:postconditions].each { |key, arg| check_assertion key,
|
|
5
|
-
[example[:name], :passed, render_success_output(
|
|
3
|
+
def check(result, example)
|
|
4
|
+
example[:postconditions].each { |key, arg| check_assertion key, result, arg, example }
|
|
5
|
+
[example[:name], :passed, render_success_output(result)]
|
|
6
6
|
rescue => e
|
|
7
|
-
[example[:name], :failed, render_error_output(
|
|
7
|
+
[example[:name], :failed, render_error_output(result, e.message)]
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def render_success_output(value)
|
|
@@ -15,8 +15,8 @@ module Mumukit::Metatest
|
|
|
15
15
|
error
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def check_assertion(key,
|
|
19
|
-
send "check_#{key}",
|
|
18
|
+
def check_assertion(key, result, arg, example)
|
|
19
|
+
send "check_#{key}", result, arg
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def fail(message)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Mumukit::Metatest
|
|
2
|
+
class InteractiveChecker < Checker
|
|
3
|
+
|
|
4
|
+
def initialize(request)
|
|
5
|
+
@request = request
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def check_last_query_equals(_result, goal)
|
|
9
|
+
expected = goal[:query]
|
|
10
|
+
actual = @request.query
|
|
11
|
+
fail_t :check_last_query_equals, expected: expected, actual: actual unless expected == actual
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def check_last_query_matches(_result, goal)
|
|
15
|
+
regex = goal[:regex]
|
|
16
|
+
fail_t :check_last_query_matches, regex: regex.inspect unless regex.matches? @request.query
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def check_last_query_fails(result, _goal)
|
|
20
|
+
fail_t :check_last_query_fails unless result[:query][:status] == :failed
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def check_last_query_outputs(result, goal)
|
|
24
|
+
expected = goal.with_indifferent_access[:output]
|
|
25
|
+
actual = result[:query][:result]
|
|
26
|
+
fail_t :check_last_query_outputs, expected: expected, actual: actual unless expected == actual
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def check_last_query_passes(result, _goal)
|
|
30
|
+
fail_t :check_last_query_passes unless result[:query][:status] == :passed
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def check_query_passes(result, goal)
|
|
34
|
+
fail_t :check_query_passes, query: goal.with_indifferent_access[:query] unless result[:status] == :passed
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def check_query_fails(result, goal)
|
|
38
|
+
fail_t :check_query_fails, query: goal.with_indifferent_access[:query] unless result[:status] == :failed
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def check_query_outputs(result, goal)
|
|
42
|
+
expected = goal.with_indifferent_access[:output]
|
|
43
|
+
actual = result[:goal]
|
|
44
|
+
fail_t :check_query_outputs, query: goal.with_indifferent_access[:query], expected: expected, actual: actual unless expected == actual
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def render_success_output(_value)
|
|
48
|
+
I18n.t locale(:goal_passed)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def fail_t(sym, *args)
|
|
52
|
+
fail I18n.t locale(sym), *args
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def locale(sym)
|
|
56
|
+
'mumukit.interactive.' + sym.to_s
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/mumukit/metatest.rb
CHANGED
data/lib/mumukit/runner.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
class Mumukit::Runner
|
|
2
3
|
attr_reader :name, :runtime
|
|
3
4
|
|
|
@@ -22,6 +23,23 @@ class Mumukit::Runner
|
|
|
22
23
|
name.camelize
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
def directives_pipeline
|
|
27
|
+
@pipeline ||= new_directives_pipeline
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def new_directives_pipeline
|
|
31
|
+
if config.preprocessor_enabled
|
|
32
|
+
Mumukit::Directives::Pipeline.new(
|
|
33
|
+
[Mumukit::Directives::Sections.new,
|
|
34
|
+
Mumukit::Directives::Interpolations.new('test'),
|
|
35
|
+
Mumukit::Directives::Interpolations.new('extra'),
|
|
36
|
+
Mumukit::Directives::Flags.new],
|
|
37
|
+
config.comment_type)
|
|
38
|
+
else
|
|
39
|
+
Mumukit::Directives::NullPipeline
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
25
43
|
def self.default_config
|
|
26
44
|
@default_config
|
|
27
45
|
end
|
data/lib/mumukit/runtime/info.rb
CHANGED
|
@@ -2,7 +2,7 @@ module Mumukit::RuntimeInfo
|
|
|
2
2
|
def info
|
|
3
3
|
{
|
|
4
4
|
name: Mumukit.runner_name,
|
|
5
|
-
version: (
|
|
5
|
+
version: hook_class(:version)::VERSION,
|
|
6
6
|
escualo_base_version: ENV['ESCUALO_BASE_VERSION'],
|
|
7
7
|
escualo_service_version: ENV['ESCUALO_SERVICE_VERSION'],
|
|
8
8
|
mumukit_version: Mumukit::VERSION,
|
|
@@ -10,6 +10,7 @@ module Mumukit::RuntimeInfo
|
|
|
10
10
|
comment_type: Mumukit.config.comment_type,
|
|
11
11
|
features: {
|
|
12
12
|
query: query_hook?,
|
|
13
|
+
try: try_hook?,
|
|
13
14
|
expectations: expectations_hook?,
|
|
14
15
|
feedback: feedback_hook?,
|
|
15
16
|
secure: validation_hook?,
|
|
@@ -7,6 +7,10 @@ class Mumukit::Runtime
|
|
|
7
7
|
@hook_classes = {}
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
def reset!
|
|
11
|
+
@hook_classes = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
def hook_defined?(hook_name)
|
|
11
15
|
hook_name.to_default_mumukit_hook_class rescue raise "Wrong hook #{hook_name}"
|
|
12
16
|
|
|
@@ -21,8 +25,6 @@ class Mumukit::Runtime
|
|
|
21
25
|
hook_class(hook_name).new(@config)
|
|
22
26
|
end
|
|
23
27
|
|
|
24
|
-
private
|
|
25
|
-
|
|
26
28
|
def hook_class(hook_name)
|
|
27
29
|
@hook_classes[hook_name] ||=
|
|
28
30
|
if hook_defined? hook_name
|
|
@@ -8,10 +8,10 @@ class Symbol
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def to_mumukit_hook_class
|
|
11
|
-
|
|
11
|
+
to_mumukit_hook_class_name.constantize
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def to_default_mumukit_hook_class
|
|
15
|
-
|
|
15
|
+
"Mumukit::Defaults::#{to_simple_mumukit_hook_class_name}".constantize
|
|
16
16
|
end
|
|
17
17
|
end
|
data/lib/mumukit/server/app.rb
CHANGED
|
@@ -12,6 +12,10 @@ class Mumukit::Server::ResponseBuilder
|
|
|
12
12
|
@response.merge!(expectationResults: r) if r.present?
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def add_try_results(r)
|
|
16
|
+
@response = unstructured_base_response(r)
|
|
17
|
+
@response.merge!(queryResult: r[2])
|
|
18
|
+
end
|
|
15
19
|
|
|
16
20
|
def add_feedback(f)
|
|
17
21
|
@response.merge!(feedback: f) if f.present?
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class Mumukit::Server::TestPipeline
|
|
2
|
+
def initialize(server, request)
|
|
3
|
+
@server = server
|
|
4
|
+
@request = request
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def evaluate!
|
|
8
|
+
@test_results = @server.run_tests! @request
|
|
9
|
+
@expectation_results = @server.run_expectations!(@request).try do |raw|
|
|
10
|
+
static_errors?(raw) ? [] : raw
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def generate_feedback!
|
|
15
|
+
@feedback = @server.run_feedback! @request,
|
|
16
|
+
struct(test_results: @test_results, expectation_results: @expectation_results)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def response
|
|
20
|
+
builder = Mumukit::Server::ResponseBuilder.new
|
|
21
|
+
builder.add_test_results @test_results
|
|
22
|
+
builder.add_expectation_results @expectation_results
|
|
23
|
+
builder.add_feedback @feedback
|
|
24
|
+
builder.build
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def static_errors?(raw)
|
|
28
|
+
raw.size == 2 && raw[1] == :errored
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -32,19 +32,10 @@ class Mumukit::Server::TestServer
|
|
|
32
32
|
|
|
33
33
|
def test!(request)
|
|
34
34
|
respond_to(request) do |r|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
expectation_results: expectation_results)
|
|
40
|
-
|
|
41
|
-
feedback = run_feedback! r, results
|
|
42
|
-
|
|
43
|
-
Mumukit::Server::ResponseBuilder.build do
|
|
44
|
-
add_test_results(test_results)
|
|
45
|
-
add_expectation_results(expectation_results)
|
|
46
|
-
add_feedback(feedback)
|
|
47
|
-
end
|
|
35
|
+
pipeline = Mumukit::Server::TestPipeline.new self, r
|
|
36
|
+
pipeline.evaluate!
|
|
37
|
+
pipeline.generate_feedback!
|
|
38
|
+
pipeline.response
|
|
48
39
|
end
|
|
49
40
|
end
|
|
50
41
|
|
|
@@ -57,8 +48,13 @@ class Mumukit::Server::TestServer
|
|
|
57
48
|
end
|
|
58
49
|
end
|
|
59
50
|
|
|
60
|
-
def
|
|
61
|
-
|
|
51
|
+
def try!(request)
|
|
52
|
+
respond_to(request) do |r|
|
|
53
|
+
results = run_try!(r)
|
|
54
|
+
Mumukit::Server::ResponseBuilder.build do
|
|
55
|
+
add_try_results(results)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
62
58
|
end
|
|
63
59
|
|
|
64
60
|
def run_tests!(request)
|
|
@@ -68,11 +64,9 @@ class Mumukit::Server::TestServer
|
|
|
68
64
|
end
|
|
69
65
|
|
|
70
66
|
def run_expectations!(request)
|
|
71
|
-
if request.expectations
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
[]
|
|
75
|
-
end
|
|
67
|
+
return [] if request.expectations.nil? || request.content.nil?
|
|
68
|
+
|
|
69
|
+
compile_and_run runtime.expectations_hook, request
|
|
76
70
|
end
|
|
77
71
|
|
|
78
72
|
def run_feedback!(request, results)
|
|
@@ -81,26 +75,23 @@ class Mumukit::Server::TestServer
|
|
|
81
75
|
|
|
82
76
|
private
|
|
83
77
|
|
|
78
|
+
def run_query!(request)
|
|
79
|
+
compile_and_run runtime.query_hook, request
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def run_try!(request)
|
|
83
|
+
compile_and_run runtime.try_hook, request
|
|
84
|
+
end
|
|
85
|
+
|
|
84
86
|
def compile_and_run(hook, request)
|
|
85
|
-
compilation = hook.compile(
|
|
87
|
+
compilation = hook.compile(request)
|
|
86
88
|
hook.run!(compilation)
|
|
89
|
+
rescue Mumukit::CompilationError => e
|
|
90
|
+
[e.message, :errored]
|
|
87
91
|
end
|
|
88
92
|
|
|
89
93
|
def preprocess(request)
|
|
90
|
-
|
|
91
|
-
directives_pipeline.transform(request)
|
|
92
|
-
else
|
|
93
|
-
request
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def directives_pipeline
|
|
98
|
-
@pipeline ||= Mumukit::Directives::Pipeline.new(
|
|
99
|
-
[Mumukit::Directives::Sections.new,
|
|
100
|
-
Mumukit::Directives::Interpolations.new('test'),
|
|
101
|
-
Mumukit::Directives::Interpolations.new('extra'),
|
|
102
|
-
Mumukit::Directives::Flags.new],
|
|
103
|
-
Mumukit.config.comment_type)
|
|
94
|
+
Mumukit.directives_pipeline.transform(request)
|
|
104
95
|
end
|
|
105
96
|
|
|
106
97
|
def validate_request!(request)
|
|
@@ -108,7 +99,7 @@ class Mumukit::Server::TestServer
|
|
|
108
99
|
end
|
|
109
100
|
|
|
110
101
|
def respond_to(request)
|
|
111
|
-
yield request.tap { |r| validate_request! r }
|
|
102
|
+
yield preprocess request.tap { |r| validate_request! r }
|
|
112
103
|
rescue Mumukit::RequestValidationError => e
|
|
113
104
|
{exit: :aborted, out: e.message}
|
|
114
105
|
rescue Exception => e
|
data/lib/mumukit/server.rb
CHANGED
|
@@ -2,17 +2,25 @@ module Mumukit
|
|
|
2
2
|
class Templates::FileHook < Mumukit::Hook
|
|
3
3
|
include Mumukit::WithTempfile
|
|
4
4
|
|
|
5
|
+
attr_accessor :request
|
|
6
|
+
|
|
7
|
+
|
|
5
8
|
def compile(request)
|
|
9
|
+
self.request = request
|
|
6
10
|
write_tempfile! compile_file_content(request)
|
|
7
11
|
end
|
|
8
12
|
|
|
9
13
|
def run!(file)
|
|
10
14
|
result, status = run_file!(file)
|
|
11
|
-
post_process_file(file, result
|
|
15
|
+
post_process_file(file, cleanup_raw_result(result), status)
|
|
12
16
|
ensure
|
|
13
17
|
file.unlink
|
|
14
18
|
end
|
|
15
19
|
|
|
20
|
+
def cleanup_raw_result(result)
|
|
21
|
+
mask_tempfile_references(result.force_encoding('UTF-8'), masked_tempfile_path)
|
|
22
|
+
end
|
|
23
|
+
|
|
16
24
|
def post_process_file(file, result, status)
|
|
17
25
|
[result, status]
|
|
18
26
|
end
|
|
@@ -22,8 +30,29 @@ module Mumukit
|
|
|
22
30
|
|
|
23
31
|
required :run_file!, 'Wrong configuration. You must include an environment mixin'
|
|
24
32
|
|
|
25
|
-
def
|
|
33
|
+
def masked_tempfile_path
|
|
34
|
+
@masked_tempfile_path ||= "#{t 'mumukit.masked_tempfile_basename'}#{tempfile_extension}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.line_number_offset(offset, options={})
|
|
38
|
+
include Mumukit::Templates::WithLineNumberOffset
|
|
39
|
+
|
|
40
|
+
define_method(:line_number_offset) do
|
|
41
|
+
extra_offset = options[:include_extra] && request.extra ? request.extra.lines.length : 0
|
|
42
|
+
offset + extra_offset
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.metatested(value=true)
|
|
47
|
+
if value
|
|
48
|
+
include Mumukit::Templates::WithMetatest
|
|
49
|
+
include Mumukit::Templates::WithMetatestResults
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.structured(value=true, separator: nil)
|
|
26
54
|
if value
|
|
55
|
+
@separator = separator
|
|
27
56
|
include Mumukit::Templates::WithStructuredResults
|
|
28
57
|
end
|
|
29
58
|
end
|
|
@@ -36,8 +65,9 @@ module Mumukit
|
|
|
36
65
|
end
|
|
37
66
|
end
|
|
38
67
|
|
|
39
|
-
def self.mashup(*args)
|
|
68
|
+
def self.mashup(*args, &map_block)
|
|
40
69
|
include Mumukit::Templates::WithMashupFileContent
|
|
70
|
+
define_method(:map_mashup_fields, &map_block) if block_given?
|
|
41
71
|
|
|
42
72
|
args = args.present? ? args : [:extra, :content, :test]
|
|
43
73
|
|
|
@@ -1,32 +1,71 @@
|
|
|
1
|
+
require 'mumukit/inspection'
|
|
2
|
+
require 'mulang'
|
|
3
|
+
|
|
1
4
|
module Mumukit
|
|
2
|
-
class Templates::MulangExpectationsHook < Mumukit::
|
|
3
|
-
|
|
5
|
+
class Templates::MulangExpectationsHook < Mumukit::Hook
|
|
6
|
+
LOGIC_SMELLS = %w(UsesCut UsesFail UsesUnificationOperator HasRedundantReduction)
|
|
7
|
+
FUNCTIONAL_SMELLS = %w(HasRedundantParameter HasRedundantGuards)
|
|
8
|
+
OBJECT_ORIENTED_SMELLS = %w(DoesNullTest ReturnsNull)
|
|
9
|
+
IMPERATIVE_SMELLS = %w(HasRedundantLocalVariableReturn HasAssignmentReturn)
|
|
10
|
+
EXPRESSIVENESS_SMELLS = %w(HasTooShortBindings HasWrongCaseBindings HasMisspelledBindings)
|
|
11
|
+
GENERIC_SMELLS = %w(IsLongCode HasCodeDuplication HasRedundantLambda HasRedundantIf DoesTypeTest HasRedundantBooleanComparison)
|
|
4
12
|
|
|
5
13
|
required :language, 'You have to provide a Mulang-compatible language in order to use this hook'
|
|
6
14
|
|
|
7
|
-
def
|
|
8
|
-
|
|
15
|
+
def compile(request)
|
|
16
|
+
expectations, exceptions = compile_expectations_and_exceptions request
|
|
17
|
+
mulang_code(request).analysis(
|
|
18
|
+
expectations: expectations,
|
|
19
|
+
smellsSet: {
|
|
20
|
+
tag: 'AllSmells',
|
|
21
|
+
exclude: (exceptions + default_smell_exceptions)
|
|
22
|
+
},
|
|
23
|
+
domainLanguage: domain_language)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def run!(analysis)
|
|
27
|
+
parse_response Mulang.analyse(analysis)
|
|
28
|
+
rescue JSON::ParserError
|
|
29
|
+
raise Mumukit::CompilationError, "Can not handle mulang results for analysis #{analysis}"
|
|
9
30
|
end
|
|
10
31
|
|
|
11
|
-
|
|
12
|
-
|
|
32
|
+
|
|
33
|
+
def domain_language
|
|
34
|
+
{
|
|
35
|
+
caseStyle: "CamelCase",
|
|
36
|
+
minimumIdentifierSize: 3,
|
|
37
|
+
jargon: []
|
|
38
|
+
}
|
|
13
39
|
end
|
|
14
40
|
|
|
15
|
-
def
|
|
16
|
-
|
|
41
|
+
def default_smell_exceptions
|
|
42
|
+
[]
|
|
17
43
|
end
|
|
18
44
|
|
|
19
|
-
def
|
|
20
|
-
|
|
45
|
+
def mulang_code(request)
|
|
46
|
+
Mulang::Code.new(mulang_language, compile_content(request[:content]))
|
|
21
47
|
end
|
|
22
48
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
49
|
+
def mulang_language
|
|
50
|
+
language == 'Mulang' ? Mulang::Language::External.new : Mulang::Language::Native.new(language)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def compile_expectations_and_exceptions(request)
|
|
54
|
+
expectations = []
|
|
55
|
+
exceptions = []
|
|
56
|
+
request[:expectations].each do |it|
|
|
57
|
+
fill_expectations_and_excetions it.deep_symbolize_keys, expectations, exceptions
|
|
58
|
+
end
|
|
59
|
+
[expectations, exceptions]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def fill_expectations_and_excetions(expectation, expectations, exceptions)
|
|
63
|
+
inspection = expectation[:inspection]
|
|
64
|
+
if inspection&.start_with? 'Except:'
|
|
65
|
+
exceptions << inspection[7..-1]
|
|
66
|
+
else
|
|
67
|
+
expectations << compile_expectation(expectation)
|
|
68
|
+
end
|
|
30
69
|
end
|
|
31
70
|
|
|
32
71
|
def compile_content(content)
|
|
@@ -34,11 +73,14 @@ module Mumukit
|
|
|
34
73
|
end
|
|
35
74
|
|
|
36
75
|
def compile_expectation(expectation)
|
|
37
|
-
(expectation
|
|
76
|
+
Mumukit::Inspection::Expectation.parse(expectation).as_v2.to_h
|
|
38
77
|
end
|
|
39
78
|
|
|
40
79
|
def parse_response(response)
|
|
41
|
-
response['
|
|
80
|
+
if response['tag'] == 'AnalysisFailed'
|
|
81
|
+
raise Mumukit::CompilationError, response['reason']
|
|
82
|
+
end
|
|
83
|
+
response['expectationResults'].map do |it|
|
|
42
84
|
{result: it['result'],
|
|
43
85
|
expectation: parse_expectation(it['expectation'])}
|
|
44
86
|
end
|
|
@@ -54,4 +96,4 @@ module Mumukit
|
|
|
54
96
|
end
|
|
55
97
|
end
|
|
56
98
|
end
|
|
57
|
-
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Mumukit
|
|
2
|
+
class Templates::TryHook < Templates::FileHook
|
|
3
|
+
def compile(request)
|
|
4
|
+
@goal = {postconditions: [[request.goal.with_indifferent_access[:kind], request.goal]]}
|
|
5
|
+
@checker = Metatest::InteractiveChecker.new request
|
|
6
|
+
super request
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def post_process_file(file, result, status)
|
|
10
|
+
structured_results = to_structured_results(file, result, status)
|
|
11
|
+
check_results = @checker.check structured_results, @goal
|
|
12
|
+
[check_results[2], check_results[1], structured_results[:query]]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
required :to_structured_results
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Mumukit::Templates::WithLineNumberOffset
|
|
2
|
+
def cleanup_raw_result(result)
|
|
3
|
+
super(result).gsub(line_number_reference_regexp) do
|
|
4
|
+
rebuild_line_number_reference correct_line_number($1.to_i)
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def line_number_reference_regexp
|
|
9
|
+
/#{masked_tempfile_path}\:(\d+)/m
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def rebuild_line_number_reference(new_line_number)
|
|
13
|
+
"#{masked_tempfile_path}:#{new_line_number}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def correct_line_number(number)
|
|
17
|
+
number - line_number_offset
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
module Mumukit
|
|
2
2
|
module Templates::WithMashupFileContent
|
|
3
3
|
def compile_file_content(request)
|
|
4
|
-
mashup_fields.map { |field| request.
|
|
4
|
+
map_mashup_fields(*mashup_fields.map { |field| request.public_send field }).join("\n")
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def mashup_fields
|
|
8
8
|
raise 'must define mashup fields'
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
def map_mashup_fields(*fields)
|
|
12
|
+
fields
|
|
13
|
+
end
|
|
10
14
|
end
|
|
11
15
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Mumukit::Templates::WithMetatest
|
|
2
|
+
def metatest
|
|
3
|
+
Mumukit::Metatest::Framework.new checker: metatest_checker,
|
|
4
|
+
runner: metatest_runner
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def metatest_runner
|
|
8
|
+
Mumukit::Metatest::IdentityRunner.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run_metatest!(target, examples)
|
|
12
|
+
metatest.test target, examples
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Mumukit::Templates::WithMetatestResults
|
|
2
|
+
def compile_file_content(request)
|
|
3
|
+
@examples = compile_metatest_examples(request)
|
|
4
|
+
compile_metatest_file_content(request)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def compile_metatest_examples(request)
|
|
8
|
+
YAML.load(request.test).deep_symbolize_keys[:examples]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def post_process_file(file, result, status)
|
|
12
|
+
if status == :passed
|
|
13
|
+
run_metatest! to_metatest_compilation(result), @examples
|
|
14
|
+
else
|
|
15
|
+
post_process_unsuccessful_result(file, result, status)
|
|
16
|
+
end
|
|
17
|
+
rescue JSON::ParserError
|
|
18
|
+
[result, :errored]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def post_process_unsuccessful_result(_file, result, status)
|
|
22
|
+
[result, status]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_metatest_compilation(result)
|
|
26
|
+
JSON.pretty_parse(result).deep_symbolize_keys
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
module Mumukit::Templates::WithStructuredResults
|
|
2
2
|
def post_process_file(file, result, status)
|
|
3
|
+
result = extract_result(result)
|
|
3
4
|
if [:passed, :failed].include? status
|
|
4
5
|
[to_structured_result(result)]
|
|
5
6
|
else
|
|
6
|
-
|
|
7
|
+
post_process_unstructured_result(file, result, status)
|
|
7
8
|
end
|
|
8
9
|
rescue JSON::ParserError
|
|
9
10
|
[result, :errored]
|
|
10
11
|
end
|
|
11
12
|
|
|
13
|
+
def post_process_unstructured_result(_file, result, status)
|
|
14
|
+
[result, status]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def extract_result(result)
|
|
18
|
+
separator = self.class.instance_variable_get :@separator
|
|
19
|
+
result = result.split(separator).last if separator.present?
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
|
|
12
23
|
def to_structured_result(result)
|
|
13
24
|
JSON.pretty_parse(result)
|
|
14
25
|
end
|
|
15
|
-
end
|
|
26
|
+
end
|
data/lib/mumukit/templates.rb
CHANGED
|
@@ -4,9 +4,14 @@ module Mumukit
|
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
require_relative './templates/file_hook'
|
|
7
|
+
require_relative './templates/try_hook'
|
|
7
8
|
require_relative './templates/with_structured_results'
|
|
9
|
+
require_relative './templates/with_metatest'
|
|
10
|
+
require_relative './templates/with_metatest_results'
|
|
8
11
|
require_relative './templates/with_mashup_file_content'
|
|
9
12
|
require_relative './templates/with_embedded_environment'
|
|
10
13
|
require_relative './templates/with_isolated_environment'
|
|
14
|
+
require_relative './templates/with_line_number_offset'
|
|
11
15
|
require_relative './templates/mulang_expectations_hook'
|
|
12
16
|
require_relative './templates/with_code_smells'
|
|
17
|
+
require_relative './templates/with_cookie'
|
data/lib/mumukit/version.rb
CHANGED
data/lib/mumukit.rb
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
require 'i18n'
|
|
2
|
-
require 'i18n/backend/fallbacks'
|
|
3
1
|
require 'mumukit/core'
|
|
4
2
|
require 'mumukit/directives'
|
|
5
3
|
require 'ostruct'
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
|
|
10
|
-
I18n.load_path += Dir[File.join(pwd, 'locales', '*.yml')]
|
|
11
|
-
|
|
12
|
-
I18n.backend.load_translations
|
|
5
|
+
I18n.load_translations_path File.join(__dir__, 'locales', '*.yml')
|
|
13
6
|
|
|
14
7
|
module Mumukit
|
|
15
8
|
def self.current_runner=(runner)
|
|
@@ -34,14 +27,14 @@ module Mumukit
|
|
|
34
27
|
end
|
|
35
28
|
|
|
36
29
|
class << self
|
|
37
|
-
delegate :prefix, :config, :configure, :runtime, :configure_runtime, to: :current_runner
|
|
30
|
+
delegate :prefix, :config, :configure, :runtime, :configure_runtime, :directives_pipeline, to: :current_runner
|
|
38
31
|
end
|
|
39
32
|
end
|
|
40
33
|
|
|
41
34
|
require_relative 'mumukit/runner'
|
|
42
35
|
|
|
43
36
|
Mumukit.configure_defaults do |config|
|
|
44
|
-
config.limit_script = File.join(
|
|
37
|
+
config.limit_script = File.join(__dir__, '..', 'bin', 'limit')
|
|
45
38
|
config.content_type = :plain
|
|
46
39
|
config.comment_type = Mumukit::Directives::CommentType::Cpp
|
|
47
40
|
config.preprocessor_enabled = true
|
|
@@ -55,6 +48,7 @@ require 'mumukit/content_type'
|
|
|
55
48
|
|
|
56
49
|
require_relative 'mumukit/version'
|
|
57
50
|
require_relative 'mumukit/env'
|
|
51
|
+
require_relative 'mumukit/cookie'
|
|
58
52
|
require_relative 'mumukit/with_tempfile'
|
|
59
53
|
require_relative 'mumukit/with_content_type'
|
|
60
54
|
require_relative 'mumukit/with_command_line'
|
|
@@ -63,6 +57,8 @@ require_relative 'mumukit/runtime'
|
|
|
63
57
|
require_relative 'mumukit/isolated_environment'
|
|
64
58
|
require_relative 'mumukit/templates'
|
|
65
59
|
require_relative 'mumukit/request_validation_error'
|
|
60
|
+
require_relative 'mumukit/compilation_error'
|
|
66
61
|
require_relative 'mumukit/defaults'
|
|
67
62
|
require_relative 'mumukit/metatest'
|
|
63
|
+
require_relative 'mumukit/explainer'
|
|
68
64
|
require_relative 'mumukit/server'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mumukit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.17.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Franco Leonardo Bulgarelli
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-11-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -66,6 +66,20 @@ dependencies:
|
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: simplecov
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
69
83
|
- !ruby/object:Gem::Dependency
|
|
70
84
|
name: sinatra
|
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -151,47 +165,87 @@ dependencies:
|
|
|
151
165
|
- !ruby/object:Gem::Version
|
|
152
166
|
version: '0.46'
|
|
153
167
|
- !ruby/object:Gem::Dependency
|
|
154
|
-
name:
|
|
168
|
+
name: mulang
|
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
|
156
170
|
requirements:
|
|
157
171
|
- - "~>"
|
|
158
172
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '
|
|
173
|
+
version: '3.3'
|
|
160
174
|
type: :runtime
|
|
161
175
|
prerelease: false
|
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
177
|
requirements:
|
|
164
178
|
- - "~>"
|
|
165
179
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '
|
|
180
|
+
version: '3.3'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: mumukit-inspection
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - "~>"
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '3.1'
|
|
188
|
+
type: :runtime
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - "~>"
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '3.1'
|
|
195
|
+
- !ruby/object:Gem::Dependency
|
|
196
|
+
name: mumukit-core
|
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
|
198
|
+
requirements:
|
|
199
|
+
- - ">="
|
|
200
|
+
- !ruby/object:Gem::Version
|
|
201
|
+
version: '0.2'
|
|
202
|
+
- - "<"
|
|
203
|
+
- !ruby/object:Gem::Version
|
|
204
|
+
version: '2'
|
|
205
|
+
type: :runtime
|
|
206
|
+
prerelease: false
|
|
207
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
208
|
+
requirements:
|
|
209
|
+
- - ">="
|
|
210
|
+
- !ruby/object:Gem::Version
|
|
211
|
+
version: '0.2'
|
|
212
|
+
- - "<"
|
|
213
|
+
- !ruby/object:Gem::Version
|
|
214
|
+
version: '2'
|
|
167
215
|
- !ruby/object:Gem::Dependency
|
|
168
216
|
name: mumukit-directives
|
|
169
217
|
requirement: !ruby/object:Gem::Requirement
|
|
170
218
|
requirements:
|
|
171
219
|
- - "~>"
|
|
172
220
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: '0.
|
|
221
|
+
version: '0.3'
|
|
174
222
|
type: :runtime
|
|
175
223
|
prerelease: false
|
|
176
224
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
225
|
requirements:
|
|
178
226
|
- - "~>"
|
|
179
227
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: '0.
|
|
228
|
+
version: '0.3'
|
|
181
229
|
- !ruby/object:Gem::Dependency
|
|
182
230
|
name: mumukit-content-type
|
|
183
231
|
requirement: !ruby/object:Gem::Requirement
|
|
184
232
|
requirements:
|
|
185
|
-
- - "
|
|
233
|
+
- - ">="
|
|
186
234
|
- !ruby/object:Gem::Version
|
|
187
235
|
version: '0.2'
|
|
236
|
+
- - "<"
|
|
237
|
+
- !ruby/object:Gem::Version
|
|
238
|
+
version: '2'
|
|
188
239
|
type: :runtime
|
|
189
240
|
prerelease: false
|
|
190
241
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
242
|
requirements:
|
|
192
|
-
- - "
|
|
243
|
+
- - ">="
|
|
193
244
|
- !ruby/object:Gem::Version
|
|
194
245
|
version: '0.2'
|
|
246
|
+
- - "<"
|
|
247
|
+
- !ruby/object:Gem::Version
|
|
248
|
+
version: '2'
|
|
195
249
|
description: Helpers for building a Mumuki Test Server
|
|
196
250
|
email:
|
|
197
251
|
- flbulgarelli@yahoo.com.ar
|
|
@@ -200,18 +254,22 @@ extensions: []
|
|
|
200
254
|
extra_rdoc_files: []
|
|
201
255
|
files:
|
|
202
256
|
- bin/limit
|
|
203
|
-
- bin/mulang
|
|
204
257
|
- lib/locales/en.yml
|
|
205
258
|
- lib/locales/es.yml
|
|
206
259
|
- lib/mumukit.rb
|
|
260
|
+
- lib/mumukit/compilation_error.rb
|
|
261
|
+
- lib/mumukit/cookie.rb
|
|
207
262
|
- lib/mumukit/defaults.rb
|
|
208
263
|
- lib/mumukit/defaults/default_expectations_hook.rb
|
|
209
264
|
- lib/mumukit/defaults/default_feedback_hook.rb
|
|
210
265
|
- lib/mumukit/defaults/default_metadata_hook.rb
|
|
211
266
|
- lib/mumukit/defaults/default_query_hook.rb
|
|
212
267
|
- lib/mumukit/defaults/default_test_hook.rb
|
|
268
|
+
- lib/mumukit/defaults/default_try_hook.rb
|
|
213
269
|
- lib/mumukit/defaults/default_validation_hook.rb
|
|
270
|
+
- lib/mumukit/defaults/default_version_hook.rb
|
|
214
271
|
- lib/mumukit/env.rb
|
|
272
|
+
- lib/mumukit/explainer.rb
|
|
215
273
|
- lib/mumukit/hook.rb
|
|
216
274
|
- lib/mumukit/isolated_environment.rb
|
|
217
275
|
- lib/mumukit/metatest.rb
|
|
@@ -219,6 +277,7 @@ files:
|
|
|
219
277
|
- lib/mumukit/metatest/errors.rb
|
|
220
278
|
- lib/mumukit/metatest/framework.rb
|
|
221
279
|
- lib/mumukit/metatest/identity_runner.rb
|
|
280
|
+
- lib/mumukit/metatest/interactive_checker.rb
|
|
222
281
|
- lib/mumukit/request_validation_error.rb
|
|
223
282
|
- lib/mumukit/runner.rb
|
|
224
283
|
- lib/mumukit/runtime.rb
|
|
@@ -229,14 +288,20 @@ files:
|
|
|
229
288
|
- lib/mumukit/server.rb
|
|
230
289
|
- lib/mumukit/server/app.rb
|
|
231
290
|
- lib/mumukit/server/response_builder.rb
|
|
291
|
+
- lib/mumukit/server/test_pipeline.rb
|
|
232
292
|
- lib/mumukit/server/test_server.rb
|
|
233
293
|
- lib/mumukit/templates.rb
|
|
234
294
|
- lib/mumukit/templates/file_hook.rb
|
|
235
295
|
- lib/mumukit/templates/mulang_expectations_hook.rb
|
|
296
|
+
- lib/mumukit/templates/try_hook.rb
|
|
236
297
|
- lib/mumukit/templates/with_code_smells.rb
|
|
298
|
+
- lib/mumukit/templates/with_cookie.rb
|
|
237
299
|
- lib/mumukit/templates/with_embedded_environment.rb
|
|
238
300
|
- lib/mumukit/templates/with_isolated_environment.rb
|
|
301
|
+
- lib/mumukit/templates/with_line_number_offset.rb
|
|
239
302
|
- lib/mumukit/templates/with_mashup_file_content.rb
|
|
303
|
+
- lib/mumukit/templates/with_metatest.rb
|
|
304
|
+
- lib/mumukit/templates/with_metatest_results.rb
|
|
240
305
|
- lib/mumukit/templates/with_structured_results.rb
|
|
241
306
|
- lib/mumukit/version.rb
|
|
242
307
|
- lib/mumukit/with_command_line.rb
|
|
@@ -263,7 +328,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
263
328
|
version: '0'
|
|
264
329
|
requirements: []
|
|
265
330
|
rubyforge_project:
|
|
266
|
-
rubygems_version: 2.
|
|
331
|
+
rubygems_version: 2.7.2
|
|
267
332
|
signing_key:
|
|
268
333
|
specification_version: 4
|
|
269
334
|
summary: Mumuki Test Server Development Kit
|
data/bin/mulang
DELETED
|
Binary file
|