mumuki-laboratory 5.10.4 → 5.11.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/app/assets/javascripts/application/codemirror.js +2 -0
- data/app/assets/javascripts/application/free-form.js +30 -0
- data/app/assets/javascripts/application/inputs.js +12 -0
- data/app/assets/javascripts/application/multiple-choice.js +6 -5
- data/app/models/concerns/with_editor.rb +1 -1
- data/app/models/exercise.rb +1 -1
- data/app/views/layouts/exercise_inputs/editors/_free_form.html.erb +4 -0
- data/db/migrate/20181004173216_add_free_form_editor_to_exercises.rb +5 -0
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/dummy/db/schema.rb +2 -1
- data/spec/models/guide_import_spec.rb +14 -0
- data/vendor/assets/javascripts/codemirror-modes/gobstones.js +23 -10
- metadata +8 -5
- data/vendor/assets/javascripts/codemirror-modes/gobstones-autocomplete.js +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 18f020ea8f88054e994d5e652d5ba0da08c502c1e49042d7906293695e396a82
|
|
4
|
+
data.tar.gz: 49f403a38857fe24615f1c4429bc68927a621e9a714eabb5698815436f973466
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5255c69d3d6ce5834f5c58db4d0b0cc451bb52262997673911e6ee54729bc543768ac07650a124874306a921df9b1b4081ff8e87482ef8594a9afb06660561c0
|
|
7
|
+
data.tar.gz: 16ba33bc9c99d07a865a17952aa5f7d4469d4532c5df5025677eaa926226c9aff94cdf3ef5817c007831356cdd124df417f629e2e366254f74d4150ab34e288d
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
mumuki.load(() => {
|
|
2
|
+
function dumpInput(values, element) {
|
|
3
|
+
values[element.attr('name')] = element.val();
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function loadInput(values, element) {
|
|
7
|
+
element.attr('value', values[element.attr('name')]);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function dumpForm(_event) {
|
|
11
|
+
let values = {};
|
|
12
|
+
$('.mu-free-form-input').each(function () {
|
|
13
|
+
dumpInput(values, $(this));
|
|
14
|
+
});
|
|
15
|
+
$('#solution_content').attr('value', JSON.stringify(values));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function loadForm() {
|
|
19
|
+
let json = $('#solution_content').val();
|
|
20
|
+
if (!json) return;
|
|
21
|
+
|
|
22
|
+
let values = JSON.parse(json);
|
|
23
|
+
$('.mu-free-form-input').each(function () {
|
|
24
|
+
loadInput(values, $(this));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
mumuki.onInputsReady('.mu-free-form-input', loadForm);
|
|
29
|
+
$('.mu-free-form-input').change(dumpForm);
|
|
30
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
// Declares a `document.ready` handler that will be
|
|
3
|
+
// activated only when there is at least one element that match
|
|
4
|
+
// the given selector
|
|
5
|
+
mumuki.onInputsReady = (inputsSelector, callback) => {
|
|
6
|
+
$(document).ready((event) => {
|
|
7
|
+
if ($(inputsSelector).length === 0) return;
|
|
8
|
+
|
|
9
|
+
callback(event);
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
})();
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
mumuki.load(
|
|
2
|
-
|
|
1
|
+
mumuki.load(() => {
|
|
2
|
+
function dumpChoices(evt) {
|
|
3
3
|
var indexes = $('.solution-choice:checked').map(function () {
|
|
4
4
|
return $(this).data('index')
|
|
5
5
|
}).get().join(':');
|
|
6
6
|
$('#solution_content').attr('value', indexes);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
mumuki.onInputsReady('.solution-choice', dumpChoices);
|
|
10
|
+
$('.solution-choice').change(dumpChoices);
|
|
10
11
|
});
|
|
@@ -2,7 +2,7 @@ module WithEditor
|
|
|
2
2
|
extend ActiveSupport::Concern
|
|
3
3
|
|
|
4
4
|
included do
|
|
5
|
-
enum editor: [:code, :upload, :text, :single_choice, :multiple_choice, :hidden, :multiple_files, :custom]
|
|
5
|
+
enum editor: [:code, :upload, :text, :single_choice, :multiple_choice, :hidden, :multiple_files, :custom, :free_form]
|
|
6
6
|
validate :ensure_has_choices, if: :choice?
|
|
7
7
|
end
|
|
8
8
|
|
data/app/models/exercise.rb
CHANGED
|
@@ -84,7 +84,7 @@ class Exercise < ApplicationRecord
|
|
|
84
84
|
reset!
|
|
85
85
|
|
|
86
86
|
attrs = whitelist_attributes(json, except: %w(type id))
|
|
87
|
-
attrs['choices'] = json['choices']
|
|
87
|
+
attrs['choices'] = json['choices']&.map { |choice| choice['value'] } || []
|
|
88
88
|
attrs['bibliotheca_id'] = json['id']
|
|
89
89
|
attrs['number'] = number
|
|
90
90
|
attrs = attrs.except('expectations') if json['type'] != 'problem' || json['new_expectations']
|
data/spec/dummy/db/schema.rb
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#
|
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
|
12
12
|
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
|
13
|
+
ActiveRecord::Schema.define(version: 20181004173216) do
|
|
14
14
|
|
|
15
15
|
# These are extensions that must be enabled in order to support this database
|
|
16
16
|
enable_extension "plpgsql"
|
|
@@ -165,6 +165,7 @@ ActiveRecord::Schema.define(version: 20180802190437) do
|
|
|
165
165
|
t.string "final_state"
|
|
166
166
|
t.text "assistance_rules"
|
|
167
167
|
t.text "randomizations"
|
|
168
|
+
t.text "free_form_editor_source"
|
|
168
169
|
t.index ["guide_id"], name: "index_exercises_on_guide_id"
|
|
169
170
|
t.index ["language_id"], name: "index_exercises_on_language_id"
|
|
170
171
|
end
|
|
@@ -176,8 +176,22 @@ describe Guide do
|
|
|
176
176
|
|
|
177
177
|
it { expect(guide.exercises.first).to be_instance_of(Problem) }
|
|
178
178
|
it { expect(guide.exercises.first).to eq reloaded_exercise_1 }
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context 'when exercise doesnt have choices anymore' do
|
|
182
|
+
let(:exercise_1) { build(:problem,
|
|
183
|
+
bibliotheca_id: 1,
|
|
184
|
+
language: haskell,
|
|
185
|
+
name: 'Choices 1',
|
|
186
|
+
description: 'description',
|
|
187
|
+
hint: 'baz',
|
|
188
|
+
choices: ['option 1', 'option 2'],
|
|
189
|
+
test: 'pending',
|
|
190
|
+
extra: 'foo') }
|
|
179
191
|
|
|
192
|
+
it { expect(guide.exercises.first.choices?).to be false }
|
|
180
193
|
end
|
|
194
|
+
|
|
181
195
|
context 'exercises are reordered' do
|
|
182
196
|
let(:exercise_1) { create(:problem,
|
|
183
197
|
bibliotheca_id: 4,
|
|
@@ -516,25 +516,38 @@ CodeMirror.defineMode("gobstones", function(cmCfg, modeCfg) {
|
|
|
516
516
|
|
|
517
517
|
var GobstonesHighlightRules = function() {
|
|
518
518
|
|
|
519
|
+
var buildList = function(values) {
|
|
520
|
+
return values.join('|');
|
|
521
|
+
};
|
|
522
|
+
|
|
519
523
|
var keywords = (
|
|
520
|
-
|
|
524
|
+
"program|procedure|function|interactive|if|then|else|switch|repeat|while|foreach|in|not|div|mod|Skip|return"
|
|
521
525
|
);
|
|
522
526
|
|
|
523
|
-
var
|
|
524
|
-
|
|
525
|
-
|
|
527
|
+
var allBuiltinConstants = {
|
|
528
|
+
es: ["Verde", "Rojo", "Azul", "Negro", "Norte", "Sur", "Este", "Oeste", "False", "True"],
|
|
529
|
+
pt: ["Verde", "Vermelho", "Azul", "Preto", "Norte", "Sul", "Leste", "Oeste", "False", "True"],
|
|
530
|
+
en: ["Green", "Red", "Blue", "Black", "North", "South", "East", "West", "False", "True"]
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
var allLangClasses = {
|
|
534
|
+
es: ["Poner", "Sacar", "Mover", "IrAlBorde", "VaciarTablero", "nroBolitas", "hayBolitas", "puedeMover", "siguiente", "previo", "opuesto", "minBool", "maxBool", "minDir", "maxDir", "minColor", "maxColor"],
|
|
535
|
+
pt: ["Colocar", "Retirar", "Mover", "IrAlBorda", "VaciarTablero", "nroPedras", "haPedras", "podeMover", "seguinte", "previo", "oposto", "minBool", "maxBool", "minDir", "maxDir", "minCor", "maxCor"],
|
|
536
|
+
en: ["Put", "Grab", "Move", "GoToEdge", "EmptyBoardContents", "numStones", "anyStones", "canMove", "next", "prev", "opposite", "minBool", "maxBool", "minDir", "maxDir", "minColor", "maxColor"]
|
|
537
|
+
};
|
|
526
538
|
|
|
539
|
+
var locale = CodeMirror.currentLocale || 'es';
|
|
527
540
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
541
|
+
registerAutocomplete('gobstones',
|
|
542
|
+
keywords.split('|')
|
|
543
|
+
.concat(allBuiltinConstants[locale])
|
|
544
|
+
.concat(allLangClasses[locale])
|
|
532
545
|
);
|
|
533
546
|
|
|
534
547
|
var keywordMapper = this.createKeywordMapper({
|
|
535
548
|
"keyword": keywords,
|
|
536
|
-
"constant.language":
|
|
537
|
-
"support.function":
|
|
549
|
+
"constant.language": buildList(allBuiltinConstants[locale]),
|
|
550
|
+
"support.function": buildList(allLangClasses[locale]),
|
|
538
551
|
"support.type": ''
|
|
539
552
|
}, "identifier");
|
|
540
553
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mumuki-laboratory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Franco Bulgarelli
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-10-
|
|
11
|
+
date: 2018-10-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
47
|
+
version: 7.3.0
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
54
|
+
version: 7.3.0
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: mumukit-core
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -268,6 +268,8 @@ files:
|
|
|
268
268
|
- app/assets/javascripts/application/console.js
|
|
269
269
|
- app/assets/javascripts/application/csrf-token.js
|
|
270
270
|
- app/assets/javascripts/application/discussions.js
|
|
271
|
+
- app/assets/javascripts/application/free-form.js
|
|
272
|
+
- app/assets/javascripts/application/inputs.js
|
|
271
273
|
- app/assets/javascripts/application/kids.js
|
|
272
274
|
- app/assets/javascripts/application/load-analytics.js
|
|
273
275
|
- app/assets/javascripts/application/load-error-svg.js
|
|
@@ -509,6 +511,7 @@ files:
|
|
|
509
511
|
- app/views/layouts/embedded.html.erb
|
|
510
512
|
- app/views/layouts/exercise_inputs/editors/_code.html.erb
|
|
511
513
|
- app/views/layouts/exercise_inputs/editors/_custom.html.erb
|
|
514
|
+
- app/views/layouts/exercise_inputs/editors/_free_form.html.erb
|
|
512
515
|
- app/views/layouts/exercise_inputs/editors/_hidden.html.erb
|
|
513
516
|
- app/views/layouts/exercise_inputs/editors/_multiple_choice.html.erb
|
|
514
517
|
- app/views/layouts/exercise_inputs/editors/_multiple_files.html.erb
|
|
@@ -798,6 +801,7 @@ files:
|
|
|
798
801
|
- db/migrate/20180704150839_rename_assignment_status_to_submission_status.rb
|
|
799
802
|
- db/migrate/20180725145801_add_submissions_caps_to_exams.rb
|
|
800
803
|
- db/migrate/20180802190437_add_approved_to_messages.rb
|
|
804
|
+
- db/migrate/20181004173216_add_free_form_editor_to_exercises.rb
|
|
801
805
|
- db/seeds/users.rb
|
|
802
806
|
- lib/events.rb
|
|
803
807
|
- lib/mumuki/laboratory.rb
|
|
@@ -1015,7 +1019,6 @@ files:
|
|
|
1015
1019
|
- vendor/assets/javascripts/codemirror-modes/css-hint.min.js
|
|
1016
1020
|
- vendor/assets/javascripts/codemirror-modes/css.min.js
|
|
1017
1021
|
- vendor/assets/javascripts/codemirror-modes/elixir.js
|
|
1018
|
-
- vendor/assets/javascripts/codemirror-modes/gobstones-autocomplete.js
|
|
1019
1022
|
- vendor/assets/javascripts/codemirror-modes/gobstones.js
|
|
1020
1023
|
- vendor/assets/javascripts/codemirror-modes/haskell-autocomplete.js
|
|
1021
1024
|
- vendor/assets/javascripts/codemirror-modes/haskell.min.js
|