Added labels to CAPA input types, with markdown syntax for adding them
in studio. LMS-1895 and others
This commit is contained in:
@@ -99,6 +99,12 @@ or= mouse</code></pre>
|
||||
<pre><code>[[wrong, (right)]]</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h6>${_("Label")}</h6>
|
||||
<div class="col">
|
||||
<pre><code>>>What is the capital of Argentina?<<</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h6>${_("Explanation")}</h6>
|
||||
<div class="col sample explanation">
|
||||
|
||||
@@ -299,7 +299,7 @@ class OptionInput(InputTypeBase):
|
||||
|
||||
Example:
|
||||
|
||||
<optioninput options="('Up','Down')" correct="Up"/><text>The location of the sky</text>
|
||||
<optioninput options="('Up','Down')" label="Where is the sky?" correct="Up"/><text>The location of the sky</text>
|
||||
|
||||
# TODO: allow ordering to be randomized
|
||||
"""
|
||||
@@ -335,6 +335,7 @@ class OptionInput(InputTypeBase):
|
||||
Convert options to a convenient format.
|
||||
"""
|
||||
return [Attribute('options', transform=cls.parse_options),
|
||||
Attribute('label', ''),
|
||||
Attribute('inline', False)]
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@@ -353,7 +354,7 @@ class ChoiceGroup(InputTypeBase):
|
||||
|
||||
Example:
|
||||
|
||||
<choicegroup>
|
||||
<choicegroup label="Which foil?">
|
||||
<choice correct="false" name="foil1">
|
||||
<text>This is foil One.</text>
|
||||
</choice>
|
||||
@@ -388,6 +389,7 @@ class ChoiceGroup(InputTypeBase):
|
||||
@classmethod
|
||||
def get_attributes(cls):
|
||||
return [Attribute("show_correctness", "always"),
|
||||
Attribute('label', ''),
|
||||
Attribute("submitted_message", "Answer received.")]
|
||||
|
||||
def _extra_context(self):
|
||||
@@ -535,7 +537,7 @@ class TextLine(InputTypeBase):
|
||||
is used e.g. for embedding simulations turned into questions.
|
||||
|
||||
Example:
|
||||
<textline math="1" trailing_text="m/s" />
|
||||
<textline math="1" trailing_text="m/s" label="How fast is a cheetah?" />
|
||||
|
||||
This example will render out a text line with a math preview and the text 'm/s'
|
||||
after the end of the text line.
|
||||
@@ -551,7 +553,7 @@ class TextLine(InputTypeBase):
|
||||
"""
|
||||
return [
|
||||
Attribute('size', None),
|
||||
|
||||
Attribute('label', ''),
|
||||
|
||||
Attribute('hidden', False),
|
||||
Attribute('inline', False),
|
||||
@@ -612,6 +614,7 @@ class FileSubmission(InputTypeBase):
|
||||
Convert the list of allowed files to a convenient format.
|
||||
"""
|
||||
return [Attribute('allowed_files', '[]', transform=cls.parse_files),
|
||||
Attribute('label', ''),
|
||||
Attribute('required_files', '[]', transform=cls.parse_files), ]
|
||||
|
||||
def setup(self):
|
||||
@@ -898,6 +901,7 @@ class Schematic(InputTypeBase):
|
||||
Attribute('analyses', None),
|
||||
Attribute('initial_value', None),
|
||||
Attribute('submit_analyses', None),
|
||||
Attribute('label', ''),
|
||||
]
|
||||
|
||||
|
||||
@@ -926,6 +930,7 @@ class ImageInput(InputTypeBase):
|
||||
"""
|
||||
return [Attribute('src'),
|
||||
Attribute('height'),
|
||||
Attribute('label', ''),
|
||||
Attribute('width'), ]
|
||||
|
||||
def setup(self):
|
||||
@@ -1016,7 +1021,8 @@ class ChemicalEquationInput(InputTypeBase):
|
||||
"""
|
||||
Can set size of text field.
|
||||
"""
|
||||
return [Attribute('size', '20'), ]
|
||||
return [Attribute('size', '20'),
|
||||
Attribute('label', ''),]
|
||||
|
||||
def _extra_context(self):
|
||||
"""
|
||||
@@ -1078,7 +1084,7 @@ class FormulaEquationInput(InputTypeBase):
|
||||
|
||||
Example:
|
||||
|
||||
<formulaequationinput size="50"/>
|
||||
<formulaequationinput size="50" label="Enter the equation for motion"/>
|
||||
|
||||
options: size -- width of the textbox.
|
||||
"""
|
||||
@@ -1094,6 +1100,7 @@ class FormulaEquationInput(InputTypeBase):
|
||||
return [
|
||||
Attribute('size', '20'),
|
||||
Attribute('inline', False),
|
||||
Attribute('label', ''),
|
||||
]
|
||||
|
||||
def _extra_context(self):
|
||||
@@ -1494,7 +1501,7 @@ class ChoiceTextGroup(InputTypeBase):
|
||||
select the correct choice and fill in numbers to make it accurate.
|
||||
<endouttext/>
|
||||
<choicetextresponse>
|
||||
<radiotextgroup>
|
||||
<radiotextgroup label="What is the correct choice?">
|
||||
<choice correct="false">The lowest number rolled was:
|
||||
<decoy_input/> and the highest number rolled was:
|
||||
<decoy_input/> .</choice>
|
||||
@@ -1517,7 +1524,7 @@ class ChoiceTextGroup(InputTypeBase):
|
||||
select the correct choices and fill in numbers to make them accurate.
|
||||
<endouttext/>
|
||||
<choicetextresponse>
|
||||
<checkboxtextgroup>
|
||||
<checkboxtextgroup label="What is the answer?">
|
||||
<choice correct="true">
|
||||
The lowest number selected was <numtolerance_input answer="1.4142" tolerance="0.01"/>
|
||||
</choice>
|
||||
@@ -1575,7 +1582,8 @@ class ChoiceTextGroup(InputTypeBase):
|
||||
"""
|
||||
return [
|
||||
Attribute("show_correctness", "always"),
|
||||
Attribute("submitted_message", "Answer received.")
|
||||
Attribute("submitted_message", "Answer received."),
|
||||
Attribute("label", ""),
|
||||
]
|
||||
|
||||
def _extra_context(self):
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="incorrect" id="status_${id}">
|
||||
% endif
|
||||
|
||||
<input type="text" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" data-input-id="${id}" value="${value|h}"
|
||||
<input type="text" name="input_${id}" id="input_${id}" aria-label="${label}" aria-describedby="answer_${id}" data-input-id="${id}" value="${value|h}"
|
||||
% if size:
|
||||
size="${size}"
|
||||
% endif
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
% endif
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<fieldset role="radiogroup" aria-label="${label}">
|
||||
|
||||
% for choice_id, choice_description in choices:
|
||||
<label for="input_${id}_${choice_id}"
|
||||
@@ -32,7 +32,7 @@
|
||||
% endif
|
||||
% endif
|
||||
>
|
||||
<input type="${input_type}" name="input_${id}${name_array_suffix}" id="input_${id}_${choice_id}" aria-describedby="answer_${id}" value="${choice_id}"
|
||||
<input type="${input_type}" name="input_${id}${name_array_suffix}" id="input_${id}_${choice_id}" aria-role="radio" aria-describedby="answer_${id}" value="${choice_id}"
|
||||
## If the student selected this choice...
|
||||
% if input_type == 'radio' and ( (isinstance(value, basestring) and (choice_id == value)) or (not isinstance(value, basestring) and choice_id in value) ):
|
||||
checked="true"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
% endif
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<fieldset aria-label="${label}">
|
||||
% for choice_id, choice_description in choices:
|
||||
<%choice_id= choice_id %>
|
||||
<section id="forinput${choice_id}"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
% endif
|
||||
<p class="debug">${status}</p>
|
||||
|
||||
<input type="file" name="input_${id}" id="input_${id}" value="${value}" multiple="multiple" data-required_files="${required_files|h}" data-allowed_files="${allowed_files|h}"/>
|
||||
<input type="file" name="input_${id}" id="input_${id}" value="${value}" multiple="multiple" data-required_files="${required_files|h}" data-allowed_files="${allowed_files|h}" aria-label="${label}" />
|
||||
</div>
|
||||
<div class="message">${msg|n}</div>
|
||||
</section>
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
<section id="formulaequationinput_${id}" class="inputtype formulaequationinput" ${doinline}>
|
||||
<div class="${reported_status}" id="status_${id}">
|
||||
<input type="text" name="input_${id}" id="input_${id}"
|
||||
data-input-id="${id}" value="${value|h}"
|
||||
% if size:
|
||||
size="${size}"
|
||||
% endif
|
||||
/>
|
||||
data-input-id="${id}" value="${value|h}"
|
||||
aria-label="${label}"
|
||||
% if size:
|
||||
size="${size}"
|
||||
% endif
|
||||
/>
|
||||
|
||||
<p class="status">${reported_status}</p>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<% doinline = "inline" if inline else "" %>
|
||||
|
||||
<form class="inputtype option-input ${doinline}">
|
||||
<select name="input_${id}" id="input_${id}" aria-describedby="answer_${id}">
|
||||
<select name="input_${id}" id="input_${id}" aria-label="${label}" aria-describedby="answer_${id}">
|
||||
<option value="option_${id}_dummy_default"> </option>
|
||||
% for option_id, option_description in options:
|
||||
<option value="${option_id}"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<span>
|
||||
<input type="hidden" class="schematic" height="${height}" width="${width}" parts="${parts}" analyses="${analyses}" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="" initial_value=""/>
|
||||
<input type="hidden" class="schematic" height="${height}" width="${width}" parts="${parts}" analyses="${analyses}" name="input_${id}" id="input_${id}" aria-label="${label}" aria-describedby="answer_${id}" value="" initial_value=""/>
|
||||
|
||||
<div id="value_${id}" style="display:none">${value}</div>
|
||||
<div id="initial_value_${id}" style="display:none">${initial_value}</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
|
||||
% endif
|
||||
|
||||
<input type="text" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="${value|h}"
|
||||
<input type="text" name="input_${id}" id="input_${id}" aria-label="${label}" aria-describedby="answer_${id}" value="${value|h}"
|
||||
% if do_math:
|
||||
class="math"
|
||||
% endif
|
||||
|
||||
@@ -154,6 +154,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
|
||||
expected_textline_context = {
|
||||
'STATIC_URL': '/dummy-static/',
|
||||
'status': 'unsubmitted',
|
||||
'label': '',
|
||||
'value': '',
|
||||
'preprocessor': None,
|
||||
'msg': '',
|
||||
|
||||
@@ -124,6 +124,7 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
self.context = {'id': '1',
|
||||
'choices': choices,
|
||||
'status': 'correct',
|
||||
'label': 'test',
|
||||
'input_type': 'checkbox',
|
||||
'name_array_suffix': '1',
|
||||
'value': '3'}
|
||||
@@ -336,6 +337,11 @@ class ChoiceGroupTemplateTest(TemplateTestCase):
|
||||
# Expect that we do NOT see the message yet
|
||||
self.assert_no_xpath(xml, "//div[@class='capa_alert']", self.context)
|
||||
|
||||
def test_label(self):
|
||||
xml = self.render_to_xml(self.context)
|
||||
xpath = "//fieldset[@aria-label='%s']" % self.context['label']
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
|
||||
|
||||
class TextlineTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
@@ -347,6 +353,7 @@ class TextlineTemplateTest(TemplateTestCase):
|
||||
def setUp(self):
|
||||
self.context = {'id': '1',
|
||||
'status': 'correct',
|
||||
'label': 'test',
|
||||
'value': '3',
|
||||
'preprocessor': None,
|
||||
'trailing_text': None}
|
||||
@@ -384,6 +391,11 @@ class TextlineTemplateTest(TemplateTestCase):
|
||||
self.assert_has_text(xml, "//p[@class='status']",
|
||||
status_mark, exact=False)
|
||||
|
||||
def test_label(self):
|
||||
xml = self.render_to_xml(self.context)
|
||||
xpath = "//input[@aria-label='%s']" % self.context['label']
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
|
||||
def test_hidden(self):
|
||||
self.context['hidden'] = True
|
||||
xml = self.render_to_xml(self.context)
|
||||
@@ -460,6 +472,7 @@ class FormulaEquationInputTemplateTest(TemplateTestCase):
|
||||
'id': 2,
|
||||
'value': 'PREFILLED_VALUE',
|
||||
'status': 'unsubmitted',
|
||||
'label': 'test',
|
||||
'previewer': 'file.js',
|
||||
'reported_status': 'REPORTED_STATUS',
|
||||
}
|
||||
@@ -651,7 +664,7 @@ class OptionInputTemplateTest(TemplateTestCase):
|
||||
TEMPLATE_NAME = 'optioninput.html'
|
||||
|
||||
def setUp(self):
|
||||
self.context = {'id': 2, 'options': [], 'status': 'unsubmitted', 'value': 0}
|
||||
self.context = {'id': 2, 'options': [], 'status': 'unsubmitted', 'label': 'test', 'value': 0}
|
||||
super(OptionInputTemplateTest, self).setUp()
|
||||
|
||||
def test_select_options(self):
|
||||
@@ -694,6 +707,11 @@ class OptionInputTemplateTest(TemplateTestCase):
|
||||
xpath = "//span[@class='{0}']".format(expected_css_class)
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
|
||||
def test_label(self):
|
||||
xml = self.render_to_xml(self.context)
|
||||
xpath = "//select[@aria-label='%s']" % self.context['label']
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
|
||||
|
||||
class DragAndDropTemplateTest(TemplateTestCase):
|
||||
"""
|
||||
@@ -769,6 +787,7 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
|
||||
'choices': choices,
|
||||
'status': 'correct',
|
||||
'input_type': 'radio',
|
||||
'label': 'choicetext label',
|
||||
'value': self.VALUE_DICT}
|
||||
|
||||
super(ChoiceTextGroupTemplateTest, self).setUp()
|
||||
@@ -908,3 +927,8 @@ class ChoiceTextGroupTemplateTest(TemplateTestCase):
|
||||
# Should NOT mark the whole problem
|
||||
xpath = "//div[@class='indicator_container']/span"
|
||||
self.assert_no_xpath(xml, xpath, self.context)
|
||||
|
||||
def test_label(self):
|
||||
xml = self.render_to_xml(self.context)
|
||||
xpath = "//fieldset[@aria-label='%s']" % self.context['label']
|
||||
self.assert_has_xpath(xml, xpath, self.context)
|
||||
|
||||
@@ -56,6 +56,7 @@ class OptionInputTest(unittest.TestCase):
|
||||
'value': 'Down',
|
||||
'options': [('Up', 'Up'), ('Down', 'Down'), ('Don\'t know', 'Don\'t know')],
|
||||
'status': 'answered',
|
||||
'label': '',
|
||||
'msg': '',
|
||||
'inline': False,
|
||||
'id': 'sky_input',
|
||||
@@ -115,6 +116,7 @@ class ChoiceGroupTest(unittest.TestCase):
|
||||
'id': 'sky_input',
|
||||
'value': 'foil3',
|
||||
'status': 'answered',
|
||||
'label': '',
|
||||
'msg': '',
|
||||
'input_type': expected_input_type,
|
||||
'choices': [('foil1', '<text>This is foil One.</text>'),
|
||||
@@ -167,6 +169,7 @@ class JavascriptInputTest(unittest.TestCase):
|
||||
'STATIC_URL': '/dummy-static/',
|
||||
'id': 'prob_1_2',
|
||||
'status': 'unanswered',
|
||||
# 'label': '',
|
||||
'msg': '',
|
||||
'value': '3',
|
||||
'params': params,
|
||||
@@ -185,7 +188,7 @@ class TextLineTest(unittest.TestCase):
|
||||
|
||||
def test_rendering(self):
|
||||
size = "42"
|
||||
xml_str = """<textline id="prob_1_2" size="{size}"/>""".format(size=size)
|
||||
xml_str = """<textline id="prob_1_2" label="testing 123" size="{size}"/>""".format(size=size)
|
||||
|
||||
element = etree.fromstring(xml_str)
|
||||
|
||||
@@ -199,6 +202,7 @@ class TextLineTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'BumbleBee',
|
||||
'status': 'unanswered',
|
||||
'label': 'testing 123',
|
||||
'size': size,
|
||||
'msg': '',
|
||||
'hidden': False,
|
||||
@@ -230,6 +234,7 @@ class TextLineTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'BumbleBee',
|
||||
'status': 'unanswered',
|
||||
'label': '',
|
||||
'size': size,
|
||||
'msg': '',
|
||||
'hidden': False,
|
||||
@@ -273,6 +278,7 @@ class TextLineTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'BumbleBee',
|
||||
'status': 'unanswered',
|
||||
'label': '',
|
||||
'size': size,
|
||||
'msg': '',
|
||||
'hidden': False,
|
||||
@@ -313,6 +319,7 @@ class FileSubmissionTest(unittest.TestCase):
|
||||
'STATIC_URL': '/dummy-static/',
|
||||
'id': 'prob_1_2',
|
||||
'status': 'queued',
|
||||
'label': '',
|
||||
'msg': the_input.submitted_msg,
|
||||
'value': 'BumbleBee.py',
|
||||
'queue_len': '3',
|
||||
@@ -362,6 +369,7 @@ class CodeInputTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'print "good evening"',
|
||||
'status': 'queued',
|
||||
# 'label': '',
|
||||
'msg': the_input.submitted_msg,
|
||||
'mode': mode,
|
||||
'linenumbers': linenumbers,
|
||||
@@ -415,6 +423,7 @@ class MatlabTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'print "good evening"',
|
||||
'status': 'queued',
|
||||
# 'label': '',
|
||||
'msg': self.the_input.submitted_msg,
|
||||
'mode': self.mode,
|
||||
'rows': self.rows,
|
||||
@@ -444,6 +453,7 @@ class MatlabTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'print "good evening"',
|
||||
'status': 'queued',
|
||||
# 'label': '',
|
||||
'msg': the_input.submitted_msg,
|
||||
'mode': self.mode,
|
||||
'rows': self.rows,
|
||||
@@ -473,6 +483,7 @@ class MatlabTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'print "good evening"',
|
||||
'status': status,
|
||||
# 'label': '',
|
||||
'msg': '',
|
||||
'mode': self.mode,
|
||||
'rows': self.rows,
|
||||
@@ -501,6 +512,7 @@ class MatlabTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'print "good evening"',
|
||||
'status': 'queued',
|
||||
# 'label': '',
|
||||
'msg': the_input.submitted_msg,
|
||||
'mode': self.mode,
|
||||
'rows': self.rows,
|
||||
@@ -610,6 +622,7 @@ class SchematicTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': value,
|
||||
'status': 'unsubmitted',
|
||||
'label': '',
|
||||
'msg': '',
|
||||
'initial_value': initial_value,
|
||||
'width': width,
|
||||
@@ -652,6 +665,7 @@ class ImageInputTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': value,
|
||||
'status': 'unsubmitted',
|
||||
'label': '',
|
||||
'width': width,
|
||||
'height': height,
|
||||
'src': src,
|
||||
@@ -706,6 +720,7 @@ class CrystallographyTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': value,
|
||||
'status': 'unsubmitted',
|
||||
# 'label': '',
|
||||
'msg': '',
|
||||
'width': width,
|
||||
'height': height,
|
||||
@@ -779,6 +794,7 @@ class ChemicalEquationTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'H2OYeah',
|
||||
'status': 'unanswered',
|
||||
'label': '',
|
||||
'msg': '',
|
||||
'size': self.size,
|
||||
'previewer': '/dummy-static/js/capa/chemical_equation_preview.js',
|
||||
@@ -866,6 +882,7 @@ class FormulaEquationTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': 'x^2+1/2',
|
||||
'status': 'unanswered',
|
||||
'label': '',
|
||||
'reported_status': '',
|
||||
'msg': '',
|
||||
'size': self.size,
|
||||
@@ -1013,6 +1030,7 @@ class DragAndDropTest(unittest.TestCase):
|
||||
'id': 'prob_1_2',
|
||||
'value': value,
|
||||
'status': 'unsubmitted',
|
||||
# 'label': '',
|
||||
'msg': '',
|
||||
'drag_and_drop_json': json.dumps(user_input)
|
||||
}
|
||||
@@ -1065,6 +1083,7 @@ class AnnotationInputTest(unittest.TestCase):
|
||||
'id': 'annotation_input',
|
||||
'value': value,
|
||||
'status': 'answered',
|
||||
# 'label': '',
|
||||
'msg': '',
|
||||
'title': 'foo',
|
||||
'text': 'bar',
|
||||
@@ -1140,6 +1159,7 @@ class TestChoiceText(unittest.TestCase):
|
||||
expected = {
|
||||
'STATIC_URL': '/dummy-static/',
|
||||
'msg': '',
|
||||
'label': '',
|
||||
'input_type': expected_input_type,
|
||||
'choices': choices,
|
||||
'show_correctness': 'always',
|
||||
|
||||
@@ -388,6 +388,164 @@ describe 'MarkdownEditingDescriptor', ->
|
||||
</div>
|
||||
</solution>
|
||||
</problem>""")
|
||||
# test labels
|
||||
it 'converts markdown labels to label attributes', ->
|
||||
data = MarkdownEditingDescriptor.markdownToXml(""">>Who lead the civil right movement in the United States of America?<<
|
||||
= | \w*\.?\s*Luther King\s*.*
|
||||
|
||||
[Explanation]
|
||||
Test Explanation.
|
||||
[Explanation]
|
||||
""")
|
||||
expect(data).toEqual("""<problem>
|
||||
<p>Who lead the civil right movement in the United States of America?</p>
|
||||
<stringresponse answer="w*.?s*Luther Kings*.*" type="ci regexp" >
|
||||
<textline label="Who lead the civil right movement in the United States of America?" size="20"/>
|
||||
</stringresponse>
|
||||
|
||||
<solution>
|
||||
<div class="detailed-solution">
|
||||
<p>Explanation</p>
|
||||
|
||||
<p>Test Explanation.</p>
|
||||
|
||||
</div>
|
||||
</solution>
|
||||
</problem>""")
|
||||
it 'handles multiple questions with labels', ->
|
||||
data = MarkdownEditingDescriptor.markdownToXml("""
|
||||
France is a country in Europe.
|
||||
|
||||
>>What is the capital of France?<<
|
||||
= Paris
|
||||
|
||||
Germany is a country in Europe, too.
|
||||
|
||||
>>What is the capital of Germany?<<
|
||||
( ) Bonn
|
||||
( ) Hamburg
|
||||
(x) Berlin
|
||||
( ) Donut
|
||||
""")
|
||||
expect(data).toEqual("""<problem>
|
||||
<p>France is a country in Europe.</p>
|
||||
|
||||
<p>What is the capital of France?</p>
|
||||
<stringresponse answer="Paris" type="ci" >
|
||||
<textline label="What is the capital of France?" size="20"/>
|
||||
</stringresponse>
|
||||
|
||||
<p>Germany is a country in Europe, too.</p>
|
||||
|
||||
<p>What is the capital of Germany?</p>
|
||||
<multiplechoiceresponse>
|
||||
<choicegroup type="MultipleChoice">
|
||||
<choice correct="false">Bonn</choice>
|
||||
<choice correct="false">Hamburg</choice>
|
||||
<choice correct="true">Berlin</choice>
|
||||
<choice correct="false">Donut</choice>
|
||||
</choicegroup>
|
||||
</multiplechoiceresponse>
|
||||
|
||||
|
||||
</problem>""")
|
||||
it 'tests multiple questions with only one label', ->
|
||||
data = MarkdownEditingDescriptor.markdownToXml("""
|
||||
France is a country in Europe.
|
||||
|
||||
>>What is the capital of France?<<
|
||||
= Paris
|
||||
|
||||
Germany is a country in Europe, too.
|
||||
|
||||
What is the capital of Germany?
|
||||
( ) Bonn
|
||||
( ) Hamburg
|
||||
(x) Berlin
|
||||
( ) Donut
|
||||
""")
|
||||
expect(data).toEqual("""<problem>
|
||||
<p>France is a country in Europe.</p>
|
||||
|
||||
<p>What is the capital of France?</p>
|
||||
<stringresponse answer="Paris" type="ci" >
|
||||
<textline label="What is the capital of France?" size="20"/>
|
||||
</stringresponse>
|
||||
|
||||
<p>Germany is a country in Europe, too.</p>
|
||||
|
||||
<p>What is the capital of Germany?</p>
|
||||
<multiplechoiceresponse>
|
||||
<choicegroup type="MultipleChoice">
|
||||
<choice correct="false">Bonn</choice>
|
||||
<choice correct="false">Hamburg</choice>
|
||||
<choice correct="true">Berlin</choice>
|
||||
<choice correct="false">Donut</choice>
|
||||
</choicegroup>
|
||||
</multiplechoiceresponse>
|
||||
|
||||
|
||||
</problem>""")
|
||||
it 'tests malformed labels', ->
|
||||
data = MarkdownEditingDescriptor.markdownToXml("""
|
||||
France is a country in Europe.
|
||||
|
||||
>>What is the capital of France?<
|
||||
= Paris
|
||||
|
||||
blah>>What is the capital of <<Germany?<<
|
||||
( ) Bonn
|
||||
( ) Hamburg
|
||||
(x) Berlin
|
||||
( ) Donut
|
||||
""")
|
||||
expect(data).toEqual("""<problem>
|
||||
<p>France is a country in Europe.</p>
|
||||
|
||||
<p>>>What is the capital of France?<</p>
|
||||
<stringresponse answer="Paris" type="ci" >
|
||||
<textline size="20"/>
|
||||
</stringresponse>
|
||||
|
||||
<p>blahWhat is the capital of Germany?</p>
|
||||
<multiplechoiceresponse>
|
||||
<choicegroup label="What is the capital of <<Germany?" type="MultipleChoice">
|
||||
<choice correct="false">Bonn</choice>
|
||||
<choice correct="false">Hamburg</choice>
|
||||
<choice correct="true">Berlin</choice>
|
||||
<choice correct="false">Donut</choice>
|
||||
</choicegroup>
|
||||
</multiplechoiceresponse>
|
||||
|
||||
|
||||
</problem>""")
|
||||
it 'adds labels to formulae', ->
|
||||
data = MarkdownEditingDescriptor.markdownToXml("""
|
||||
>>Enter the numerical value of Pi:<<
|
||||
= 3.14159 +- .02
|
||||
""")
|
||||
expect(data).toEqual("""<problem>
|
||||
<p>Enter the numerical value of Pi:</p>
|
||||
<numericalresponse answer="3.14159">
|
||||
<responseparam type="tolerance" default=".02" />
|
||||
<formulaequationinput label="Enter the numerical value of Pi:" />
|
||||
</numericalresponse>
|
||||
|
||||
|
||||
</problem>""")
|
||||
it 'escapes entities in labels', ->
|
||||
data = MarkdownEditingDescriptor.markdownToXml("""
|
||||
>>What is the "capital" of France & the 'best' > place < to live"?<<
|
||||
= Paris
|
||||
""")
|
||||
expect(data).toEqual("""<problem>
|
||||
<p>What is the "capital" of France & the 'best' > place < to live"?</p>
|
||||
<stringresponse answer="Paris" type="ci" >
|
||||
<textline label="What is the "capital" of France & the 'best' > place < to live"?" size="20"/>
|
||||
</stringresponse>
|
||||
|
||||
|
||||
</problem>""")
|
||||
# test oddities
|
||||
it 'converts headers and oddities to xml', ->
|
||||
data = MarkdownEditingDescriptor.markdownToXml("""Not a header
|
||||
|
||||
@@ -329,6 +329,33 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor
|
||||
|
||||
return selectString;
|
||||
});
|
||||
|
||||
// replace labels
|
||||
// looks for >>arbitrary text<< and inserts it into the label attribute of the input type directly below the text.
|
||||
var split = xml.split('\n');
|
||||
var new_xml = [];
|
||||
var line, i, curlabel = '';
|
||||
var didinput = false;
|
||||
for (i = 0; i < split.length; i++) {
|
||||
line = split[i];
|
||||
if (match = line.match(/>>(.*)<</)) {
|
||||
curlabel = match[1].replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
line = line.replace(/>>|<</g, '');
|
||||
} else if (line.match(/<\w+response/) && didinput) {
|
||||
// reset label to prevent gobbling up previous one (if multiple questions)
|
||||
curlabel = '';
|
||||
didinput = false;
|
||||
} else if (line.match(/<(textline|optioninput|formulaequationinput|choicegroup|checkboxgroup)/) && curlabel != '') {
|
||||
line = line.replace(/<(textline|optioninput|formulaequationinput|choicegroup|checkboxgroup)/, '<$1 label="' + curlabel + '"');
|
||||
didinput = true;
|
||||
}
|
||||
new_xml.push(line);
|
||||
}
|
||||
xml = new_xml.join('\n');
|
||||
|
||||
// replace code blocks
|
||||
xml = xml.replace(/\[code\]\n?([^\]]*)\[\/?code\]/gmi, function(match, p1) {
|
||||
|
||||
@@ -13,7 +13,7 @@ data: |
|
||||
<problem>
|
||||
<p>A checkboxes problem presents checkbox buttons for student input. Students can select more than one option presented.</p>
|
||||
<choiceresponse>
|
||||
<checkboxgroup direction="vertical">
|
||||
<checkboxgroup direction="vertical" label="Select the answer that matches">
|
||||
<choice correct="true">correct</choice>
|
||||
<choice correct="false">incorrect</choice>
|
||||
<choice correct="true">correct</choice>
|
||||
|
||||
@@ -27,14 +27,14 @@ data: |
|
||||
|
||||
<p>Enter two integers which sum to 10: </p>
|
||||
<customresponse cfn="test_add_to_ten">
|
||||
<textline size="40" correct_answer="3"/><br/>
|
||||
<textline size="40" correct_answer="7"/>
|
||||
<textline size="40" correct_answer="3" label="Integer #1"/><br/>
|
||||
<textline size="40" correct_answer="7" label="Integer #2"/>
|
||||
</customresponse>
|
||||
|
||||
<p>Enter two integers which sum to 20: </p>
|
||||
<customresponse cfn="test_add" expect="20">
|
||||
<textline size="40" correct_answer="11"/><br/>
|
||||
<textline size="40" correct_answer="9"/>
|
||||
<textline size="40" correct_answer="11" label="Integer #1"/><br/>
|
||||
<textline size="40" correct_answer="9" label="Integer #2"/>
|
||||
</customresponse>
|
||||
|
||||
<solution>
|
||||
|
||||
@@ -32,7 +32,7 @@ data: |
|
||||
|
||||
<formularesponse type="ci" samples="R_1,R_2,R_3@1,2,3:3,4,5#10" answer="$VoVi">
|
||||
<responseparam type="tolerance" default="0.00001"/>
|
||||
<formulaequationinput size="40" />
|
||||
<formulaequationinput size="40" label="Enter the equation"/>
|
||||
</formularesponse>
|
||||
<solution>
|
||||
<div class="detailed-solution">
|
||||
|
||||
@@ -98,7 +98,7 @@ data: |
|
||||
Where is the earth? </p>
|
||||
<p>
|
||||
<optionresponse>
|
||||
<optioninput options="('up','down')" correct="down"/>
|
||||
<optioninput options="('up','down')" correct="down" label="Where is the earth?"/>
|
||||
</optionresponse>
|
||||
</p>
|
||||
<p>
|
||||
@@ -108,7 +108,7 @@ data: |
|
||||
What is Einstein's equation for the energy equivalent of a mass [mathjaxinline]m[/mathjaxinline]? </p>
|
||||
<p>
|
||||
<symbolicresponse expect="m*c^2">
|
||||
<textline size="90" correct_answer="m*c^2" math="1"/>
|
||||
<textline size="90" correct_answer="m*c^2" math="1" label="Enter Einstein's equation"/>
|
||||
</symbolicresponse>
|
||||
</p>
|
||||
<p>
|
||||
@@ -120,7 +120,7 @@ data: |
|
||||
<p style="display:inline">Energy saved = </p>
|
||||
<numericalresponse inline="1" answer="0.52">
|
||||
<responseparam description="Numerical Tolerance" type="tolerance" default="0.02" name="tol"/>
|
||||
<formulaequationinput/>
|
||||
<formulaequationinput label="Enter the equation"/>
|
||||
</numericalresponse>
|
||||
<p style="display:inline"> EJ/year</p>
|
||||
</p>
|
||||
@@ -131,7 +131,7 @@ data: |
|
||||
What color is a banana? </p>
|
||||
<p>
|
||||
<choiceresponse>
|
||||
<checkboxgroup>
|
||||
<checkboxgroup label="What color is a banana?">
|
||||
<choice correct="false" name="1">
|
||||
<text>Red</text>
|
||||
</choice>
|
||||
@@ -154,7 +154,7 @@ data: |
|
||||
In what U.S. state is Detroit located? </p>
|
||||
<p>
|
||||
<stringresponse answer="Michigan">
|
||||
<textline/>
|
||||
<textline label="What state contains Michigan?"/>
|
||||
</stringresponse>
|
||||
</p>
|
||||
<p>
|
||||
@@ -179,7 +179,7 @@ data: |
|
||||
Enter a python list of two numbers which sum to 10, eg [9,1]: </p>
|
||||
<p>
|
||||
<customresponse cfn="sumtest" expect="[1,9]">
|
||||
<textline correct_answer="[1,9]"/>
|
||||
<textline correct_answer="[1,9]" label="Enter the python list"/>
|
||||
</customresponse>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -10,7 +10,7 @@ metadata:
|
||||
That is, each of the alternate responses presented to the student should be the result of a plausible mistake
|
||||
that a student might make.
|
||||
|
||||
What Apple device competed with the portable CD player?
|
||||
>>What Apple device competed with the portable CD player?<<
|
||||
( ) The iPad
|
||||
( ) Napster
|
||||
(x) The iPod
|
||||
@@ -30,7 +30,7 @@ data: |
|
||||
|
||||
<p>What Apple device competed with the portable CD player?</p>
|
||||
<multiplechoiceresponse>
|
||||
<choicegroup type="MultipleChoice">
|
||||
<choicegroup type="MultipleChoice" label="What Apple device competed with the portable CD player?">
|
||||
<choice correct="false" name="ipad">The iPad</choice>
|
||||
<choice correct="false" name="beatles">Napster</choice>
|
||||
<choice correct="true" name="ipod">The iPod</choice>
|
||||
|
||||
@@ -9,13 +9,13 @@ metadata:
|
||||
The answer is correct if it is within a specified numerical tolerance
|
||||
of the expected answer.
|
||||
|
||||
Enter the numerical value of Pi:
|
||||
>>Enter the numerical value of Pi:<<
|
||||
= 3.14159 +- .02
|
||||
|
||||
Enter the approximate value of 502*9:
|
||||
>>Enter the approximate value of 502*9:<<
|
||||
= 4518 +- 15%
|
||||
|
||||
Enter the number of fingers on a human hand:
|
||||
>>Enter the number of fingers on a human hand<<
|
||||
= 5
|
||||
|
||||
[explanation]
|
||||
@@ -47,19 +47,19 @@ data: |
|
||||
<p>Enter the numerical value of Pi:
|
||||
<numericalresponse answer="3.14159">
|
||||
<responseparam type="tolerance" default=".02" />
|
||||
<formulaequationinput />
|
||||
<formulaequationinput label="Enter the numerical value of Pi" />
|
||||
</numericalresponse>
|
||||
</p>
|
||||
<p>Enter the approximate value of 502*9:
|
||||
<numericalresponse answer="$computed_response">
|
||||
<responseparam type="tolerance" default="15%"/>
|
||||
<formulaequationinput />
|
||||
<formulaequationinput label="Enter the approximate value of 502 times 9"/>
|
||||
</numericalresponse>
|
||||
</p>
|
||||
|
||||
<p>Enter the number of fingers on a human hand:
|
||||
<numericalresponse answer="5">
|
||||
<formulaequationinput />
|
||||
<formulaequationinput label="Enter the number of fingers on a human hand"/>
|
||||
</numericalresponse>
|
||||
</p>
|
||||
<solution>
|
||||
|
||||
@@ -8,7 +8,7 @@ metadata:
|
||||
|
||||
The answer options and the identification of the correct answer is defined in the <b>optioninput</b> tag.
|
||||
|
||||
Translation between Dropdown and __________ is extremely straightforward:
|
||||
>>Translation between Dropdown and __________ is extremely straightforward:<<
|
||||
|
||||
[[(Multiple Choice), Text Input, Numerical Input, External Response, Image Response]]
|
||||
|
||||
@@ -29,7 +29,7 @@ data: |
|
||||
<p>Translation between Dropdown and __________ is extremely straightforward:
|
||||
|
||||
<optionresponse>
|
||||
<optioninput options="('Multiple Choice','Text Input','Numerical Input','External Response','Image Response')" correct="Multiple Choice"></optioninput>
|
||||
<optioninput options="('Multiple Choice','Text Input','Numerical Input','External Response','Image Response')" correct="Multiple Choice" label="Translation between Dropdown and __________ is extremely straightforward"></optioninput>
|
||||
</optionresponse>
|
||||
</p>
|
||||
<solution>
|
||||
|
||||
@@ -40,7 +40,7 @@ data: |
|
||||
What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes. </p>
|
||||
<p>
|
||||
<customresponse cfn="test_str" expect="python">
|
||||
<textline correct_answer="python"/>
|
||||
<textline correct_answer="python" label="What is the best programming language that exists today?"/>
|
||||
<hintgroup hintfn="hint_fn"/>
|
||||
</customresponse>
|
||||
</p>
|
||||
|
||||
@@ -85,7 +85,7 @@ data: |
|
||||
What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes. </p>
|
||||
<p>
|
||||
<customresponse cfn="test_str" expect="python">
|
||||
<textline correct_answer="python"/>
|
||||
<textline correct_answer="python" label="What is the best programming language that exists today?"/>
|
||||
<hintgroup hintfn="hint_fn"/>
|
||||
</customresponse>
|
||||
</p>
|
||||
|
||||
@@ -9,7 +9,7 @@ metadata:
|
||||
The answer is correct if it matches every character of the expected answer. This can be a problem with
|
||||
international spelling, dates, or anything where the format of the answer is not clear.
|
||||
|
||||
Which US state has Lansing as its capital?
|
||||
>>Which US state has Lansing as its capital?<<
|
||||
|
||||
= Michigan
|
||||
|
||||
@@ -29,9 +29,9 @@ data: |
|
||||
The answer is correct if it matches every character of the expected answer. This can be a problem with international spelling, dates, or anything where the format of the answer is not clear.
|
||||
</p>
|
||||
|
||||
<p >Which US state has Lansing as its capital? </p>
|
||||
<p>Which US state has Lansing as its capital? </p>
|
||||
<stringresponse answer="Michigan" type="ci">
|
||||
<textline size="20"/>
|
||||
<textline size="20" label="Which US state has Lansing as its capital?"/>
|
||||
</stringresponse>
|
||||
<solution>
|
||||
<div class="detailed-solution">
|
||||
|
||||
Reference in New Issue
Block a user