summaryrefslogtreecommitdiff
path: root/yaksh
diff options
context:
space:
mode:
Diffstat (limited to 'yaksh')
-rw-r--r--yaksh/admin.py14
-rw-r--r--yaksh/base_evaluator.py20
-rw-r--r--yaksh/bash_code_evaluator.py64
-rw-r--r--yaksh/bash_stdio_evaluator.py5
-rw-r--r--yaksh/cpp_code_evaluator.py35
-rw-r--r--yaksh/cpp_stdio_evaluator.py51
-rw-r--r--yaksh/decorators.py5
-rw-r--r--yaksh/documentation/conf.py8
-rw-r--r--yaksh/error_messages.py10
-rw-r--r--yaksh/evaluator_tests/test_bash_evaluation.py230
-rw-r--r--yaksh/evaluator_tests/test_c_cpp_evaluation.py288
-rw-r--r--yaksh/evaluator_tests/test_grader_evaluation.py32
-rw-r--r--yaksh/evaluator_tests/test_java_evaluation.py270
-rw-r--r--yaksh/evaluator_tests/test_python_stdio_evaluator.py5
-rw-r--r--yaksh/evaluator_tests/test_scilab_evaluation.py27
-rw-r--r--yaksh/evaluator_tests/test_simple_question_types.py250
-rw-r--r--yaksh/file_utils.py2
-rw-r--r--yaksh/hook_evaluator.py15
-rw-r--r--yaksh/java_code_evaluator.py35
-rw-r--r--yaksh/java_stdio_evaluator.py6
-rw-r--r--yaksh/language_registry.py13
-rw-r--r--yaksh/management/commands/create_moderator.py21
-rw-r--r--yaksh/middleware/one_session_per_user.py28
-rw-r--r--yaksh/middleware/user_time_zone.py6
-rw-r--r--yaksh/models.py101
-rw-r--r--yaksh/python_stdio_evaluator.py1
-rw-r--r--yaksh/scilab_code_evaluator.py17
-rw-r--r--yaksh/send_emails.py13
-rw-r--r--yaksh/settings.py29
-rw-r--r--yaksh/stdio_evaluator.py4
-rw-r--r--yaksh/templatetags/test_custom_filters.py105
-rw-r--r--yaksh/test_models.py515
-rw-r--r--yaksh/test_views.py1127
-rw-r--r--yaksh/tests/test_code_server.py7
-rw-r--r--yaksh/urls.py143
-rw-r--r--yaksh/views.py240
36 files changed, 2063 insertions, 1679 deletions
diff --git a/yaksh/admin.py b/yaksh/admin.py
index 199fb56..7ea8ed6 100644
--- a/yaksh/admin.py
+++ b/yaksh/admin.py
@@ -1,16 +1,18 @@
from yaksh.models import Question, Quiz, QuestionPaper, Profile
-from yaksh.models import TestCase, StandardTestCase, StdIOBasedTestCase, Course, AnswerPaper
+from yaksh.models import (TestCase, StandardTestCase, StdIOBasedTestCase,
+ Course, AnswerPaper)
from django.contrib import admin
-
class AnswerPaperAdmin(admin.ModelAdmin):
- search_fields = ['user__first_name', 'user__last_name','user__username',
- "question_paper__quiz__description","user_ip" ]
+ search_fields = ['user__first_name', 'user__last_name', 'user__username',
+ "question_paper__quiz__description", "user_ip"]
+
class ProfileAdmin(admin.ModelAdmin):
- search_fields = ['user__first_name', 'user__last_name','user__username',
- "roll_number", "institute","department"]
+ search_fields = ['user__first_name', 'user__last_name', 'user__username',
+ "roll_number", "institute", "department"]
+
admin.site.register(Profile, ProfileAdmin)
admin.site.register(Question)
diff --git a/yaksh/base_evaluator.py b/yaksh/base_evaluator.py
index e702f68..567d5ad 100644
--- a/yaksh/base_evaluator.py
+++ b/yaksh/base_evaluator.py
@@ -1,20 +1,19 @@
#!/usr/bin/env python
from __future__ import unicode_literals
-import traceback
-import pwd
import os
-from os.path import join, isfile
-from os.path import isdir, dirname, abspath, join, isfile, exists
+from os.path import abspath, exists
import subprocess
import stat
import signal
# Local imports
-from .grader import MY_DIR, TimeoutException
+from .grader import TimeoutException
+
class BaseEvaluator(object):
- """Base Evaluator class containing generic attributes and callable methods"""
+ """Base Evaluator class containing generic attributes
+ and callable methods"""
def __init__(self):
pass
@@ -31,7 +30,8 @@ class BaseEvaluator(object):
stdout and stderr.
"""
try:
- proc = subprocess.Popen(cmd_args,preexec_fn=os.setpgrp, *args, **kw)
+ proc = subprocess.Popen(cmd_args,
+ preexec_fn=os.setpgrp, *args, **kw)
stdout, stderr = proc.communicate()
except TimeoutException:
# Runaway code, so kill it.
@@ -64,6 +64,6 @@ class BaseEvaluator(object):
submit_f.close()
def _set_file_as_executable(self, fname):
- os.chmod(fname, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
- | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
- | stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH)
+ os.chmod(fname, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
+ stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH |
+ stat.S_IWOTH | stat.S_IXOTH)
diff --git a/yaksh/bash_code_evaluator.py b/yaksh/bash_code_evaluator.py
index 288a744..61cb9fa 100644
--- a/yaksh/bash_code_evaluator.py
+++ b/yaksh/bash_code_evaluator.py
@@ -1,12 +1,8 @@
#!/usr/bin/env python
from __future__ import unicode_literals
-import traceback
-import pwd
import os
-from os.path import join, isfile
-import sys
+from os.path import isfile
import subprocess
-import importlib
# local imports
from .base_evaluator import BaseEvaluator
@@ -19,7 +15,7 @@ class BashCodeEvaluator(BaseEvaluator):
self.files = []
self.submit_code_path = ""
self.test_code_path = ""
- self.tc_args_path= ""
+ self.tc_args_path = ""
# Set metadata values
self.user_answer = metadata.get('user_answer')
@@ -55,20 +51,20 @@ class BashCodeEvaluator(BaseEvaluator):
Returns
--------
- success - Boolean, indicating if code was executed successfully, correctly
+ success - Boolean, indicating if code was executed successfully,
+ correctly
weight - Float, indicating total weight of all successful test cases
error - String, error message if success is false
- returns (True, "Correct answer", 1.0) : If the student script passes all
- test cases/have same output, when compared to the instructor script
+ returns (True, "Correct answer", 1.0) : If the student script passes
+ all test cases/have same output, when compared to the instructor script
returns (False, error_msg, 0.0): If the student script fails a single
test/have dissimilar output, when compared to the instructor script.
- Returns (False, error_msg, 0.0): If mandatory arguments are not files or if
- the required permissions are not given to the file(s).
+ Returns (False, error_msg, 0.0): If mandatory arguments are not files
+ or if the required permissions are not given to the file(s).
"""
- success = False
mark_fraction = 0.0
self.submit_code_path = self.create_submit_code_file('submit.sh')
self._set_file_as_executable(self.submit_code_path)
@@ -76,13 +72,15 @@ class BashCodeEvaluator(BaseEvaluator):
self._set_file_as_executable(self.test_code_path)
if self.test_case_args:
self.tc_args_path = self.create_submit_code_file('main.args')
- self.write_to_submit_code_file(self.tc_args_path, self.test_case_args)
+ self.write_to_submit_code_file(self.tc_args_path,
+ self.test_case_args)
shebang = "#!/bin/bash\n"
self.user_answer = shebang + self.user_answer.replace("\r", "")
self.test_case = self.test_case.replace("\r", "")
self.write_to_submit_code_file(self.submit_code_path, self.user_answer)
self.write_to_submit_code_file(self.test_code_path, self.test_case)
- clean_ref_code_path, clean_test_case_path = self.test_code_path, self.tc_args_path
+ clean_ref_code_path, clean_test_case_path = \
+ self.test_code_path, self.tc_args_path
if self.file_paths:
self.files = copy_files(self.file_paths)
@@ -101,22 +99,23 @@ class BashCodeEvaluator(BaseEvaluator):
if not clean_test_case_path:
ret = self._run_command(["bash", clean_ref_code_path],
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
proc, inst_stdout, inst_stderr = ret
ret = self._run_command(["bash", self.submit_code_path],
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
proc, stdnt_stdout, stdnt_stderr = ret
if inst_stdout == stdnt_stdout:
mark_fraction = 1.0 if self.partial_grading else 0.0
return True, None, mark_fraction
else:
- err = "Error: expected %s, got %s" % (inst_stdout + inst_stderr,
+ err = "Error: expected %s, got %s" % (
+ inst_stdout + inst_stderr,
stdnt_stdout + stdnt_stderr
)
return False, err, 0.0
@@ -140,27 +139,28 @@ class BashCodeEvaluator(BaseEvaluator):
args = ["bash", clean_ref_code_path] + \
[x for x in tc.split()]
ret = self._run_command(args,
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
proc, inst_stdout, inst_stderr = ret
if self.file_paths:
self.files = copy_files(self.file_paths)
args = ["bash", self.submit_code_path] + \
[x for x in tc.split()]
ret = self._run_command(args,
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
proc, stdnt_stdout, stdnt_stderr = ret
valid_answer = inst_stdout == stdnt_stdout
if valid_answer and (num_lines == loop_count):
mark_fraction = 1.0 if self.partial_grading else 0.0
return True, None, mark_fraction
else:
- err = ("Error:expected"
- " {0}, got {1}").format(inst_stdout+inst_stderr,
+ err = ("Error:expected {0}, got {1}").format(
+ inst_stdout+inst_stderr,
stdnt_stdout+stdnt_stderr
)
return False, err, 0.0
diff --git a/yaksh/bash_stdio_evaluator.py b/yaksh/bash_stdio_evaluator.py
index 1ce729a..f445e09 100644
--- a/yaksh/bash_stdio_evaluator.py
+++ b/yaksh/bash_stdio_evaluator.py
@@ -4,7 +4,7 @@ import subprocess
import os
from os.path import isfile
-#local imports
+# local imports
from .stdio_evaluator import StdIOEvaluator
from .file_utils import copy_files, delete_files
@@ -22,7 +22,7 @@ class BashStdIOEvaluator(StdIOEvaluator):
# Set test case data values
self.expected_input = test_case_data.get('expected_input')
self.expected_output = test_case_data.get('expected_output')
- self.weight = test_case_data.get('weight')
+ self.weight = test_case_data.get('weight')
def teardown(self):
os.remove(self.submit_code_path)
@@ -36,7 +36,6 @@ class BashStdIOEvaluator(StdIOEvaluator):
if not isfile(self.submit_code_path):
msg = "No file at %s or Incorrect path" % self.submit_code_path
return False, msg
- user_code_directory = os.getcwd() + '/'
self.user_answer = self.user_answer.replace("\r", "")
self.write_to_submit_code_file(self.submit_code_path, self.user_answer)
diff --git a/yaksh/cpp_code_evaluator.py b/yaksh/cpp_code_evaluator.py
index 4c8e938..8bd3beb 100644
--- a/yaksh/cpp_code_evaluator.py
+++ b/yaksh/cpp_code_evaluator.py
@@ -1,9 +1,7 @@
#!/usr/bin/env python
from __future__ import unicode_literals
-import traceback
-import pwd
import os
-from os.path import join, isfile
+from os.path import isfile
import subprocess
# Local imports
@@ -51,12 +49,13 @@ class CppCodeEvaluator(BaseEvaluator):
return user_output_path, ref_output_path
def get_commands(self, clean_ref_code_path, user_output_path,
- ref_output_path):
- compile_command = 'g++ {0} -c -o {1}'.format(self.submit_code_path,
- user_output_path)
- compile_main = 'g++ {0} {1} -o {2}'.format(clean_ref_code_path,
- user_output_path,
- ref_output_path)
+ ref_output_path):
+ compile_command = 'g++ {0} -c -o {1}'.format(
+ self.submit_code_path, user_output_path)
+ compile_main = 'g++ {0} {1} -o {2}'.format(
+ clean_ref_code_path, user_output_path,
+ ref_output_path
+ )
return compile_command, compile_main
def compile_code(self):
@@ -65,7 +64,8 @@ class CppCodeEvaluator(BaseEvaluator):
else:
self.submit_code_path = self.create_submit_code_file('submit.c')
self.test_code_path = self.create_submit_code_file('main.c')
- self.write_to_submit_code_file(self.submit_code_path, self.user_answer)
+ self.write_to_submit_code_file(self.submit_code_path,
+ self.user_answer)
self.write_to_submit_code_file(self.test_code_path, self.test_case)
clean_ref_code_path = self.test_code_path
if self.file_paths:
@@ -129,13 +129,12 @@ class CppCodeEvaluator(BaseEvaluator):
if stdnt_stderr == '':
proc, main_out, main_err = self.compiled_test_code
main_err = self._remove_null_substitute_char(main_err)
-
if main_err == '':
ret = self._run_command([self.ref_output_path],
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
proc, stdout, stderr = ret
if proc.returncode == 0:
success, err = True, None
@@ -143,7 +142,7 @@ class CppCodeEvaluator(BaseEvaluator):
else:
err = "{0} \n {1}".format(stdout, stderr)
else:
- err = "Error:"
+ err = "Test case Error:"
try:
error_lines = main_err.splitlines()
for e in error_lines:
@@ -151,7 +150,7 @@ class CppCodeEvaluator(BaseEvaluator):
err = "{0} \n {1}".format(err, e.split(":", 1)[1])
else:
err = "{0} \n {1}".format(err, e)
- except:
+ except Exception:
err = "{0} \n {1}".format(err, main_err)
else:
err = "Compilation Error:"
@@ -162,7 +161,7 @@ class CppCodeEvaluator(BaseEvaluator):
err = "{0} \n {1}".format(err, e.split(":", 1)[1])
else:
err = "{0} \n {1}".format(err, e)
- except:
+ except Exception:
err = "{0} \n {1}".format(err, stdnt_stderr)
return success, err, mark_fraction
diff --git a/yaksh/cpp_stdio_evaluator.py b/yaksh/cpp_stdio_evaluator.py
index d211bb7..4e8f8df 100644
--- a/yaksh/cpp_stdio_evaluator.py
+++ b/yaksh/cpp_stdio_evaluator.py
@@ -4,7 +4,7 @@ import subprocess
import os
from os.path import isfile
-#Local imports
+# Local imports
from .stdio_evaluator import StdIOEvaluator
from .file_utils import copy_files, delete_files
@@ -22,12 +22,17 @@ class CppStdIOEvaluator(StdIOEvaluator):
# Set test case data values
self.expected_input = test_case_data.get('expected_input')
self.expected_output = test_case_data.get('expected_output')
- self.weight = test_case_data.get('weight')
+ self.weight = test_case_data.get('weight')
def teardown(self):
- os.remove(self.submit_code_path)
+ if os.path.exists(self.submit_code_path):
+ os.remove(self.submit_code_path)
if self.files:
delete_files(self.files)
+ if os.path.exists(self.ref_output_path):
+ os.remove(self.ref_output_path)
+ if os.path.exists(self.user_output_path):
+ os.remove(self.user_output_path)
def set_file_paths(self):
user_output_path = os.getcwd() + '/output_file'
@@ -44,7 +49,7 @@ class CppStdIOEvaluator(StdIOEvaluator):
def compile_code(self):
self.submit_code_path = self.create_submit_code_file('submit.c')
if self.file_paths:
- self.files = copy_files(file_paths)
+ self.files = copy_files(self.file_paths)
if not isfile(self.submit_code_path):
msg = "No file at %s or Incorrect path" % self.submit_code_path
return False, msg
@@ -77,31 +82,17 @@ class CppStdIOEvaluator(StdIOEvaluator):
if stdnt_stderr == '':
proc, main_out, main_err = self.compiled_test_code
main_err = self._remove_null_substitute_char(main_err)
- if main_err == '':
- proc = subprocess.Popen("./executable",
- shell=True,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- preexec_fn=os.setpgrp
- )
- success, err = self.evaluate_stdio(self.user_answer, proc,
- self.expected_input,
- self.expected_output
- )
- os.remove(self.ref_output_path)
- else:
- err = "Error:"
- try:
- error_lines = main_err.splitlines()
- for e in error_lines:
- if ':' in e:
- err = err + "\n" + e.split(":", 1)[1]
- else:
- err = err + "\n" + e
- except:
- err = err + "\n" + main_err
- os.remove(self.user_output_path)
+ proc = subprocess.Popen("./executable",
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ preexec_fn=os.setpgrp
+ )
+ success, err = self.evaluate_stdio(self.user_answer, proc,
+ self.expected_input,
+ self.expected_output
+ )
else:
err = "Compilation Error:"
try:
@@ -111,7 +102,7 @@ class CppStdIOEvaluator(StdIOEvaluator):
err = err + "\n" + e.split(":", 1)[1]
else:
err = err + "\n" + e
- except:
+ except Exception:
err = err + "\n" + stdnt_stderr
mark_fraction = 1.0 if self.partial_grading and success else 0.0
return success, err, mark_fraction
diff --git a/yaksh/decorators.py b/yaksh/decorators.py
index 4b886a3..81912f0 100644
--- a/yaksh/decorators.py
+++ b/yaksh/decorators.py
@@ -1,6 +1,5 @@
-from django.shortcuts import render, redirect
+from django.shortcuts import render
from django.conf import settings
-from django.template import RequestContext
# Local imports
from yaksh.forms import ProfileForm
@@ -50,4 +49,4 @@ def email_verified(func):
request, 'yaksh/activation_status.html', context
)
return func(request, *args, **kwargs)
- return is_email_verified \ No newline at end of file
+ return is_email_verified
diff --git a/yaksh/documentation/conf.py b/yaksh/documentation/conf.py
index 1a2c50f..39481c7 100644
--- a/yaksh/documentation/conf.py
+++ b/yaksh/documentation/conf.py
@@ -38,7 +38,7 @@ extensions = [
'sphinx.ext.mathjax',
'sphinx.ext.ifconfig',
'sphinx.ext.viewcode',
-# 'sphinx.ext.githubpages',
+ # 'sphinx.ext.githubpages',
]
# Add any paths that contain templates here, relative to this directory.
@@ -129,7 +129,7 @@ todo_include_todos = True
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'default' #'sphinx_rtd_theme'
+html_theme = 'default' # 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -155,8 +155,8 @@ html_theme = 'default' #'sphinx_rtd_theme'
# html_logo = None
# The name of an image file (relative to this directory) to use as a favicon of
-# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
+# the docs. This file should be a Windows icon file (.ico) being 16x16 or
+# 32x32 pixels large.
#
# html_favicon = None
diff --git a/yaksh/error_messages.py b/yaksh/error_messages.py
index 7a18c22..512d664 100644
--- a/yaksh/error_messages.py
+++ b/yaksh/error_messages.py
@@ -50,15 +50,15 @@ def compare_outputs(expected_output, user_output, given_input=None):
err_line_numbers = _get_incorrect_user_lines(exp_lines, given_lines)
msg["error_line_numbers"] = err_line_numbers
if ng != ne:
- msg["error_msg"] = ("Incorrect Answer: "
- + "We had expected {} number of lines. ".format(ne)
- + "We got {} number of lines.".format(ng)
+ msg["error_msg"] = ("Incorrect Answer: " +
+ "We had expected {} number of lines. ".format(ne) +
+ "We got {} number of lines.".format(ng)
)
return False, msg
else:
if err_line_numbers:
- msg["error_msg"] = ("Incorrect Answer: "
- + "Line number(s) {0} did not match."
+ msg["error_msg"] = ("Incorrect Answer: " +
+ "Line number(s) {0} did not match."
.format(", ".join(
map(str, [x+1 for x in err_line_numbers])
)))
diff --git a/yaksh/evaluator_tests/test_bash_evaluation.py b/yaksh/evaluator_tests/test_bash_evaluation.py
index 5542710..f86bf24 100644
--- a/yaksh/evaluator_tests/test_bash_evaluation.py
+++ b/yaksh/evaluator_tests/test_bash_evaluation.py
@@ -3,11 +3,9 @@ import unittest
import os
import shutil
import tempfile
-from psutil import Process, pid_exists
+from psutil import Process
# Local Imports
from yaksh.grader import Grader
-from yaksh.bash_code_evaluator import BashCodeEvaluator
-from yaksh.bash_stdio_evaluator import BashStdIOEvaluator
from yaksh.evaluator_tests.test_python_evaluation import EvaluatorBaseTest
from yaksh.settings import SERVER_TIMEOUT
from textwrap import dedent
@@ -25,15 +23,15 @@ class BashAssertionEvaluationTestCases(EvaluatorBaseTest):
self.tc_data_args = "1 2\n2 1"
self.test_case_data = [
{"test_case": self.tc_data,
- "test_case_args": self.tc_data_args,
- "test_case_type": "standardtestcase",
- "weight": 0.0
- }
+ "test_case_args": self.tc_data_args,
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }
]
self.in_dir = tempfile.mkdtemp()
self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your"
- " code.").format(SERVER_TIMEOUT)
+ "You probably have an infinite loop in your"
+ " code.").format(SERVER_TIMEOUT)
self.file_paths = None
def tearDown(self):
@@ -43,16 +41,14 @@ class BashAssertionEvaluationTestCases(EvaluatorBaseTest):
def test_correct_answer(self):
# Given
user_answer = ("#!/bin/bash\n[[ $# -eq 2 ]]"
- " && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))"
- )
- kwargs = {
- 'metadata': {
- 'user_answer': user_answer,
- 'file_paths': self.file_paths,
- 'partial_grading': False,
- 'language': 'bash'
- },
- 'test_case_data': self.test_case_data,
+ " && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))"
+ )
+ kwargs = {'metadata': {
+ 'user_answer': user_answer,
+ 'file_paths': self.file_paths,
+ 'partial_grading': False,
+ 'language': 'bash'
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -62,18 +58,69 @@ class BashAssertionEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get('success'))
+ def test_correct_answer_without_test_case_args(self):
+ # Given
+ user_answer = "echo 'hello'"
+ tc_data = "echo 'hello'"
+ self.test_case_data = [
+ {"test_case": tc_data,
+ "test_case_args": "",
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }
+ ]
+ kwargs = {'metadata': {
+ 'user_answer': user_answer,
+ 'file_paths': self.file_paths,
+ 'partial_grading': False,
+ 'language': 'bash'
+ }, 'test_case_data': self.test_case_data,
+ }
+
+ # When
+ grader = Grader(self.in_dir)
+ result = grader.evaluate(kwargs)
+
+ # Then
+ self.assertTrue(result.get('success'))
+
+ def test_incorrect_answer_without_test_case_args(self):
+ # Given
+ user_answer = "echo 'hello'"
+ tc_data = "echo 'hello world'"
+ self.test_case_data = [
+ {"test_case": tc_data,
+ "test_case_args": "",
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }
+ ]
+ kwargs = {'metadata': {
+ 'user_answer': user_answer,
+ 'file_paths': self.file_paths,
+ 'partial_grading': False,
+ 'language': 'bash'
+ }, 'test_case_data': self.test_case_data,
+ }
+
+ # When
+ grader = Grader(self.in_dir)
+ result = grader.evaluate(kwargs)
+
+ # Then
+ self.assertFalse(result.get('success'))
+
def test_error(self):
# Given
user_answer = ("#!/bin/bash\n[[ $# -eq 2 ]] "
- "&& echo $(( $1 - $2 )) && exit $(( $1 - $2 ))")
+ "&& echo $(( $1 - $2 )) && exit $(( $1 - $2 ))")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -87,15 +134,14 @@ class BashAssertionEvaluationTestCases(EvaluatorBaseTest):
def test_infinite_loop(self):
# Given
user_answer = ("#!/bin/bash\nwhile [ 1 ] ;"
- " do echo "" > /dev/null ; done")
+ " do echo "" > /dev/null ; done")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -120,22 +166,19 @@ class BashAssertionEvaluationTestCases(EvaluatorBaseTest):
cat $1
""")
self.tc_data_args = "test.txt"
- self.test_case_data = [
- {"test_case": self.tc_data,
- "test_case_args": self.tc_data_args,
- "test_case_type": "standardtestcase",
- "weight": 0.0
- }
- ]
+ self.test_case_data = [{
+ "test_case": self.tc_data,
+ "test_case_args": self.tc_data_args,
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }]
user_answer = ("#!/bin/bash\ncat $1")
- kwargs = {
- 'metadata': {
+ kwargs = {'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -145,6 +188,7 @@ class BashAssertionEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get("success"))
+
class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
def setUp(self):
self.in_dir = tempfile.mkdtemp()
@@ -153,7 +197,6 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
" code.").format(SERVER_TIMEOUT)
self.file_paths = None
-
def test_correct_answer(self):
# Given
user_answer = dedent(""" #!/bin/bash
@@ -162,7 +205,8 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
echo -n `expr $A + $B`
"""
)
- test_case_data = [{'expected_output': '11',
+ test_case_data = [{
+ 'expected_output': '11',
'expected_input': '5\n6',
'test_case_type': 'stdiobasedtestcase',
'weight': 0.0
@@ -173,8 +217,7 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -190,14 +233,14 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
COUNTER=0
while [ $COUNTER -lt 3 ]; do
echo -n "${arr[$COUNTER]}"
- let COUNTER=COUNTER+1
+ let COUNTER=COUNTER+1
done
"""
)
test_case_data = [{'expected_output': '1 2 3\n4 5 6\n7 8 9\n',
- 'expected_input': '1,2,3\n4,5,6\n7,8,9',
- 'test_case_type': 'stdiobasedtestcase',
- 'weight': 0.0
+ 'expected_input': '1,2,3\n4,5,6\n7,8,9',
+ 'test_case_type': 'stdiobasedtestcase',
+ 'weight': 0.0
}]
kwargs = {
'metadata': {
@@ -205,8 +248,7 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -224,7 +266,8 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
echo -n `expr $A - $B`
"""
)
- test_case_data = [{'expected_output': '11',
+ test_case_data = [{
+ 'expected_output': '11',
'expected_input': '5\n6',
'test_case_type': 'stdiobasedtestcase',
'weight': 0.0
@@ -235,8 +278,7 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -266,8 +308,7 @@ class BashStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -286,8 +327,8 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
f.write('2'.encode('ascii'))
self.in_dir = tempfile.mkdtemp()
self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your"
- " code.").format(SERVER_TIMEOUT)
+ "You probably have an infinite loop in your"
+ " code.").format(SERVER_TIMEOUT)
self.file_paths = None
def tearDown(self):
@@ -306,28 +347,26 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
success = False
err = "Incorrect Answer"
mark_fraction = 0.0
- proc = subprocess.Popen(user_answer, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ user_answer, shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0}]
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -349,20 +388,18 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
success = False
err = "Incorrect Answer"
mark_fraction = 0.0
- proc = subprocess.Popen(user_answer, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ user_answer, shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
-
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0}]
kwargs = {
'metadata': {
@@ -370,8 +407,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -381,7 +417,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertFalse(result.get('success'))
self.assert_correct_output('Incorrect Answer', result.get('error'))
-
+
def test_assert_with_hook(self):
# Given
user_answer = ("#!/bin/bash\n[[ $# -eq 2 ]]"
@@ -393,7 +429,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
""")
assert_test_case_args = "1 2\n2 1"
-
+
hook_code = dedent("""\
def check_answer(user_answer):
success = False
@@ -402,13 +438,11 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
if "echo $(( $1 + $2 ))" in user_answer:
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
-
+ """)
test_case_data = [{"test_case_type": "standardtestcase",
"test_case": assert_test_case,
- "test_case_args":assert_test_case_args,
+ "test_case_args": assert_test_case_args,
'weight': 1.0
},
{"test_case_type": "hooktestcase",
@@ -420,8 +454,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': True,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -438,7 +471,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
echo -n Hello, world!
"""
)
-
+
hook_code_1 = dedent("""\
def check_answer(user_answer):
success = False
@@ -447,8 +480,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
if "echo -n Hello, world!" in user_answer:
success, err, mark_fraction = True, "", 0.5
return success, err, mark_fraction
- """
- )
+ """)
hook_code_2 = dedent("""\
def check_answer(user_answer):
import subprocess
@@ -465,9 +497,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode('utf-8') == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
-
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
"hook_code": hook_code_1, 'weight': 1.0},
@@ -480,8 +510,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': True,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -491,7 +520,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get('success'))
self.assertEqual(result.get("weight"), 1.5)
-
+
def test_infinite_loop(self):
# Given
user_answer = ("#!/bin/bash\nwhile [ 1 ] ;"
@@ -503,21 +532,19 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
success = False
err = "Incorrect Answer"
mark_fraction = 0.0
- proc = subprocess.Popen(user_answer, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ user_answer, shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
-
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0}]
kwargs = {
'metadata': {
@@ -525,8 +552,7 @@ class BashHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'bash'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
diff --git a/yaksh/evaluator_tests/test_c_cpp_evaluation.py b/yaksh/evaluator_tests/test_c_cpp_evaluation.py
index 162d90c..5b49671 100644
--- a/yaksh/evaluator_tests/test_c_cpp_evaluation.py
+++ b/yaksh/evaluator_tests/test_c_cpp_evaluation.py
@@ -8,8 +8,6 @@ from psutil import Process
# Local import
from yaksh.grader import Grader
-from yaksh.cpp_code_evaluator import CppCodeEvaluator
-from yaksh.cpp_stdio_evaluator import CppStdIOEvaluator
from yaksh.evaluator_tests.test_python_evaluation import EvaluatorBaseTest
from yaksh.settings import SERVER_TIMEOUT
@@ -60,8 +58,8 @@ class CAssertionEvaluationTestCases(EvaluatorBaseTest):
}]
self.in_dir = tmp_in_dir_path
self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your"
- " code.").format(SERVER_TIMEOUT)
+ "You probably have an infinite loop in your"
+ " code.").format(SERVER_TIMEOUT)
self.file_paths = None
def tearDown(self):
@@ -77,8 +75,7 @@ class CAssertionEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -97,8 +94,7 @@ class CAssertionEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -120,8 +116,7 @@ class CAssertionEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -141,8 +136,7 @@ class CAssertionEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -211,8 +205,7 @@ class CAssertionEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -222,6 +215,71 @@ class CAssertionEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get('success'))
+ def test_incorrect_testcase(self):
+ # Given
+ self.tc_data = dedent("""
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ extern int add(int, int);
+
+ template <class T>
+
+ void check(T expect, T result)
+ {
+ if (expect == result)
+ {
+ printf("Correct: Expected %d got %d ",expect,result);
+ }
+ else
+ {
+ printf("Incorrect: Expected %d got %d ",expect,result);
+ exit (1);
+ }
+ }
+
+ int main(void)
+ {
+ int result;
+ result = add(0,0);
+ printf("Input submitted to the function: 0, 0");
+ check(0, result);
+ result = add(2,3);
+ printf("Input submitted to the function: 2 3");
+ check(5,result)
+ printf("All Correct");
+ return 0;
+ }
+ """)
+ user_answer = dedent("""\
+ int add(int a, int b)
+ {
+ return a+b;
+ }""")
+ self.test_case_data = [{"test_case": self.tc_data,
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }]
+ kwargs = {
+ 'metadata': {
+ 'user_answer': user_answer,
+ 'file_paths': self.file_paths,
+ 'partial_grading': False,
+ 'language': 'cpp'
+ }, 'test_case_data': self.test_case_data,
+ }
+
+ # When
+ grader = Grader(self.in_dir)
+ result = grader.evaluate(kwargs)
+
+ # Then
+ err = result.get('error')[0]
+ lines_of_error = len(err.splitlines())
+ self.assertFalse(result.get('success'))
+ self.assertTrue(lines_of_error > 1)
+ self.assertIn("Test case Error", err)
+
class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
def setUp(self):
@@ -254,8 +312,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -287,8 +344,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -318,8 +374,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -343,8 +398,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -372,8 +426,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -398,8 +451,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -434,8 +486,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -461,8 +512,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -495,8 +545,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -527,8 +576,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -553,8 +601,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -583,8 +630,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -610,8 +656,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -644,8 +689,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -655,6 +699,7 @@ class CppStdIOEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get('success'))
+
class CppHookEvaluationTestCases(EvaluatorBaseTest):
def setUp(self):
@@ -664,8 +709,8 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
tmp_in_dir_path = tempfile.mkdtemp()
self.in_dir = tmp_in_dir_path
self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your"
- " code.").format(SERVER_TIMEOUT)
+ "You probably have an infinite loop in your"
+ " code.").format(SERVER_TIMEOUT)
self.file_paths = None
def tearDown(self):
@@ -703,20 +748,17 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0}]
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -744,11 +786,11 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
err = "Incorrect Answer"
mark_fraction = 0.0
def _run_command(cmd):
- proc = subprocess.Popen("{}".format(cmd),
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ "{}".format(cmd), shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
return stdout,stderr
cmds = ["gcc Test.c", "./a.out"]
@@ -757,20 +799,17 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0}]
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -780,46 +819,47 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertFalse(result.get('success'))
self.assert_correct_output('Incorrect Answer', result.get('error'))
-
+
def test_assert_with_hook(self):
# Given
user_answer = "int add(int a, int b)\n{return a+b;}"
-
assert_test_case = dedent("""\
- #include <stdio.h>
- #include <stdlib.h>
-
- extern int add(int, int);
-
- template <class T>
-
- void check(T expect, T result)
- {
- if (expect == result)
- {
- printf("Correct: Expected %d got %d ",expect,result);
- }
- else
- {
- printf("Incorrect: Expected %d got %d ",expect,result);
- exit (1);
- }
- }
-
- int main(void)
- {
- int result;
- result = add(0,0);
- printf("Input submitted to the function: 0, 0");
- check(0, result);
- result = add(2,3);
- printf("Input submitted to the function: 2 3");
- check(5,result);
- printf("All Correct");
- return 0;
- }
- """)
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ extern int add(int, int);
+
+ template <class T>
+
+ void check(T expect, T result)
+ {
+ if (expect == result)
+ {
+ printf("Correct: Expected %d got %d ",
+ expect,result);
+ }
+ else
+ {
+ printf("Incorrect: Expected %d got %d ",
+ expect,result);
+ exit (1);
+ }
+ }
+
+ int main(void)
+ {
+ int result;
+ result = add(0,0);
+ printf("Input submitted 0, 0");
+ check(0, result);
+ result = add(2,3);
+ printf("Input submitted 2 3");
+ check(5,result);
+ printf("All Correct");
+ return 0;
+ }
+ """)
hook_code = dedent("""\
def check_answer(user_answer):
@@ -829,9 +869,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
if "return a+b;" in user_answer:
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
-
+ """)
test_case_data = [{"test_case_type": "standardtestcase",
"test_case": assert_test_case,
@@ -846,8 +884,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': True,
'language': 'cpp'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -867,7 +904,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
printf("Hello, world!");
}
""")
-
+
hook_code_1 = dedent("""\
def check_answer(user_answer):
with open("Test.c", "w+") as f:
@@ -877,11 +914,11 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
err = "Incorrect Answer"
mark_fraction = 0.0
def _run_command(cmd):
- proc = subprocess.Popen("{}".format(cmd),
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ "{}".format(cmd), shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
return stdout,stderr
cmds = ["gcc Test.c", "./a.out"]
@@ -890,8 +927,8 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
+
hook_code_2 = dedent("""\
def check_answer(user_answer):
success = False
@@ -900,10 +937,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
if 'printf("Hello, world!");' in user_answer:
success, err, mark_fraction = True, "", 0.5
return success, err, mark_fraction
- """
- )
-
-
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
"hook_code": hook_code_1, 'weight': 1.0},
@@ -916,8 +950,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': True,
'language': 'cpp'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -927,7 +960,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get('success'))
self.assertEqual(result.get("weight"), 1.5)
-
+
def test_infinite_loop(self):
# Given
user_answer = dedent("""\
@@ -937,7 +970,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
printf("abc");}
}""")
- hook_code= dedent("""\
+ hook_code = dedent("""\
def check_answer(user_answer):
with open("Test.c", "w+") as f:
f.write(user_answer)
@@ -946,11 +979,11 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
err = "Incorrect Answer"
mark_fraction = 0.0
def _run_command(cmd):
- proc = subprocess.Popen("{}".format(cmd),
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ "{}".format(cmd), shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
return stdout,stderr
cmds = ["gcc Test.c", "./a.out"]
@@ -959,12 +992,10 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
-
+ """)
+
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0}]
kwargs = {
'metadata': {
@@ -972,8 +1003,7 @@ class CppHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'cpp'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
diff --git a/yaksh/evaluator_tests/test_grader_evaluation.py b/yaksh/evaluator_tests/test_grader_evaluation.py
index d11f4a0..6a05e19 100644
--- a/yaksh/evaluator_tests/test_grader_evaluation.py
+++ b/yaksh/evaluator_tests/test_grader_evaluation.py
@@ -1,9 +1,8 @@
from __future__ import unicode_literals
import unittest
-import os
from yaksh import python_assertion_evaluator
from yaksh.language_registry import _LanguageRegistry, get_registry
-from yaksh.settings import SERVER_TIMEOUT, code_evaluators
+from yaksh.settings import code_evaluators
class RegistryTestCase(unittest.TestCase):
@@ -11,32 +10,33 @@ class RegistryTestCase(unittest.TestCase):
self.registry_object = get_registry()
self.language_registry = _LanguageRegistry()
assertion_evaluator_path = ("yaksh.python_assertion_evaluator"
- ".PythonAssertionEvaluator"
- )
+ ".PythonAssertionEvaluator"
+ )
stdio_evaluator_path = ("yaksh.python_stdio_evaluator."
- "PythonStdIOEvaluator"
- )
+ "PythonStdIOEvaluator"
+ )
hook_evaluator_path = ("yaksh.hook_evaluator."
- "HookEvaluator"
- )
+ "HookEvaluator"
+ )
code_evaluators['python'] = \
- {"standardtestcase": assertion_evaluator_path,
- "stdiobasedtestcase": stdio_evaluator_path,
- "hooktestcase": hook_evaluator_path
- }
+ {"standardtestcase": assertion_evaluator_path,
+ "stdiobasedtestcase": stdio_evaluator_path,
+ "hooktestcase": hook_evaluator_path
+ }
def test_set_register(self):
- evaluator_class = self.registry_object.get_class("python",
- "standardtestcase"
+ evaluator_class = self.registry_object.get_class(
+ "python", "standardtestcase"
)
- class_name = getattr(python_assertion_evaluator,
- 'PythonAssertionEvaluator'
+ class_name = getattr(
+ python_assertion_evaluator, 'PythonAssertionEvaluator'
)
self.assertEqual(evaluator_class, class_name)
def tearDown(self):
self.registry_object = None
+
if __name__ == '__main__':
unittest.main()
diff --git a/yaksh/evaluator_tests/test_java_evaluation.py b/yaksh/evaluator_tests/test_java_evaluation.py
index 35b64d0..ab86dec 100644
--- a/yaksh/evaluator_tests/test_java_evaluation.py
+++ b/yaksh/evaluator_tests/test_java_evaluation.py
@@ -4,15 +4,12 @@ import os
import shutil
import tempfile
from textwrap import dedent
-from psutil import Process, pid_exists
-import time
+from psutil import Process
# Local Import
from yaksh import grader as gd
from yaksh.grader import Grader
-from yaksh.java_code_evaluator import JavaCodeEvaluator
-from yaksh.java_stdio_evaluator import JavaStdIOEvaluator
from yaksh.evaluator_tests.test_python_evaluation import EvaluatorBaseTest
@@ -29,11 +26,13 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
{
if(result.equals(expect))
{
- System.out.println("Correct:Output expected "+expect+" and got "+result);
+ System.out.println("Correct:Output expected "+expect+
+ "and got "+result);
}
else
{
- System.out.println("Incorrect:Output expected "+expect+" but got "+result);
+ System.out.println("Incorrect:Output expected "+expect+
+ "but got "+result);
System.exit(1);
}
}
@@ -43,15 +42,18 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
int result, input, output;
input = 0; output = 0;
result = t.square_num(input);
- System.out.println("Input submitted to the function: "+input);
+ System.out.println("Input submitted to the function: "+
+ input);
check(output, result);
input = 5; output = 25;
result = t.square_num(input);
- System.out.println("Input submitted to the function: "+input);
+ System.out.println("Input submitted to the function: "+
+ input);
check(output, result);
input = 6; output = 36;
result = t.square_num(input);
- System.out.println("Input submitted to the function: "+input);
+ System.out.println("Input submitted to the function: "+
+ input);
check(output, result);
}
}
@@ -59,17 +61,16 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
self.test_case_data = [
{"test_case": self.tc_data,
- "test_case_type": "standardtestcase",
- "weight": 0.0
- }
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }
]
self.in_dir = tmp_in_dir_path
self.file_paths = None
gd.SERVER_TIMEOUT = 9
self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in"
- " your code.").format(gd.SERVER_TIMEOUT)
-
+ "You probably have an infinite loop in"
+ " your code.").format(gd.SERVER_TIMEOUT)
def tearDown(self):
gd.SERVER_TIMEOUT = 4
@@ -78,15 +79,15 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
def test_correct_answer(self):
# Given
- user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a;\n\t}\n}"
+ user_answer = ("class Test {\n\tint square_num(int a)"
+ " {\n\treturn a*a;\n\t}\n}")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -98,15 +99,15 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
def test_incorrect_answer(self):
# Given
- user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a;\n\t}\n}"
+ user_answer = ("class Test {\n\tint square_num(int a) "
+ "{\n\treturn a;\n\t}\n}")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -122,15 +123,14 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
def test_error(self):
# Given
- user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a"
+ user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a}"
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -143,15 +143,15 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
def test_infinite_loop(self):
# Given
- user_answer = "class Test {\n\tint square_num(int a) {\n\t\twhile(0==0){\n\t\t}\n\t}\n}"
+ user_answer = ("class Test {\n\tint square_num(int a)"
+ " {\n\t\twhile(0==0){\n\t\t}\n\t}\n}")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -178,11 +178,13 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
{
if(result.equals(expect))
{
- System.out.println("Correct:Output expected "+expect+" and got "+result);
+ System.out.println("Correct:Output expected "+expect+
+ " and got "+result);
}
else
{
- System.out.println("Incorrect:Output expected "+expect+" but got "+result);
+ System.out.println("Incorrect:Output expected "+expect+
+ " but got "+result);
System.exit(1);
}
}
@@ -201,9 +203,9 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
""")
self.test_case_data = [
{"test_case": self.tc_data,
- "test_case_type": "standardtestcase",
- "weight": 0.0
- }
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }
]
user_answer = dedent("""
import java.io.BufferedReader;
@@ -229,8 +231,7 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -240,6 +241,64 @@ class JavaAssertionEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get("success"))
+ def test_incorrect_testcase(self):
+ # Given
+ self.tc_data = dedent("""
+ class main
+ {
+ public static <E> void check(E expect, E result)
+ {
+ if(result.equals(expect))
+ {
+ System.out.println("Correct:Output expected "+expect+
+ "and got "+result);
+ }
+ else
+ {
+ System.out.println("Incorrect:Output expected "+expect+
+ "but got "+result);
+ System.exit(1);
+ }
+ }
+ public static void main(String arg[])
+ {
+ Test t = new Test();
+ int result, input, output;
+ input = 0; output = 0;
+ result = t.square_num(input);
+ System.out.println("Input submitted to the function: "+
+ input);
+ check(output, result)
+ }
+ }
+ """)
+ user_answer = ("class Test {\n\tint square_num(int a) "
+ "{\n\treturn a;\n\t}\n}")
+ self.test_case_data = [{"test_case": self.tc_data,
+ "test_case_type": "standardtestcase",
+ "weight": 0.0
+ }]
+ kwargs = {
+ 'metadata': {
+ 'user_answer': user_answer,
+ 'file_paths': self.file_paths,
+ 'partial_grading': False,
+ 'language': 'java'
+ }, 'test_case_data': self.test_case_data,
+ }
+
+ # When
+ grader = Grader(self.in_dir)
+ result = grader.evaluate(kwargs)
+
+ # Then
+ err = result.get('error')[0]
+ lines_of_error = len(err.splitlines())
+ self.assertFalse(result.get('success'))
+ self.assertTrue(lines_of_error > 1)
+ self.assertIn("Test case Error", err)
+
+
class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
def setUp(self):
self.f_path = os.path.join(tempfile.gettempdir(), "test.txt")
@@ -251,7 +310,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'expected_input': '5\n6',
'test_case_type': 'stdiobasedtestcase',
'weight': 0.0
- }]
+ }]
self.file_paths = None
gd.SERVER_TIMEOUT = 9
self.timeout_msg = ("Code took more than {0} seconds to run. "
@@ -280,8 +339,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -314,8 +372,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -342,8 +399,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -370,8 +426,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -397,8 +452,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -420,7 +474,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
self.test_case_data = [{'expected_output': '11',
'test_case_type': 'stdiobasedtestcase',
'weight': 0.0
- }]
+ }]
user_answer = dedent("""
class Test
{public static void main(String[] args){
@@ -434,8 +488,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -451,7 +504,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'expected_input': 'Hello\nWorld',
'test_case_type': 'stdiobasedtestcase',
'weight': 0.0
- }]
+ }]
user_answer = dedent("""
import java.util.Scanner;
class Test
@@ -467,8 +520,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -485,7 +537,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'expected_input': '',
'test_case_type': 'stdiobasedtestcase',
'weight': 0.0
- }]
+ }]
user_answer = dedent("""
import java.io.BufferedReader;
import java.io.FileReader;
@@ -510,8 +562,7 @@ class JavaStdIOEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
# When
@@ -533,8 +584,8 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
self.file_paths = None
gd.SERVER_TIMEOUT = 9
self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in"
- " your code.").format(gd.SERVER_TIMEOUT)
+ "You probably have an infinite loop in"
+ " your code.").format(gd.SERVER_TIMEOUT)
def tearDown(self):
gd.SERVER_TIMEOUT = 4
@@ -558,11 +609,11 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
err = "Incorrect Answer"
mark_fraction = 0.0
def _run_command(cmd):
- proc = subprocess.Popen("{}".format(cmd),
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ "{}".format(cmd), shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
return stdout,stderr
cmds = ["javac Test.java", "java Test"]
@@ -571,20 +622,18 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0
+ }]
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -624,20 +673,18 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0
+ }]
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -647,10 +694,11 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertFalse(result.get('success'))
self.assert_correct_output('Incorrect Answer', result.get('error'))
-
+
def test_assert_with_hook(self):
# Given
- user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a;\n\t}\n}"
+ user_answer = ("class Test {\n\tint square_num(int a)"
+ " {\n\treturn a*a;\n\t}\n}")
assert_test_case = dedent("""
class main
{
@@ -658,11 +706,13 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
{
if(result.equals(expect))
{
- System.out.println("Correct:Output expected "+expect+" and got "+result);
+ System.out.println("Correct:Output expected "+expect+
+ " and got "+result);
}
else
{
- System.out.println("Incorrect:Output expected "+expect+" but got "+result);
+ System.out.println("Incorrect:Output expected "+expect+
+ " but got "+result);
System.exit(1);
}
}
@@ -672,20 +722,23 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
int result, input, output;
input = 0; output = 0;
result = t.square_num(input);
- System.out.println("Input submitted to the function: "+input);
+ System.out.println("Input submitted to the function: "+
+ input);
check(output, result);
input = 5; output = 25;
result = t.square_num(input);
- System.out.println("Input submitted to the function: "+input);
+ System.out.println("Input submitted to the function: "+
+ input);
check(output, result);
input = 6; output = 36;
result = t.square_num(input);
- System.out.println("Input submitted to the function: "+input);
+ System.out.println("Input submitted to the function: "+
+ input);
check(output, result);
}
}
""")
-
+
hook_code = dedent("""\
def check_answer(user_answer):
success = False
@@ -694,9 +747,7 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
if "return a*a" in user_answer:
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
-
+ """)
test_case_data = [{"test_case_type": "standardtestcase",
"test_case": assert_test_case,
@@ -711,8 +762,7 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': True,
'language': 'java'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -731,7 +781,7 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
System.out.print("Hello, world!");
}}
""")
-
+
hook_code_1 = dedent("""\
def check_answer(user_answer):
with open("Test.java", "w+") as f:
@@ -741,11 +791,11 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
err = "Incorrect Answer"
mark_fraction = 0.0
def _run_command(cmd):
- proc = subprocess.Popen("{}".format(cmd),
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ "{}".format(cmd), shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
return stdout,stderr
cmds = ["javac Test.java", "java Test"]
@@ -754,20 +804,18 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
hook_code_2 = dedent("""\
def check_answer(user_answer):
success = False
err = "Incorrect Answer"
mark_fraction = 0.0
- if 'System.out.print("Hello, world!");' in user_answer:
+ if ('System.out.print("Hello, world!");' in
+ user_answer):
success, err, mark_fraction = True, "", 0.5
return success, err, mark_fraction
- """
- )
-
+ """)
test_case_data = [{"test_case_type": "hooktestcase",
"hook_code": hook_code_1, 'weight': 1.0},
@@ -780,8 +828,7 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': True,
'language': 'java'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
@@ -791,7 +838,7 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
# Then
self.assertTrue(result.get('success'))
self.assertEqual(result.get("weight"), 1.5)
-
+
def test_infinite_loop(self):
# Given
user_answer = dedent("""\
@@ -811,11 +858,11 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
err = "Incorrect Answer"
mark_fraction = 0.0
def _run_command(cmd):
- proc = subprocess.Popen("{}".format(cmd),
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
+ proc = subprocess.Popen(
+ "{}".format(cmd), shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
stdout,stderr = proc.communicate()
return stdout,stderr
cmds = ["javac Test.java", "java Test"]
@@ -824,13 +871,11 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
if stdout.decode("utf-8") == "Hello, world!":
success, err, mark_fraction = True, "", 1.0
return success, err, mark_fraction
- """
- )
+ """)
-
test_case_data = [{"test_case_type": "hooktestcase",
- "hook_code": hook_code,"weight": 1.0
- }]
+ "hook_code": hook_code, "weight": 1.0
+ }]
kwargs = {
'metadata': {
@@ -838,8 +883,7 @@ class JavaHookEvaluationTestCases(EvaluatorBaseTest):
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'java'
- },
- 'test_case_data': test_case_data,
+ }, 'test_case_data': test_case_data,
}
# When
diff --git a/yaksh/evaluator_tests/test_python_stdio_evaluator.py b/yaksh/evaluator_tests/test_python_stdio_evaluator.py
index 9b8d702..db2fd69 100644
--- a/yaksh/evaluator_tests/test_python_stdio_evaluator.py
+++ b/yaksh/evaluator_tests/test_python_stdio_evaluator.py
@@ -1,5 +1,6 @@
from yaksh.error_messages import compare_outputs
+
def test_compare_outputs():
exp = "5\n5\n"
given = "5\n5\n"
@@ -26,8 +27,8 @@ def test_compare_outputs():
success, msg = compare_outputs(given, exp)
error_msg = msg.get('error_msg')
assert not success
- m = ("Incorrect Answer: We had expected 1 number of lines. "
- + "We got 2 number of lines.")
+ m = ("Incorrect Answer: We had expected 1 number of lines. " +
+ "We got 2 number of lines.")
assert m == error_msg
exp = "5\n5\n"
diff --git a/yaksh/evaluator_tests/test_scilab_evaluation.py b/yaksh/evaluator_tests/test_scilab_evaluation.py
index f7a9925..d3f1dc8 100644
--- a/yaksh/evaluator_tests/test_scilab_evaluation.py
+++ b/yaksh/evaluator_tests/test_scilab_evaluation.py
@@ -6,12 +6,12 @@ import tempfile
from psutil import Process
from textwrap import dedent
-#Local Import
+# Local Import
from yaksh import grader as gd
from yaksh.grader import Grader
-from yaksh.scilab_code_evaluator import ScilabCodeEvaluator
from yaksh.evaluator_tests.test_python_evaluation import EvaluatorBaseTest
+
class ScilabEvaluationTestCases(EvaluatorBaseTest):
def setUp(self):
tmp_in_dir_path = tempfile.mkdtemp()
@@ -54,7 +54,7 @@ class ScilabEvaluationTestCases(EvaluatorBaseTest):
self.file_paths = None
gd.SERVER_TIMEOUT = 9
self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop"
+ "You probably have an infinite loop"
" in your code.").format(gd.SERVER_TIMEOUT)
def tearDown(self):
@@ -63,15 +63,14 @@ class ScilabEvaluationTestCases(EvaluatorBaseTest):
def test_correct_answer(self):
user_answer = ("funcprot(0)\nfunction[c]=add(a,b)"
- "\n\tc=a+b;\nendfunction")
+ "\n\tc=a+b;\nendfunction")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'scilab'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
grader = Grader(self.in_dir)
@@ -81,15 +80,14 @@ class ScilabEvaluationTestCases(EvaluatorBaseTest):
def test_error(self):
user_answer = ("funcprot(0)\nfunction[c]=add(a,b)"
- "\n\tc=a+b;\ndis(\tendfunction")
+ "\n\tc=a+b;\ndis(\tendfunction")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'scilab'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
grader = Grader(self.in_dir)
@@ -98,18 +96,16 @@ class ScilabEvaluationTestCases(EvaluatorBaseTest):
self.assertFalse(result.get("success"))
self.assert_correct_output('error', result.get("error"))
-
def test_incorrect_answer(self):
user_answer = ("funcprot(0)\nfunction[c]=add(a,b)"
- "\n\tc=a-b;\nendfunction")
+ "\n\tc=a-b;\nendfunction")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'scilab'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
grader = Grader(self.in_dir)
@@ -122,15 +118,14 @@ class ScilabEvaluationTestCases(EvaluatorBaseTest):
def test_infinite_loop(self):
user_answer = ("funcprot(0)\nfunction[c]=add(a,b)"
- "\n\tc=a;\nwhile(1==1)\nend\nendfunction")
+ "\n\tc=a;\nwhile(1==1)\nend\nendfunction")
kwargs = {
'metadata': {
'user_answer': user_answer,
'file_paths': self.file_paths,
'partial_grading': False,
'language': 'scilab'
- },
- 'test_case_data': self.test_case_data,
+ }, 'test_case_data': self.test_case_data,
}
grader = Grader(self.in_dir)
diff --git a/yaksh/evaluator_tests/test_simple_question_types.py b/yaksh/evaluator_tests/test_simple_question_types.py
index dfb82a2..f7a6cf6 100644
--- a/yaksh/evaluator_tests/test_simple_question_types.py
+++ b/yaksh/evaluator_tests/test_simple_question_types.py
@@ -4,7 +4,7 @@ from django.utils import timezone
from textwrap import dedent
import pytz
from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\
- QuestionSet, AnswerPaper, Answer, Course, IntegerTestCase, FloatTestCase,\
+ AnswerPaper, Answer, Course, IntegerTestCase, FloatTestCase,\
StringTestCase, McqTestCase, ArrangeTestCase
@@ -19,34 +19,30 @@ def setUpModule():
institute='IIT', department='Aerospace',
position='Student')
# Create User 2
- user2 = User.objects.create_user(username='demo_user_101',
- password='demo',
- email='demo@test.com')
+ user2 = User.objects.create_user(
+ username='demo_user_101', password='demo',
+ email='demo@test.com')
Profile.objects.create(user=user2, roll_number=2,
institute='IIT', department='Aerospace',
position='Student')
-
+
# Create a course
- course = Course.objects.create(name="Python Course 100",
- enrollment="Enroll Request", creator=user)
-
- quiz = Quiz.objects.create(start_date_time=datetime\
- (2015, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc),
- end_date_time=datetime\
- (2199, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc),
- duration=30, active=True, attempts_allowed=1,
- time_between_attempts=0, pass_criteria=0,
- description='demo quiz 100',
- instructions="Demo Instructions",
- creator=user
- )
- question_paper = QuestionPaper.objects.create(quiz=quiz,
- total_marks=1.0)
-
-
+ Course.objects.create(name="Python Course 100",
+ enrollment="Enroll Request", creator=user)
+
+ quiz = Quiz.objects.create(
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ duration=30, active=True, attempts_allowed=1,
+ time_between_attempts=0, pass_criteria=0,
+ description='demo quiz 100',
+ instructions="Demo Instructions",
+ creator=user
+ )
+ QuestionPaper.objects.create(quiz=quiz, total_marks=1.0)
+
+
def tearDownModule():
User.objects.filter(username__in=["demo_user_100", "demo_user_101"])\
.delete()
@@ -62,10 +58,10 @@ class IntegerQuestionTestCases(unittest.TestCase):
# Creating Question paper
self.question_paper = QuestionPaper.objects.get(quiz=self.quiz)
- #Creating User
+ # Creating User
self.user = User.objects.get(username='demo_user_100')
- #Creating Question
+ # Creating Question
self.question1 = Question.objects.create(summary='int1', points=1,
type='code', user=self.user)
self.question1.language = 'python'
@@ -74,30 +70,26 @@ class IntegerQuestionTestCases(unittest.TestCase):
self.question1.description = 'sum of 12+13?'
self.question1.save()
- #Creating answerpaper
-
- self.answerpaper = AnswerPaper.objects.create(user=self.user,
- user_ip='101.0.0.1',
- start_time=timezone.now(),
- question_paper=self.question_paper,
- end_time=timezone.now()
- +timedelta(minutes=5),
- attempt_number=1,
- course=self.course
- )
+ # Creating answerpaper
+
+ self.answerpaper = AnswerPaper.objects.create(
+ user=self.user, user_ip='101.0.0.1', start_time=timezone.now(),
+ question_paper=self.question_paper, course=self.course,
+ end_time=timezone.now()+timedelta(minutes=5), attempt_number=1
+ )
self.answerpaper.questions.add(self.question1)
self.answerpaper.save()
- # For question
+ # For question
self.integer_based_testcase = IntegerTestCase(question=self.question1,
correct=25,
- type = 'integertestcase',
+ type='integertestcase',
)
self.integer_based_testcase.save()
@classmethod
def tearDownClass(self):
- self.question1.delete()
- self.answerpaper.delete()
+ self.question1.delete()
+ self.answerpaper.delete()
def test_validate_regrade_integer_correct_answer(self):
# Given
@@ -118,7 +110,7 @@ class IntegerQuestionTestCases(unittest.TestCase):
self.assertTrue(result['success'])
# Regrade
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=self.answer.id)
regrade_answer.answer = 200
regrade_answer.save()
@@ -134,7 +126,6 @@ class IntegerQuestionTestCases(unittest.TestCase):
self.assertEqual(self.answer.marks, 0)
self.assertFalse(self.answer.correct)
-
def test_validate_regrade_integer_incorrect_answer(self):
# Given
integer_answer = 26
@@ -154,7 +145,7 @@ class IntegerQuestionTestCases(unittest.TestCase):
self.assertFalse(result['success'])
# Regrade
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=self.answer.id)
regrade_answer.answer = 25
regrade_answer.save()
@@ -180,9 +171,9 @@ class StringQuestionTestCases(unittest.TestCase):
self.quiz = Quiz.objects.get(description="demo quiz 100")
# Creating Question paper
self.question_paper = QuestionPaper.objects.get(quiz=self.quiz)
- #Creating User
+ # Creating User
self.user = User.objects.get(username='demo_user_100')
- #Creating Question
+ # Creating Question
self.question1 = Question.objects.create(summary='str1', points=1,
type='code', user=self.user)
self.question1.language = 'python'
@@ -199,45 +190,41 @@ class StringQuestionTestCases(unittest.TestCase):
self.question2.description = 'Write Hello, EARTH!'
self.question2.save()
- #Creating answerpaper
-
- self.answerpaper = AnswerPaper.objects.create(user=self.user,
- user_ip='101.0.0.1',
- start_time=timezone.now(),
- question_paper=self.question_paper,
- end_time=timezone.now()
- +timedelta(minutes=5),
- attempt_number=1,
- course=self.course
- )
+ # Creating answerpaper
+
+ self.answerpaper = AnswerPaper.objects.create(
+ user=self.user, user_ip='101.0.0.1', start_time=timezone.now(),
+ question_paper=self.question_paper, course=self.course,
+ end_time=timezone.now()+timedelta(minutes=5), attempt_number=1
+ )
self.answerpaper.questions.add(*[self.question1, self.question2])
self.answerpaper.save()
- # For question
+ # For question
self.lower_string_testcase = StringTestCase(question=self.question1,
correct="Hello, EARTH!",
string_check="lower",
- type = 'stringtestcase',
+ type='stringtestcase',
)
self.lower_string_testcase.save()
self.exact_string_testcase = StringTestCase(question=self.question2,
correct="Hello, EARTH!",
string_check="exact",
- type = 'stringtestcase',
+ type='stringtestcase',
)
self.exact_string_testcase.save()
@classmethod
def tearDownClass(self):
- self.question1.delete()
- self.question2.delete()
- self.answerpaper.delete()
+ self.question1.delete()
+ self.question2.delete()
+ self.answerpaper.delete()
def test_validate_regrade_case_insensitive_string_correct_answer(self):
# Given
string_answer = "hello, earth!"
- answer = Answer(question=self.question1,answer=string_answer)
+ answer = Answer(question=self.question1, answer=string_answer)
answer.save()
self.answerpaper.answers.add(answer)
@@ -250,7 +237,7 @@ class StringQuestionTestCases(unittest.TestCase):
self.assertTrue(result['success'])
# Regrade
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=answer.id)
regrade_answer.answer = "hello, mars!"
regrade_answer.save()
@@ -259,8 +246,8 @@ class StringQuestionTestCases(unittest.TestCase):
details = self.answerpaper.regrade(self.question1.id)
# Then
- answer = self.answerpaper.answers.filter(question=self.question1)\
- .last()
+ answer = self.answerpaper.answers.filter(
+ question=self.question1).last()
self.assertEqual(answer, regrade_answer)
self.assertTrue(details[0])
self.assertEqual(answer.marks, 0)
@@ -269,7 +256,7 @@ class StringQuestionTestCases(unittest.TestCase):
def test_validate_regrade_case_insensitive_string_incorrect_answer(self):
# Given
string_answer = "hello, mars!"
- answer = Answer(question=self.question1,answer=string_answer)
+ answer = Answer(question=self.question1, answer=string_answer)
answer.save()
self.answerpaper.answers.add(answer)
@@ -283,7 +270,7 @@ class StringQuestionTestCases(unittest.TestCase):
self.assertFalse(result['success'])
# Regrade
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=answer.id)
regrade_answer.answer = "hello, earth!"
regrade_answer.save()
@@ -292,8 +279,8 @@ class StringQuestionTestCases(unittest.TestCase):
details = self.answerpaper.regrade(self.question1.id)
# Then
- answer = self.answerpaper.answers.filter(question=self.question1)\
- .last()
+ answer = self.answerpaper.answers.filter(
+ question=self.question1).last()
self.assertEqual(answer, regrade_answer)
self.assertTrue(details[0])
self.assertEqual(answer.marks, 1)
@@ -302,7 +289,7 @@ class StringQuestionTestCases(unittest.TestCase):
def test_validate_regrade_case_sensitive_string_correct_answer(self):
# Given
string_answer = "Hello, EARTH!"
- answer = Answer(question=self.question2,answer=string_answer)
+ answer = Answer(question=self.question2, answer=string_answer)
answer.save()
self.answerpaper.answers.add(answer)
@@ -315,7 +302,7 @@ class StringQuestionTestCases(unittest.TestCase):
self.assertTrue(result['success'])
# Regrade
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=answer.id)
regrade_answer.answer = "hello, earth!"
regrade_answer.save()
@@ -324,8 +311,8 @@ class StringQuestionTestCases(unittest.TestCase):
details = self.answerpaper.regrade(self.question2.id)
# Then
- answer = self.answerpaper.answers.filter(question=self.question2)\
- .last()
+ answer = self.answerpaper.answers.filter(
+ question=self.question2).last()
self.assertEqual(answer, regrade_answer)
self.assertTrue(details[0])
self.assertEqual(answer.marks, 0)
@@ -334,7 +321,7 @@ class StringQuestionTestCases(unittest.TestCase):
def test_case_sensitive_string_incorrect_answer(self):
# Given
string_answer = "hello, earth!"
- answer = Answer(question=self.question2,answer=string_answer)
+ answer = Answer(question=self.question2, answer=string_answer)
answer.save()
self.answerpaper.answers.add(answer)
@@ -348,7 +335,7 @@ class StringQuestionTestCases(unittest.TestCase):
self.assertFalse(result['success'])
# Regrade
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=answer.id)
regrade_answer.answer = "Hello, EARTH!"
regrade_answer.save()
@@ -357,8 +344,8 @@ class StringQuestionTestCases(unittest.TestCase):
details = self.answerpaper.regrade(self.question2.id)
# Then
- answer = self.answerpaper.answers.filter(question=self.question2)\
- .last()
+ answer = self.answerpaper.answers.filter(
+ question=self.question2).last()
self.assertEqual(answer, regrade_answer)
self.assertTrue(details[0])
self.assertEqual(answer.marks, 1)
@@ -375,9 +362,9 @@ class FloatQuestionTestCases(unittest.TestCase):
# Creating Question paper
self.question_paper = QuestionPaper.objects.get(quiz=self.quiz)
- #Creating User
+ # Creating User
self.user = User.objects.get(username='demo_user_100')
- #Creating Question
+ # Creating Question
self.question1 = Question.objects.create(summary='flt1', points=1,
type='code', user=self.user)
self.question1.language = 'python'
@@ -385,31 +372,28 @@ class FloatQuestionTestCases(unittest.TestCase):
self.question1.test_case_type = 'floattestcase'
self.question1.save()
- #Creating answerpaper
-
- self.answerpaper = AnswerPaper.objects.create(user=self.user,
- user_ip='101.0.0.1',
- start_time=timezone.now(),
- question_paper=self.question_paper,
- end_time=timezone.now()
- +timedelta(minutes=5),
- attempt_number=1,
- course=self.course
- )
+ # Creating answerpaper
+
+ self.answerpaper = AnswerPaper.objects.create(
+ user=self.user, user_ip='101.0.0.1', start_time=timezone.now(),
+ question_paper=self.question_paper, course=self.course,
+ end_time=timezone.now()+timedelta(minutes=5), attempt_number=1,
+ )
+
self.answerpaper.questions.add(self.question1)
self.answerpaper.save()
- # For question
+ # For question
self.float_based_testcase = FloatTestCase(question=self.question1,
correct=100,
error_margin=0.1,
- type = 'floattestcase',
+ type='floattestcase',
)
self.float_based_testcase.save()
@classmethod
def tearDownClass(self):
- self.question1.delete()
- self.answerpaper.delete()
+ self.question1.delete()
+ self.answerpaper.delete()
def test_validate_regrade_float_correct_answer(self):
# Given
@@ -430,7 +414,7 @@ class FloatQuestionTestCases(unittest.TestCase):
self.assertTrue(result['success'])
# Regrade with wrong answer
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=self.answer.id)
regrade_answer.answer = 0.0
regrade_answer.save()
@@ -465,7 +449,7 @@ class FloatQuestionTestCases(unittest.TestCase):
self.assertFalse(result['success'])
# Regrade
- # Given
+ # Given
regrade_answer = Answer.objects.get(id=self.answer.id)
regrade_answer.answer = 99.9
regrade_answer.save()
@@ -480,15 +464,17 @@ class FloatQuestionTestCases(unittest.TestCase):
self.assertTrue(details[0])
self.assertEqual(self.answer.marks, 1)
self.assertTrue(self.answer.correct)
+
+
class MCQQuestionTestCases(unittest.TestCase):
@classmethod
def setUpClass(self):
- #Creating User
+ # Creating User
self.user = User.objects.get(username='demo_user_100')
self.user2 = User.objects.get(username='demo_user_101')
self.user_ip = '127.0.0.1'
- #Creating Course
+ # Creating Course
self.course = Course.objects.get(name="Python Course 100")
# Creating Quiz
self.quiz = Quiz.objects.get(description="demo quiz 100")
@@ -496,7 +482,7 @@ class MCQQuestionTestCases(unittest.TestCase):
self.question_paper = QuestionPaper.objects.get(quiz=self.quiz)
self.question_paper.shuffle_testcases = True
self.question_paper.save()
- #Creating Question
+ # Creating Question
self.question1 = Question.objects.create(summary='mcq1', points=1,
type='code', user=self.user,
)
@@ -552,9 +538,9 @@ class MCQQuestionTestCases(unittest.TestCase):
@classmethod
def tearDownClass(self):
- self.question1.delete()
- self.answerpaper.delete()
- self.answerpaper2.delete()
+ self.question1.delete()
+ self.answerpaper.delete()
+ self.answerpaper2.delete()
def test_shuffle_test_cases(self):
# Given
@@ -576,7 +562,8 @@ class MCQQuestionTestCases(unittest.TestCase):
course_id=self.course.id
)
not_ordered_testcase = self.question1.get_ordered_test_cases(
- answerpaper3 )
+ answerpaper3
+ )
get_test_cases = self.question1.get_test_cases()
# Then
self.assertNotEqual(order1, order2)
@@ -594,9 +581,9 @@ class ArrangeQuestionTestCases(unittest.TestCase):
self.question_paper = QuestionPaper.objects.get(quiz=self.quiz,
total_marks=1.0)
- #Creating User
+ # Creating User
self.user = User.objects.get(username='demo_user_100')
- #Creating Question
+ # Creating Question
self.question1 = Question.objects.create(summary='arrange1',
points=1.0,
user=self.user
@@ -607,42 +594,39 @@ class ArrangeQuestionTestCases(unittest.TestCase):
self.question1.test_case_type = 'arrangetestcase'
self.question1.save()
- #Creating answerpaper
-
- self.answerpaper = AnswerPaper.objects.create(user=self.user,
- user_ip='101.0.0.1',
- start_time=timezone.now(),
- question_paper=self.question_paper,
- end_time=timezone.now()
- +timedelta(minutes=5),
- attempt_number=1,
- course=self.course
- )
+ # Creating answerpaper
+
+ self.answerpaper = AnswerPaper.objects.create(
+ user=self.user, user_ip='101.0.0.1', course=self.course,
+ start_time=timezone.now(), question_paper=self.question_paper,
+ end_time=timezone.now()+timedelta(minutes=5), attempt_number=1
+ )
self.answerpaper.questions.add(self.question1)
self.answerpaper.save()
# For question
self.arrange_testcase_1 = ArrangeTestCase(question=self.question1,
options="A",
- type = 'arrangetestcase',
+ type='arrangetestcase',
)
self.arrange_testcase_1.save()
self.testcase_1_id = self.arrange_testcase_1.id
self.arrange_testcase_2 = ArrangeTestCase(question=self.question1,
options="B",
- type = 'arrangetestcase',
+ type='arrangetestcase',
)
self.arrange_testcase_2.save()
self.testcase_2_id = self.arrange_testcase_2.id
self.arrange_testcase_3 = ArrangeTestCase(question=self.question1,
options="C",
- type = 'arrangetestcase',
+ type='arrangetestcase',
)
self.arrange_testcase_3.save()
self.testcase_3_id = self.arrange_testcase_3.id
+
@classmethod
def tearDownClass(self):
- self.question1.delete()
- self.answerpaper.delete()
+ self.question1.delete()
+ self.answerpaper.delete()
def test_validate_regrade_arrange_correct_answer(self):
# Given
@@ -681,11 +665,10 @@ class ArrangeQuestionTestCases(unittest.TestCase):
self.quiz.description,
self.question1.summary,
self.question1.type
- ) )
+ ))
self.assertFalse(details[0])
self.assertEqual(details[1], err_msg)
-
# Try regrade with incorrect answer
# When
regrade_answer.answer = [self.testcase_1_id,
@@ -741,15 +724,17 @@ class ArrangeQuestionTestCases(unittest.TestCase):
self.assertTrue(details[0])
self.assertEqual(self.answer.marks, 1)
self.assertTrue(self.answer.correct)
-class MCQQuestionTestCases(unittest.TestCase):
+
+
+class MCQShuffleTestCases(unittest.TestCase):
@classmethod
def setUpClass(self):
- #Creating User
+ # Creating User
self.user = User.objects.get(username='demo_user_100')
self.user2 = User.objects.get(username='demo_user_101')
self.user_ip = '127.0.0.1'
- #Creating Course
+ # Creating Course
self.course = Course.objects.get(name="Python Course 100")
# Creating Quiz
self.quiz = Quiz.objects.get(description="demo quiz 100")
@@ -757,7 +742,7 @@ class MCQQuestionTestCases(unittest.TestCase):
self.question_paper = QuestionPaper.objects.get(quiz=self.quiz)
self.question_paper.shuffle_testcases = True
self.question_paper.save()
- #Creating Question
+ # Creating Question
self.question1 = Question.objects.create(summary='mcq1', points=1,
type='code', user=self.user,
)
@@ -810,11 +795,12 @@ class MCQQuestionTestCases(unittest.TestCase):
attempt_num=1,
course_id=self.course.id
)
+
@classmethod
def tearDownClass(self):
- self.question1.delete()
- self.answerpaper.delete()
- self.answerpaper2.delete()
+ self.question1.delete()
+ self.answerpaper.delete()
+ self.answerpaper2.delete()
def test_shuffle_test_cases(self):
# Given
diff --git a/yaksh/file_utils.py b/yaksh/file_utils.py
index b178eeb..6c3fd5d 100644
--- a/yaksh/file_utils.py
+++ b/yaksh/file_utils.py
@@ -4,6 +4,7 @@ import zipfile
import tempfile
import csv
+
def copy_files(file_paths):
""" Copy Files to current directory, takes
tuple with file paths and extract status"""
@@ -65,4 +66,3 @@ def is_csv(document):
except (csv.Error, UnicodeDecodeError):
return False, None
return True, dialect
-
diff --git a/yaksh/hook_evaluator.py b/yaksh/hook_evaluator.py
index 41ef6e4..33c1549 100644
--- a/yaksh/hook_evaluator.py
+++ b/yaksh/hook_evaluator.py
@@ -40,18 +40,19 @@ class HookEvaluator(BaseEvaluator):
--------
Returns a tuple (success, error, test_case_weight)
- success - Boolean, indicating if code was executed successfully, correctly
+ success - Boolean, indicating if code was executed successfully,
+ correctly
mark_fraction - Float, indicating fraction of the weight to a test case
error - String, error message if success is false
- returns (True, "Correct answer", 1.0) : If the student script passes all
- test cases/have same output, when compared to the instructor script
+ returns (True, "Correct answer", 1.0) : If the student script passes
+ all test cases/have same output, when compared to the instructor script
returns (False, error_msg, 0.0): If the student script fails a single
test/have dissimilar output, when compared to the instructor script.
- Returns (False, error_msg, 0.0): If mandatory arguments are not files or if
- the required permissions are not given to the file(s).
+ Returns (False, error_msg, 0.0): If mandatory arguments are not files
+ or if the required permissions are not given to the file(s).
"""
if self.file_paths:
self.files = copy_files(self.file_paths)
@@ -84,8 +85,8 @@ class HookEvaluator(BaseEvaluator):
del tb_list[1:3]
err = prettify_exceptions(exc_type.__name__,
str(exc_value),
- "Error in Hook Code:\n"
- + "".join(tb_list)
+ "Error in Hook Code:\n" + "".join(
+ tb_list)
)
return success, err, mark_fraction
diff --git a/yaksh/java_code_evaluator.py b/yaksh/java_code_evaluator.py
index e6dc628..5f2288d 100644
--- a/yaksh/java_code_evaluator.py
+++ b/yaksh/java_code_evaluator.py
@@ -1,11 +1,8 @@
#!/usr/bin/env python
from __future__ import unicode_literals
-import traceback
-import pwd
import os
-from os.path import join, isfile
+from os.path import isfile
import subprocess
-import importlib
# Local imports
from .base_evaluator import BaseEvaluator
@@ -62,8 +59,8 @@ class JavaCodeEvaluator(BaseEvaluator):
# create student code and moderator code file
self.submit_code_path = self.create_submit_code_file('Test.java')
self.test_code_path = self.create_submit_code_file('main.java')
- self.write_to_submit_code_file(self.submit_code_path,
- self.user_answer
+ self.write_to_submit_code_file(
+ self.submit_code_path, self.user_answer
)
self.write_to_submit_code_file(self.test_code_path, self.test_case)
clean_ref_code_path = self.test_code_path
@@ -78,11 +75,11 @@ class JavaCodeEvaluator(BaseEvaluator):
user_code_directory = os.getcwd() + '/'
ref_file_name = (clean_ref_code_path.split('/')[-1]).split('.')[0]
- self.user_output_path = self.set_file_paths(user_code_directory,
- 'Test'
+ self.user_output_path = self.set_file_paths(
+ user_code_directory, 'Test'
)
- self.ref_output_path = self.set_file_paths(user_code_directory,
- ref_file_name
+ self.ref_output_path = self.set_file_paths(
+ user_code_directory, ref_file_name
)
compile_command, self.compile_main = self.get_commands(
clean_ref_code_path,
@@ -93,13 +90,15 @@ class JavaCodeEvaluator(BaseEvaluator):
ref_file_name
)
- self.compiled_user_answer = self._run_command(compile_command,
+ self.compiled_user_answer = self._run_command(
+ compile_command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
- self.compiled_test_code = self._run_command(self.compile_main,
+ self.compiled_test_code = self._run_command(
+ self.compile_main,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
@@ -141,9 +140,9 @@ class JavaCodeEvaluator(BaseEvaluator):
if main_err == '':
ret = self._run_command(self.run_command_args, shell=True,
- stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
proc, stdout, stderr = ret
if proc.returncode == 0:
success, err = True, None
@@ -151,7 +150,7 @@ class JavaCodeEvaluator(BaseEvaluator):
else:
err = stdout + "\n" + stderr
else:
- err = "Error:"
+ err = "Test case Error:"
try:
error_lines = main_err.splitlines()
for e in error_lines:
@@ -159,7 +158,7 @@ class JavaCodeEvaluator(BaseEvaluator):
err = err + "\n" + e.split(":", 1)[1]
else:
err = err + "\n" + e
- except:
+ except Exception:
err = err + "\n" + main_err
else:
err = "Compilation Error:"
@@ -170,7 +169,7 @@ class JavaCodeEvaluator(BaseEvaluator):
err = err + "\n" + e.split(":", 1)[1]
else:
err = err + "\n" + e
- except:
+ except Exception:
err = err + "\n" + stdnt_stderr
return success, err, mark_fraction
diff --git a/yaksh/java_stdio_evaluator.py b/yaksh/java_stdio_evaluator.py
index 4e9238f..0504177 100644
--- a/yaksh/java_stdio_evaluator.py
+++ b/yaksh/java_stdio_evaluator.py
@@ -4,7 +4,7 @@ import subprocess
import os
from os.path import isfile
-#Local imports
+# Local imports
from .stdio_evaluator import StdIOEvaluator
from .file_utils import copy_files, delete_files
@@ -22,7 +22,7 @@ class JavaStdIOEvaluator(StdIOEvaluator):
# Set test case data values
self.expected_input = test_case_data.get('expected_input')
self.expected_output = test_case_data.get('expected_output')
- self.weight = test_case_data.get('weight')
+ self.weight = test_case_data.get('weight')
def teardown(self):
os.remove(self.submit_code_path)
@@ -84,7 +84,7 @@ class JavaStdIOEvaluator(StdIOEvaluator):
err = err + "\n" + e.split(":", 1)[1]
else:
err = err + "\n" + e
- except:
+ except Exception:
err = err + "\n" + stdnt_stderr
mark_fraction = 1.0 if self.partial_grading and success else 0.0
return success, err, mark_fraction
diff --git a/yaksh/language_registry.py b/yaksh/language_registry.py
index 994e9ed..ec5dae9 100644
--- a/yaksh/language_registry.py
+++ b/yaksh/language_registry.py
@@ -1,26 +1,29 @@
from __future__ import unicode_literals
import importlib
-import json
-import six
+import six
# Local imports
from .settings import code_evaluators
registry = None
-
+
+
def get_registry():
global registry
if registry is None:
registry = _LanguageRegistry()
return registry
+
def create_evaluator_instance(metadata, test_case):
"""Create instance of relevant EvaluateCode class based on language"""
registry = get_registry()
- cls = registry.get_class(metadata.get('language'), test_case.get('test_case_type'))
+ cls = registry.get_class(metadata.get('language'),
+ test_case.get('test_case_type'))
instance = cls(metadata, test_case)
return instance
+
class _LanguageRegistry(object):
def __init__(self):
self._register = {}
@@ -33,7 +36,6 @@ class _LanguageRegistry(object):
if not self._register.get(language):
self._register[language] = code_evaluators.get(language)
test_case_register = self._register[language]
-
cls = test_case_register.get(test_case_type)
module_name, class_name = cls.rsplit(".", 1)
# load the module, will raise ImportError if module cannot be loaded
@@ -45,4 +47,3 @@ class _LanguageRegistry(object):
def register(self, language, class_names):
""" Register a new code evaluator class for language"""
self._register[language] = class_names
-
diff --git a/yaksh/management/commands/create_moderator.py b/yaksh/management/commands/create_moderator.py
index 3bbe462..86489d5 100644
--- a/yaksh/management/commands/create_moderator.py
+++ b/yaksh/management/commands/create_moderator.py
@@ -1,5 +1,6 @@
'''
- This command creates a moderator group and adds users to the moderator group with permissions to add, change and delete
+ This command creates a moderator group and adds users to the moderator group
+ with permissions to add, change and delete
the objects in the exam app.
'''
@@ -7,10 +8,7 @@
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User, Group, Permission
from django.contrib.contenttypes.models import ContentType
-from django.db.utils import IntegrityError
-# Yaksh imports
-from yaksh.models import Profile
class Command(BaseCommand):
help = 'Adds users to the moderator group'
@@ -30,7 +28,8 @@ class Command(BaseCommand):
# Get the models for the given app
content_types = ContentType.objects.filter(app_label=app_label)
# Get list of permissions for the models
- permission_list = Permission.objects.filter(content_type__in=content_types)
+ permission_list = Permission.objects.filter(
+ content_type__in=content_types)
group.permissions.add(*permission_list)
group.save()
self.stdout.write('Moderator group added successfully')
@@ -40,9 +39,15 @@ class Command(BaseCommand):
try:
user = User.objects.get(username=uname)
except User.DoesNotExist:
- raise CommandError('User "{0}" does not exist'.format(uname))
+ raise CommandError('User "{0}" does not exist'.format(
+ uname)
+ )
if user in group.user_set.all():
- self.stdout.write('User "{0}" is already a Moderator'.format(uname))
+ self.stdout.write('User "{0}" is '
+ 'already a Moderator'.format(uname)
+ )
else:
group.user_set.add(user)
- self.stdout.write('Successfully added User "{0}" to Moderator group'.format(uname))
+ self.stdout.write('Successfully added User "{0}"'
+ ' to Moderator group'.format(uname)
+ )
diff --git a/yaksh/middleware/one_session_per_user.py b/yaksh/middleware/one_session_per_user.py
index 92e888d..1ed1786 100644
--- a/yaksh/middleware/one_session_per_user.py
+++ b/yaksh/middleware/one_session_per_user.py
@@ -7,21 +7,27 @@ from yaksh.models import ConcurrentUser
class OneSessionPerUserMiddleware(object):
"""
Middleware to handle multiple logins with same credentials
- - Creates a Database entry to record the current user and active session key
- - Checks if the current user has already been logged in. If True, the new session
- key is stored with respect to the user and the old session key is deleted,
+ - Creates a Database entry to record the current user and active
+ session key
+ - Checks if the current user has already been logged in. If True, the
+ new session key is stored with respect to the user and the old
+ session key is deleted,
effectively terminating the older session for the same user.
- - The concurrentuser attribute of the User model refers to the ConcurrentUser
- model object and not the concurrent_user field due to behaviour described
- in the Documentation
- Link: https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#extending-the-existing-user-model)
+ - The concurrentuser attribute of the User model refers to the
+ ConcurrentUser
+ model object and not the concurrent_user field due to behaviour
+ described in the Documentation
+ Link: https://docs.djangoproject.com/en/1.5/topics/auth/customizing/
+ #extending-the-existing-user-model
"""
def process_request(self, request):
+ """
+ # Documentation:
+ # https://docs.djangoproject.com/en/1.5/topics/auth/customizing/
+ #extending-the-existing-user-model
+ """
if isinstance(request.user, User):
current_key = request.session.session_key
- #
- # Documentation:
- # https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#extending-the-existing-user-model
if hasattr(request.user, 'concurrentuser'):
active_key = request.user.concurrentuser.session_key
if active_key != current_key:
@@ -32,4 +38,4 @@ class OneSessionPerUserMiddleware(object):
ConcurrentUser.objects.create(
concurrent_user=request.user,
session_key=current_key,
- ) \ No newline at end of file
+ )
diff --git a/yaksh/middleware/user_time_zone.py b/yaksh/middleware/user_time_zone.py
index ff9ec5c..206c08a 100644
--- a/yaksh/middleware/user_time_zone.py
+++ b/yaksh/middleware/user_time_zone.py
@@ -4,8 +4,10 @@ from django.utils import timezone
class TimezoneMiddleware(object):
- """ Middleware to get user's timezone and activate timezone
- if user timezone is not available default value 'Asia/Kolkata' is activated """
+ """ Middleware to get user's timezone and activate timezone
+ if user timezone is not available default value 'Asia/Kolkata'
+ is activated
+ """
def process_request(self, request):
user = request.user
user_tz = 'Asia/Kolkata'
diff --git a/yaksh/models.py b/yaksh/models.py
index 50a5cc2..5d17dba 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -19,8 +19,6 @@ except ImportError:
from io import BytesIO as string_io
import pytz
import os
-import sys
-import traceback
import stat
from os.path import join, exists
import shutil
@@ -92,10 +90,10 @@ FIXTURES_DIR_PATH = os.path.join(settings.BASE_DIR, 'yaksh', 'fixtures')
def get_assignment_dir(instance, filename):
upload_dir = instance.question_paper.quiz.description.replace(" ", "_")
- return os.sep.join((
- upload_dir, instance.user.username, str(instance.assignmentQuestion.id),
- filename
- ))
+ return os.sep.join((upload_dir, instance.user.username,
+ str(instance.assignmentQuestion.id),
+ filename
+ ))
def get_model_class(model):
@@ -110,13 +108,14 @@ def get_upload_dir(instance, filename):
'question_%s' % (instance.question.id), filename
))
+
def dict_to_yaml(dictionary):
- for k,v in dictionary.items():
+ for k, v in dictionary.items():
if isinstance(v, list):
- for nested_v in v:
+ for nested_v in v:
if isinstance(nested_v, dict):
dict_to_yaml(nested_v)
- elif v and isinstance(v,str):
+ elif v and isinstance(v, str):
dictionary[k] = PreservedScalarString(v)
return ruamel.yaml.round_trip_dump(dictionary, explicit_start=True,
default_flow_style=False,
@@ -204,12 +203,10 @@ class QuizManager(models.Manager):
def create_trial_quiz(self, user):
"""Creates a trial quiz for testing questions"""
- trial_quiz = self.create(duration=1000,
- description="trial_questions",
- is_trial=True,
- time_between_attempts=0,
- creator=user
- )
+ trial_quiz = self.create(
+ duration=1000, description="trial_questions",
+ is_trial=True, time_between_attempts=0, creator=user
+ )
return trial_quiz
def create_trial_from_quiz(self, original_quiz_id, user, godmode,
@@ -955,12 +952,11 @@ class Question(models.Model):
# Check assignment upload based question
grade_assignment_upload = models.BooleanField(default=False)
- min_time = models.IntegerField("time in minutes", default=0)
+ min_time = models.IntegerField("time in minutes", default=0)
- #Solution for the question.
+ # Solution for the question.
solution = models.TextField(blank=True)
-
def consolidate_answer_data(self, user_answer, user=None):
question_data = {}
metadata = {}
@@ -986,7 +982,7 @@ class Question(models.Model):
)
if assignment_files:
metadata['assign_files'] = [(file.assignmentFile.path, False)
- for file in assignment_files]
+ for file in assignment_files]
question_data['metadata'] = metadata
return json.dumps(question_data)
@@ -1020,8 +1016,7 @@ class Question(models.Model):
for question in questions:
question['user'] = user
file_names = question.pop('files') \
- if 'files' in question \
- else None
+ if 'files' in question else None
tags = question.pop('tags') if 'tags' in question else None
test_cases = question.pop('testcase')
que, result = Question.objects.get_or_create(**question)
@@ -1040,8 +1035,8 @@ class Question(models.Model):
new_test_case.type = test_case_type
new_test_case.save()
- except:
- msg = "File not correct."
+ except Exception:
+ msg = "Unable to parse test case data"
except Exception as exc_msg:
msg = "Error Parsing Yaml: {0}".format(exc_msg)
return msg
@@ -1075,7 +1070,7 @@ class Question(models.Model):
def get_ordered_test_cases(self, answerpaper):
try:
order = TestCaseOrder.objects.get(answer_paper=answerpaper,
- question = self
+ question=self
).order.split(",")
return [self.get_test_case(id=int(tc_id))
for tc_id in order
@@ -1111,13 +1106,11 @@ class Question(models.Model):
file_upload.extract = extract
file_upload.file.save(file_name, django_file, save=True)
- def _add_yaml_to_zip(self, zip_file, q_dict,path_to_file=None):
-
+ def _add_yaml_to_zip(self, zip_file, q_dict, path_to_file=None):
tmp_file_path = tempfile.mkdtemp()
yaml_path = os.path.join(tmp_file_path, "questions_dump.yaml")
for elem in q_dict:
relevant_dict = CommentedMap()
- irrelevant_dict = CommentedMap()
relevant_dict['summary'] = elem.pop('summary')
relevant_dict['type'] = elem.pop('type')
relevant_dict['language'] = elem.pop('language')
@@ -1125,8 +1118,8 @@ class Question(models.Model):
relevant_dict['points'] = elem.pop('points')
relevant_dict['testcase'] = elem.pop('testcase')
relevant_dict.update(CommentedMap(sorted(elem.items(),
- key=lambda x:x[0]
- ))
+ key=lambda x: x[0]
+ ))
)
yaml_block = dict_to_yaml(relevant_dict)
@@ -1142,7 +1135,7 @@ class Question(models.Model):
if os.path.exists(yaml_file):
with open(yaml_file, 'r') as q_file:
questions_list = q_file.read()
- msg = self.load_questions(questions_list, user,
+ msg = self.load_questions(questions_list, user,
file_path, files
)
else:
@@ -1291,7 +1284,7 @@ class QuestionPaper(models.Model):
# Shuffle testcase order.
shuffle_testcases = models.BooleanField("Shuffle testcase for each user",
- default=True
+ default=True
)
objects = QuestionPaperManager()
@@ -1360,16 +1353,16 @@ class QuestionPaper(models.Model):
question_ids = []
for question in questions:
question_ids.append(str(question.id))
- if (question.type == "arrange") or (self.shuffle_testcases
- and question.type in ["mcq", "mcc"]):
+ if (question.type == "arrange") or (
+ self.shuffle_testcases and
+ question.type in ["mcq", "mcc"]):
testcases = question.get_test_cases()
random.shuffle(testcases)
testcases_ids = ",".join([str(tc.id) for tc in testcases]
)
- testcases_order = TestCaseOrder.objects.create(
- answer_paper=ans_paper,
- question=question,
- order=testcases_ids)
+ TestCaseOrder.objects.create(
+ answer_paper=ans_paper, question=question,
+ order=testcases_ids)
ans_paper.questions_order = ",".join(question_ids)
ans_paper.save()
@@ -1388,11 +1381,12 @@ class QuestionPaper(models.Model):
user=user, questionpaper=self, course_id=course_id
)
if last_attempt:
- time_lag = (timezone.now() - last_attempt.start_time).total_seconds() / 3600
+ time_lag = (timezone.now() - last_attempt.start_time)
+ time_lag = time_lag.total_seconds()/3600
can_attempt = time_lag >= self.quiz.time_between_attempts
- msg = "You cannot start the next attempt for this quiz before {0} hour(s)".format(
- self.quiz.time_between_attempts
- ) if not can_attempt else None
+ msg = "You cannot start the next attempt for this quiz before"\
+ "{0} hour(s)".format(self.quiz.time_between_attempts) \
+ if not can_attempt else None
return can_attempt, msg
else:
return True, None
@@ -1696,11 +1690,12 @@ class AnswerPaper(models.Model):
)
def get_per_question_score(self, question_id):
- if question_id not in self.get_questions().values_list('id', flat=True):
+ questions = self.get_questions().values_list('id', flat=True)
+ if question_id not in questions:
return 'NA'
answer = self.get_latest_answer(question_id)
if answer:
- return answer.marks
+ return answer.marks
else:
return 0
@@ -1716,7 +1711,8 @@ class AnswerPaper(models.Model):
def get_current_question(self, questions):
if self.questions_order:
available_question_ids = questions.values_list('id', flat=True)
- ordered_question_ids = [int(q) for q in self.questions_order.split(',')]
+ ordered_question_ids = [int(q)
+ for q in self.questions_order.split(',')]
for qid in ordered_question_ids:
if qid in available_question_ids:
return questions.get(id=qid)
@@ -1731,7 +1727,7 @@ class AnswerPaper(models.Model):
Adds the completed question to the list of answered
questions and returns the next question.
"""
- if question_id not in self.questions_answered.all():
+ if question_id not in self.questions_answered.all():
self.questions_answered.add(question_id)
self.questions_unanswered.remove(question_id)
@@ -1919,11 +1915,11 @@ class AnswerPaper(models.Model):
for tc in question.get_test_cases():
if tc.string_check == "lower":
if tc.correct.lower().splitlines()\
- == user_answer.lower().splitlines():
+ == user_answer.lower().splitlines():
tc_status.append(True)
else:
if tc.correct.splitlines()\
- == user_answer.splitlines():
+ == user_answer.splitlines():
tc_status.append(True)
if any(tc_status):
result['success'] = True
@@ -1948,7 +1944,6 @@ class AnswerPaper(models.Model):
result['success'] = True
result['error'] = ['Correct answer']
-
elif question.type == 'code' or question.type == "upload":
user_dir = self.user.profile.get_user_dir()
url = '{0}:{1}'.format(SERVER_HOST_NAME, server_port)
@@ -2140,6 +2135,7 @@ class HookTestCase(TestCase):
def __str__(self):
return u'Hook Testcase | Correct: {0}'.format(self.hook_code)
+
class IntegerTestCase(TestCase):
correct = models.IntegerField(default=None)
@@ -2152,11 +2148,11 @@ class IntegerTestCase(TestCase):
class StringTestCase(TestCase):
correct = models.TextField(default=None)
- string_check = models.CharField(max_length=200,choices=string_check_type)
+ string_check = models.CharField(max_length=200, choices=string_check_type)
def get_field_value(self):
return {"test_case_type": "stringtestcase", "correct": self.correct,
- "string_check":self.string_check}
+ "string_check": self.string_check}
def __str__(self):
return u'String Testcase | Correct: {0}'.format(self.correct)
@@ -2169,7 +2165,7 @@ class FloatTestCase(TestCase):
def get_field_value(self):
return {"test_case_type": "floattestcase", "correct": self.correct,
- "error_margin":self.error_margin}
+ "error_margin": self.error_margin}
def __str__(self):
return u'Testcase | Correct: {0} | Error Margin: +or- {1}'.format(
@@ -2178,7 +2174,6 @@ class FloatTestCase(TestCase):
class ArrangeTestCase(TestCase):
-
options = models.TextField(default=None)
def get_field_value(self):
@@ -2201,7 +2196,7 @@ class TestCaseOrder(models.Model):
# Question in an answerpaper.
question = models.ForeignKey(Question)
- #Order of the test case for a question.
+ # Order of the test case for a question.
order = models.TextField()
diff --git a/yaksh/python_stdio_evaluator.py b/yaksh/python_stdio_evaluator.py
index b08103a..64a2809 100644
--- a/yaksh/python_stdio_evaluator.py
+++ b/yaksh/python_stdio_evaluator.py
@@ -21,6 +21,7 @@ def redirect_stdout():
finally:
sys.stdout = old_target # restore to the previous value
+
class PythonStdIOEvaluator(BaseEvaluator):
"""Tests the Python code obtained from Code Server"""
def __init__(self, metadata, test_case_data):
diff --git a/yaksh/scilab_code_evaluator.py b/yaksh/scilab_code_evaluator.py
index f5c81b5..9f26234 100644
--- a/yaksh/scilab_code_evaluator.py
+++ b/yaksh/scilab_code_evaluator.py
@@ -1,11 +1,8 @@
#!/usr/bin/env python
from __future__ import unicode_literals
-import traceback
import os
-from os.path import join, isfile
import subprocess
import re
-import importlib
# Local imports
from .base_evaluator import BaseEvaluator
@@ -41,8 +38,7 @@ class ScilabCodeEvaluator(BaseEvaluator):
self.test_code_path = self.create_submit_code_file('main.sci')
if self.file_paths:
self.files = copy_files(self.file_paths)
- ref_code_path = self.test_case
- clean_ref_path, clean_test_case_path = self.test_code_path, None
+ clean_ref_path = self.test_code_path
self.user_answer, terminate_commands = \
self._remove_scilab_exit(self.user_answer.lstrip())
@@ -61,12 +57,10 @@ class ScilabCodeEvaluator(BaseEvaluator):
clean_ref_path
)
cmd += ' | scilab-cli -nb'
- ret = self._run_command(cmd,
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
- )
- proc, stdout, stderr = ret
+ ret = self._run_command(cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
+ proc, stdout, stderr = ret
# Get only the error.
stderr = self._get_error(stdout)
@@ -117,4 +111,3 @@ class ScilabCodeEvaluator(BaseEvaluator):
if l.strip():
strip_out = strip_out+"\n"+l.strip()
return strip_out
-
diff --git a/yaksh/send_emails.py b/yaksh/send_emails.py
index 4c9a7dc..061cb0e 100644
--- a/yaksh/send_emails.py
+++ b/yaksh/send_emails.py
@@ -6,7 +6,6 @@ except ImportError:
from string import digits, punctuation
import hashlib
from textwrap import dedent
-import smtplib
import os
# Django imports
@@ -61,18 +60,20 @@ def send_user_mail(user_mail, key):
return success, msg
+
def send_bulk_mail(subject, email_body, recipients, attachments):
try:
text_msg = ""
msg = EmailMultiAlternatives(subject, text_msg, settings.SENDER_EMAIL,
- [settings.SENDER_EMAIL], bcc=recipients
- )
+ [settings.SENDER_EMAIL], bcc=recipients
+ )
msg.attach_alternative(email_body, "text/html")
if attachments:
for file in attachments:
- path = default_storage.save('attachments/'+file.name,
- ContentFile(file.read())
- )
+ path = default_storage.save(
+ os.path.join('attachments', file.name),
+ ContentFile(file.read())
+ )
msg.attach_file(os.sep.join((settings.MEDIA_ROOT, path)),
mimetype="text/html"
)
diff --git a/yaksh/settings.py b/yaksh/settings.py
index d895d19..9e9597d 100644
--- a/yaksh/settings.py
+++ b/yaksh/settings.py
@@ -12,8 +12,8 @@ N_CODE_SERVERS = config('N_CODE_SERVERS', default=5, cast=int)
# service is running. It should be > 1024 and less < 65535 though.
SERVER_POOL_PORT = config('SERVER_POOL_PORT', default=55555, cast=int)
+# Server host name
SERVER_HOST_NAME = config('SERVER_HOST_NAME', default='http://localhost')
-#'localhost'
# Timeout for the code to run in seconds. This is an integer!
SERVER_TIMEOUT = config('SERVER_TIMEOUT', default=4, cast=int)
@@ -25,27 +25,34 @@ SERVER_TIMEOUT = config('SERVER_TIMEOUT', default=4, cast=int)
URL_ROOT = ''
code_evaluators = {
- "python": {"standardtestcase": "yaksh.python_assertion_evaluator.PythonAssertionEvaluator",
- "stdiobasedtestcase": "yaksh.python_stdio_evaluator.PythonStdIOEvaluator",
- "hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
- },
+ "python": {
+ "standardtestcase":
+ "yaksh.python_assertion_evaluator.PythonAssertionEvaluator",
+ "stdiobasedtestcase":
+ "yaksh.python_stdio_evaluator.PythonStdIOEvaluator",
+ "hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
+ },
"c": {"standardtestcase": "yaksh.cpp_code_evaluator.CppCodeEvaluator",
"stdiobasedtestcase": "yaksh.cpp_stdio_evaluator.CppStdIOEvaluator",
"hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
},
"cpp": {"standardtestcase": "yaksh.cpp_code_evaluator.CppCodeEvaluator",
- "stdiobasedtestcase": "yaksh.cpp_stdio_evaluator.CppStdIOEvaluator",
+ "stdiobasedtestcase":
+ "yaksh.cpp_stdio_evaluator.CppStdIOEvaluator",
"hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
},
"java": {"standardtestcase": "yaksh.java_code_evaluator.JavaCodeEvaluator",
- "stdiobasedtestcase": "yaksh.java_stdio_evaluator.JavaStdIOEvaluator",
+ "stdiobasedtestcase":
+ "yaksh.java_stdio_evaluator.JavaStdIOEvaluator",
"hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
},
"bash": {"standardtestcase": "yaksh.bash_code_evaluator.BashCodeEvaluator",
- "stdiobasedtestcase": "yaksh.bash_stdio_evaluator.BashStdIOEvaluator",
+ "stdiobasedtestcase":
+ "yaksh.bash_stdio_evaluator.BashStdIOEvaluator",
"hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
},
- "scilab": {"standardtestcase": "yaksh.scilab_code_evaluator.ScilabCodeEvaluator",
- "hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
- },
+ "scilab": {
+ "standardtestcase": "yaksh.scilab_code_evaluator.ScilabCodeEvaluator",
+ "hooktestcase": "yaksh.hook_evaluator.HookEvaluator"
+ },
}
diff --git a/yaksh/stdio_evaluator.py b/yaksh/stdio_evaluator.py
index 55adb5c..ce4a70e 100644
--- a/yaksh/stdio_evaluator.py
+++ b/yaksh/stdio_evaluator.py
@@ -9,7 +9,8 @@ from .error_messages import compare_outputs
class StdIOEvaluator(BaseEvaluator):
- def evaluate_stdio(self, user_answer, proc, expected_input, expected_output):
+ def evaluate_stdio(self, user_answer, proc,
+ expected_input, expected_output):
success = False
try:
if expected_input:
@@ -21,7 +22,6 @@ class StdIOEvaluator(BaseEvaluator):
else:
user_output_bytes, output_err_bytes = proc.communicate()
user_output = user_output_bytes.decode('utf-8')
- output_err = output_err_bytes.decode('utf-8')
except TimeoutException:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
raise
diff --git a/yaksh/templatetags/test_custom_filters.py b/yaksh/templatetags/test_custom_filters.py
index 7cef957..e8d1d61 100644
--- a/yaksh/templatetags/test_custom_filters.py
+++ b/yaksh/templatetags/test_custom_filters.py
@@ -5,10 +5,7 @@ import pytz
# local imports
from yaksh.models import (User, Profile, Question, Quiz, QuestionPaper,
- QuestionSet, AnswerPaper, Answer, Course,
- IntegerTestCase, FloatTestCase,
- StringTestCase, McqTestCase, ArrangeTestCase,
- TestCaseOrder
+ AnswerPaper, Course, ArrangeTestCase, TestCaseOrder
)
from yaksh.templatetags.custom_filters import (completed, inprogress,
@@ -19,9 +16,10 @@ from yaksh.templatetags.custom_filters import (completed, inprogress,
def setUpModule():
# Create user profile
- teacher = User.objects.create_user(username='teacher2000',
- password='demo',
- email='teacher2000@test.com')
+ teacher = User.objects.create_user(
+ username='teacher2000', password='demo',
+ email='teacher2000@test.com'
+ )
Profile.objects.create(user=teacher, roll_number=2000, institute='IIT',
department='Chemical', position='Teacher')
# Create a course
@@ -29,34 +27,31 @@ def setUpModule():
enrollment="Enroll Request",
creator=teacher)
# Create a quiz
- quiz = Quiz.objects.create(start_date_time=datetime(
- 2015, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc),
- end_date_time=datetime(
- 2199, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc),
- duration=30, active=True,
- attempts_allowed=1, time_between_attempts=0,
- description='demo quiz 2000',
- pass_criteria=0,
- instructions="Demo Instructions",
- creator=teacher
- )
+ quiz = Quiz.objects.create(
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ duration=30, active=True,
+ attempts_allowed=1, time_between_attempts=0,
+ description='demo quiz 2000',
+ pass_criteria=0, instructions="Demo Instructions",
+ creator=teacher
+ )
# Create a question paper
question_paper = QuestionPaper.objects.create(quiz=quiz,
total_marks=1.0)
# Create an answer paper
- answerpaper = AnswerPaper.objects.create(user=teacher,
- user_ip='101.0.0.1',
- start_time=timezone.now(),
- question_paper=question_paper,
- end_time=timezone.now()
- +timedelta(minutes=5),
- attempt_number=1,
- course=course
- )
+ AnswerPaper.objects.create(
+ user=teacher, user_ip='101.0.0.1',
+ start_time=timezone.now(),
+ question_paper=question_paper,
+ end_time=timezone.now()+timedelta(minutes=5),
+ attempt_number=1,
+ course=course
+ )
+
+
def tearDownModule():
- User.objects.get(username="teacher2000").delete()
+ User.objects.get(username="teacher2000").delete()
class CustomFiltersTestCases(unittest.TestCase):
@@ -76,47 +71,47 @@ class CustomFiltersTestCases(unittest.TestCase):
self.question1.save()
self.question_paper.fixed_questions.add(self.question1)
self.question_paper.save()
- #Creating answerpaper
+ # Creating answerpaper
- self.answerpaper = AnswerPaper.objects.get(user=self.user,
- course=self.course,
- question_paper=self.question_paper
- )
+ self.answerpaper = AnswerPaper.objects.get(
+ user=self.user, course=self.course,
+ question_paper=self.question_paper
+ )
self.answerpaper.questions.add(self.question1)
self.answerpaper.save()
- # For question
- self.arrange_testcase_1 = ArrangeTestCase(question=self.question1,
- options="A",
- type = 'arrangetestcase',
- )
+ # For question
+ self.arrange_testcase_1 = ArrangeTestCase(
+ question=self.question1, options="A",
+ type='arrangetestcase',
+ )
self.arrange_testcase_1.save()
self.testcase_1_id = self.arrange_testcase_1.id
- self.arrange_testcase_2 = ArrangeTestCase(question=self.question1,
- options="B",
- type = 'arrangetestcase',
- )
+ self.arrange_testcase_2 = ArrangeTestCase(
+ question=self.question1, options="B",
+ type='arrangetestcase',
+ )
self.arrange_testcase_2.save()
self.testcase_2_id = self.arrange_testcase_2.id
- self.arrange_testcase_3 = ArrangeTestCase(question=self.question1,
- options="C",
- type = 'arrangetestcase',
- )
+ self.arrange_testcase_3 = ArrangeTestCase(
+ question=self.question1, options="C",
+ type='arrangetestcase',
+ )
self.arrange_testcase_3.save()
self.testcase_3_id = self.arrange_testcase_3.id
@classmethod
def tearDownClass(self):
- self.question1.delete()
- self.answerpaper.delete()
+ self.question1.delete()
+ self.answerpaper.delete()
def test_completed_inprogress(self):
- # Test in progress
+ # Test in progress
answerpaper = AnswerPaper.objects.filter(id=self.answerpaper.id)
self.assertEqual(inprogress(answerpaper), 1)
self.assertEqual(completed(answerpaper), 0)
# Test completed
- self.answerpaper.status='completed'
+ self.answerpaper.status = 'completed'
self.answerpaper.save()
self.assertEqual(inprogress(answerpaper), 0)
self.assertEqual(completed(answerpaper), 1)
@@ -134,7 +129,7 @@ class CustomFiltersTestCases(unittest.TestCase):
def test_get_ordered_testcases(self):
new_answerpaper = self.question_paper.make_answerpaper(self.user,
- "101.0.0.1",2,
+ "101.0.0.1", 2,
self.course.id
)
tc_order = TestCaseOrder.objects.get(answer_paper=new_answerpaper,
@@ -142,8 +137,8 @@ class CustomFiltersTestCases(unittest.TestCase):
)
testcases = [self.question1.get_test_case(id=ids)
for ids in tc_order.order.split(",")
- ]
-
+ ]
+
ordered_testcases = get_ordered_testcases(self.question1,
new_answerpaper
)
diff --git a/yaksh/test_models.py b/yaksh/test_models.py
index f97b7b2..eaf5bbc 100644
--- a/yaksh/test_models.py
+++ b/yaksh/test_models.py
@@ -3,18 +3,16 @@ from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\
QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\
StdIOBasedTestCase, FileUpload, McqTestCase, AssignmentUpload,\
LearningModule, LearningUnit, Lesson, LessonFile, CourseStatus
-from yaksh.code_server import(ServerPool,
- get_result as get_result_from_code_server
- )
+from yaksh.code_server import (
+ ServerPool, get_result as get_result_from_code_server
+ )
import json
import ruamel.yaml as yaml
from datetime import datetime, timedelta
from django.utils import timezone
import pytz
-from django.contrib.auth.models import Group
from django.db import IntegrityError
from django.core.files import File
-from django.forms.models import model_to_dict
from textwrap import dedent
import zipfile
import os
@@ -23,6 +21,7 @@ import tempfile
from threading import Thread
from yaksh import settings
+
def setUpModule():
# create user profile
user = User.objects.create_user(username='creator',
@@ -39,31 +38,29 @@ def setUpModule():
Profile.objects.create(user=student, roll_number=3, institute='IIT',
department='Chemical', position='Student')
- user4 = User.objects.create_user(username='demo_user4',
- password='demo',
- email='demo4@test.com'
+ user4 = User.objects.create_user(
+ username='demo_user4', password='demo', email='demo4@test.com'
)
Profile.objects.create(user=user4, roll_number=4, institute='IIT',
department='Chemical', position='Student')
-
# create a course
course = Course.objects.create(name="Python Course",
enrollment="Enroll Request", creator=user)
# create 20 questions
for i in range(1, 21):
- Question.objects.create(summary='Q%d' % (i), points=1, type='code', user=user)
+ Question.objects.create(summary='Q%d' % (i), points=1,
+ type='code', user=user)
# create a quiz
- quiz = Quiz.objects.create(start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc),
- end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc),
- duration=30, active=True,
- attempts_allowed=1, time_between_attempts=0,
- description='demo quiz 1', pass_criteria=0,
- instructions="Demo Instructions")
+ quiz = Quiz.objects.create(
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ duration=30, active=True,
+ attempts_allowed=1, time_between_attempts=0,
+ description='demo quiz 1', pass_criteria=0,
+ instructions="Demo Instructions")
Quiz.objects.create(start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0,
tzinfo=pytz.utc),
@@ -78,13 +75,12 @@ def setUpModule():
f.write('2'.encode('ascii'))
# Learing module
- learning_module_one = LearningModule.objects.create(name='LM1',
- description='module one',
- creator=user)
- learning_module_two = LearningModule.objects.create(name='LM2',
- description='module two',
- creator=user,
- order=1)
+ learning_module_one = LearningModule.objects.create(
+ name='LM1', description='module one', creator=user
+ )
+ learning_module_two = LearningModule.objects.create(
+ name='LM2', description='module two', creator=user, order=1
+ )
lesson = Lesson.objects.create(name='L1', description='Video Lesson',
creator=user)
learning_unit_lesson = LearningUnit.objects.create(order=1, lesson=lesson,
@@ -288,30 +284,23 @@ class ProfileTestCases(unittest.TestCase):
self.assertEqual(self.profile.department, 'Chemical')
self.assertEqual(self.profile.position, 'Student')
+
###############################################################################
class QuestionTestCases(unittest.TestCase):
def setUp(self):
# Single question details
self.user1 = User.objects.get(username="creator")
self.user2 = User.objects.get(username="demo_user2")
- self.question1 = Question.objects.create(summary='Demo Python 1',
- language='Python',
- type='Code',
- active=True,
- description='Write a function',
- points=1.0,
- snippet='def myfunc()',
- user=self.user1
+ self.question1 = Question.objects.create(
+ summary='Demo Python 1', language='Python', type='Code',
+ active=True, description='Write a function', points=1.0,
+ snippet='def myfunc()', user=self.user1
)
- self.question2 = Question.objects.create(summary='Yaml Json',
- language='python',
- type='code',
- active=True,
- description='factorial of a no',
- points=2.0,
- snippet='def fact()',
- user=self.user2
+ self.question2 = Question.objects.create(
+ summary='Yaml Json', language='python', type='code',
+ active=True, description='factorial of a no', points=2.0,
+ snippet='def fact()', user=self.user2
)
# create a temp directory and add files for loading questions test
@@ -326,26 +315,28 @@ class QuestionTestCases(unittest.TestCase):
file2 = os.path.join(self.dump_tmp_path, "test.txt")
upload_file = open(file2, "r")
django_file = File(upload_file)
- file = FileUpload.objects.create(file=django_file,
- question=self.question2
- )
+ FileUpload.objects.create(file=django_file,
+ question=self.question2
+ )
self.question1.tags.add('python', 'function')
- self.assertion_testcase = StandardTestCase(question=self.question1,
+ self.assertion_testcase = StandardTestCase(
+ question=self.question1,
test_case='assert myfunc(12, 13) == 15',
type='standardtestcase'
)
- self.upload_test_case = StandardTestCase(question=self.question2,
+ self.upload_test_case = StandardTestCase(
+ question=self.question2,
test_case='assert fact(3) == 6',
type='standardtestcase'
)
self.upload_test_case.save()
self.user_answer = "demo_answer"
self.test_case_upload_data = [{"test_case": "assert fact(3)==6",
- "test_case_type": "standardtestcase",
- "test_case_args": "",
- "weight": 1.0
- }]
+ "test_case_type": "standardtestcase",
+ "test_case_args": "",
+ "weight": 1.0
+ }]
questions_data = [{"snippet": "def fact()", "active": True,
"points": 1.0,
"description": "factorial of a no",
@@ -355,20 +346,33 @@ class QuestionTestCases(unittest.TestCase):
"summary": "Yaml Demo",
"tags": ['yaml_demo']
}]
- questions_data_with_missing_fields = [{"active": True,
- "points": 1.0,
- "description":\
- "factorial of a no",
- "language": "Python",
- "type": "Code",
- "testcase":\
- self.test_case_upload_data,
- "summary": "Yaml Demo 2"
- }]
+ questions_data_with_missing_fields = [{
+ "active": True, "points": 1.0, "description": "factorial of a no",
+ "language": "Python", "type": "Code",
+ "testcase": self.test_case_upload_data,
+ "summary": "Yaml Demo 2"
+ }]
self.yaml_questions_data = yaml.safe_dump_all(questions_data)
self.yaml_questions_data_with_missing_fields = yaml.safe_dump_all(
questions_data_with_missing_fields
)
+ self.bad_yaml_question_data = '''[{
+ "active": True, "points": 1.0, "description" "factorial of a no",
+ "language": "Python", "type": "Code",
+ "testcase": self.test_case_upload_data,
+ "summary": "bad yaml"
+ }]'''
+
+ self.test_case_without_type = [{"test_case": "assert fact(3)==6",
+ "test_case_args": "",
+ "weight": 1.0
+ }]
+ self.yaml_question_data_without_test_case_type = yaml.safe_dump_all([{
+ "active": True, "points": 1.0, "description": "factorial of a no",
+ "language": "Python", "type": "Code",
+ "testcase": self.test_case_without_type,
+ "summary": "bad yaml"
+ }])
def tearDown(self):
shutil.rmtree(self.load_tmp_path)
@@ -419,8 +423,9 @@ class QuestionTestCases(unittest.TestCase):
self.assertTrue(self.question2.active)
self.assertEqual(self.question2.snippet, q['snippet'])
self.assertEqual(os.path.basename(que_file.file.path),
- q['files'][0][0])
- self.assertEqual([case.get_field_value() for case in test_case],
+ q['files'][0][0])
+ self.assertEqual([case.get_field_value()
+ for case in test_case],
q['testcase']
)
for file in zip_file.namelist():
@@ -429,7 +434,7 @@ class QuestionTestCases(unittest.TestCase):
def test_load_questions_with_all_fields(self):
""" Test load questions into database from Yaml """
question = Question()
- result = question.load_questions(self.yaml_questions_data, self.user1)
+ question.load_questions(self.yaml_questions_data, self.user1)
question_data = Question.objects.get(summary="Yaml Demo")
file = FileUpload.objects.get(question=question_data)
test_case = question_data.get_test_cases()
@@ -439,7 +444,7 @@ class QuestionTestCases(unittest.TestCase):
self.assertEqual(question_data.description, 'factorial of a no')
self.assertEqual(question_data.points, 1.0)
self.assertTrue(question_data.active)
- tags = question_data.tags.all().values_list("name",flat=True)
+ tags = question_data.tags.all().values_list("name", flat=True)
self.assertListEqual(list(tags), ['yaml_demo'])
self.assertEqual(question_data.snippet, 'def fact()')
self.assertEqual(os.path.basename(file.file.path), "test.txt")
@@ -451,27 +456,45 @@ class QuestionTestCases(unittest.TestCase):
""" Test load questions into database from Yaml with
missing fields like files, snippet and tags. """
question = Question()
- result = question.load_questions(
- self.yaml_questions_data_with_missing_fields,
- self.user1
- )
+ question.load_questions(
+ self.yaml_questions_data_with_missing_fields,
+ self.user1
+ )
question_data = Question.objects.get(summary="Yaml Demo 2")
file = FileUpload.objects.filter(question=question_data)
test_case = question_data.get_test_cases()
- self.assertEqual(question_data.summary,'Yaml Demo 2')
- self.assertEqual(question_data.language,'Python')
+ self.assertEqual(question_data.summary, 'Yaml Demo 2')
+ self.assertEqual(question_data.language, 'Python')
self.assertEqual(question_data.type, 'Code')
- self.assertEqual(question_data.description,'factorial of a no')
+ self.assertEqual(question_data.description, 'factorial of a no')
self.assertEqual(question_data.points, 1.0)
self.assertTrue(question_data.active)
- self.assertEqual(question_data.snippet,'')
- self.assertListEqual(list(file),[])
+ self.assertEqual(question_data.snippet, '')
+ self.assertListEqual(list(file), [])
self.assertEqual([case.get_field_value() for case in test_case],
self.test_case_upload_data
)
- tags = question_data.tags.all().values_list("name",flat=True)
+ tags = question_data.tags.all().values_list("name", flat=True)
self.assertListEqual(list(tags), [])
+ def test_load_questions_with_bad_yaml(self):
+ """
+ Test if yaml file is parsed correctly
+ """
+ question = Question()
+ msg = question.load_questions(
+ self.bad_yaml_question_data,
+ self.user1
+ )
+ self.assertIn("Error Parsing Yaml", msg)
+
+ msg = question.load_questions(
+ self.yaml_question_data_without_test_case_type,
+ self.user1
+ )
+ self.assertEqual(msg, "Unable to parse test case data")
+
+
###############################################################################
class QuizTestCases(unittest.TestCase):
def setUp(self):
@@ -483,7 +506,8 @@ class QuizTestCases(unittest.TestCase):
self.quiz1 = Quiz.objects.get(description='demo quiz 1')
self.quiz2 = Quiz.objects.get(description='demo quiz 2')
self.quiz3 = Quiz.objects.create(
- start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0,
+ tzinfo=pytz.utc),
end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
duration=30, active=True,
attempts_allowed=1, time_between_attempts=0,
@@ -492,7 +516,8 @@ class QuizTestCases(unittest.TestCase):
)
self.question_paper3 = QuestionPaper.objects.create(quiz=self.quiz3)
self.quiz4 = Quiz.objects.create(
- start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0,
+ tzinfo=pytz.utc),
end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
duration=30, active=True,
attempts_allowed=1, time_between_attempts=0,
@@ -627,13 +652,14 @@ class QuestionPaperTestCases(unittest.TestCase):
@classmethod
def setUpClass(self):
self.course = Course.objects.get(name="Python Course")
- self.user= User.objects.get(username='creator')
+ self.user = User.objects.get(username='creator')
# All active questions
self.questions = Question.objects.filter(active=True, user=self.user)
self.quiz = Quiz.objects.get(description="demo quiz 1")
self.quiz_with_time_between_attempts = Quiz.objects.create(
description="demo quiz with time between attempts",
- start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0,
+ tzinfo=pytz.utc),
end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
duration=30, active=True,
attempts_allowed=3, time_between_attempts=1.0,
@@ -645,15 +671,20 @@ class QuestionPaperTestCases(unittest.TestCase):
self.question_paper_fixed_questions = QuestionPaper.objects.create(
quiz=self.quiz)
self.question_paper_fixed_questions.fixed_questions.add(
- self.questions.get(summary='Q11'), self.questions.get(summary='Q10'))
+ self.questions.get(summary='Q11'),
+ self.questions.get(summary='Q10')
+ )
# create question paper with only random questions
self.question_paper_random_questions = QuestionPaper.objects.create(
quiz=self.quiz)
- self.question_set_random = QuestionSet.objects.create(marks=2,
- num_questions=2)
- self.question_set_random.questions.add(self.questions.get(summary='Q13'),
- self.questions.get(summary='Q5'), self.questions.get(summary='Q7'))
+ self.question_set_random = QuestionSet.objects.create(
+ marks=2, num_questions=2
+ )
+ self.question_set_random.questions.add(
+ self.questions.get(summary='Q13'),
+ self.questions.get(summary='Q5'), self.questions.get(summary='Q7')
+ )
self.question_paper_random_questions.random_questions.add(
self.question_set_random)
@@ -662,49 +693,47 @@ class QuestionPaperTestCases(unittest.TestCase):
quiz=self.quiz)
# create question paper
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
- total_marks=0.0,
- shuffle_questions=True
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz, total_marks=0.0, shuffle_questions=True
)
- self.question_paper_with_time_between_attempts = QuestionPaper.objects.create(
- quiz=self.quiz_with_time_between_attempts,
- total_marks=0.0,
- shuffle_questions=True
- )
+ self.question_paper_with_time_between_attempts = \
+ QuestionPaper.objects.create(
+ quiz=self.quiz_with_time_between_attempts,
+ total_marks=0.0,
+ shuffle_questions=True
+ )
self.question_paper.fixed_question_order = "{0}, {1}".format(
self.questions[3].id, self.questions[5].id
)
# add fixed set of questions to the question paper
- self.question_paper.fixed_questions.add(self.questions[3],
- self.questions[5]
- )
+ self.question_paper.fixed_questions.add(
+ self.questions[3], self.questions[5]
+ )
# create two QuestionSet for random questions
# QuestionSet 1
- self.question_set_1 = QuestionSet.objects.create(marks=2,
- num_questions=2
+ self.question_set_1 = QuestionSet.objects.create(
+ marks=2, num_questions=2
)
# add pool of questions for random sampling
- self.question_set_1.questions.add(self.questions[6],
- self.questions[7],
- self.questions[8],
- self.questions[9]
+ self.question_set_1.questions.add(
+ self.questions[6], self.questions[7],
+ self.questions[8], self.questions[9]
)
# add question set 1 to random questions in Question Paper
self.question_paper.random_questions.add(self.question_set_1)
# QuestionSet 2
- self.question_set_2 = QuestionSet.objects.create(marks=3,
- num_questions=3
+ self.question_set_2 = QuestionSet.objects.create(
+ marks=3, num_questions=3
)
# add pool of questions
- self.question_set_2.questions.add(self.questions[11],
- self.questions[12],
- self.questions[13],
- self.questions[14]
+ self.question_set_2.questions.add(
+ self.questions[11], self.questions[12],
+ self.questions[13], self.questions[14]
)
# add question set 2
self.question_paper.random_questions.add(self.question_set_2)
@@ -738,10 +767,11 @@ class QuestionPaperTestCases(unittest.TestCase):
self.assertSequenceEqual(questions, question_bank)
# Given
- summaries = ['Q13','Q5','Q7']
+ summaries = ['Q13', 'Q5', 'Q7']
questions = list(Question.objects.filter(summary__in=summaries))
# When
- question_bank = self.question_paper_random_questions.get_question_bank()
+ question_bank = \
+ self.question_paper_random_questions.get_question_bank()
# Then
self.assertSequenceEqual(questions, question_bank)
@@ -756,8 +786,8 @@ class QuestionPaperTestCases(unittest.TestCase):
""" Test question paper"""
self.assertEqual(self.question_paper.quiz.description, 'demo quiz 1')
self.assertSequenceEqual(self.question_paper.fixed_questions.all(),
- [self.questions[3], self.questions[5]]
- )
+ [self.questions[3], self.questions[5]]
+ )
self.assertTrue(self.question_paper.shuffle_questions)
def test_update_total_marks(self):
@@ -770,8 +800,8 @@ class QuestionPaperTestCases(unittest.TestCase):
""" Test get_random_questions() method of Question Paper"""
random_questions_set_1 = self.question_set_1.get_random_questions()
random_questions_set_2 = self.question_set_2.get_random_questions()
- total_random_questions = len(random_questions_set_1 + \
- random_questions_set_2)
+ total_random_questions = len(random_questions_set_1 +
+ random_questions_set_2)
self.assertEqual(total_random_questions, 5)
# To check whether random questions are from random_question_set
@@ -803,21 +833,21 @@ class QuestionPaperTestCases(unittest.TestCase):
answerpaper.passed = True
answerpaper.save()
# test can_attempt_now(self):
- result = (False, u'You cannot attempt demo quiz 1 quiz more than 1 time(s)')
+ result = (False,
+ u'You cannot attempt demo quiz 1 quiz more than 1 time(s)')
self.assertEquals(
- self.question_paper.can_attempt_now(self.user, self.course.id), result
+ self.question_paper.can_attempt_now(self.user, self.course.id),
+ result
)
# trying to create an answerpaper with same parameters passed.
- answerpaper2 = self.question_paper.make_answerpaper(self.user, self.ip,
- attempt_num,
- self.course.id)
+ answerpaper2 = self.question_paper.make_answerpaper(
+ self.user, self.ip, attempt_num, self.course.id
+ )
# check if make_answerpaper returned an object instead of creating one.
self.assertEqual(answerpaper, answerpaper2)
-
def test_time_between_attempt(self):
""" Test make_answerpaper() method of Question Paper"""
- already_attempted = self.attempted_papers.count()
attempt_num = 1
self.first_start_time = timezone.now()
@@ -849,26 +879,28 @@ class QuestionPaperTestCases(unittest.TestCase):
)
self.second_answerpaper.passed = True
self.second_answerpaper.save()
-
- result = (False, u'You cannot start the next attempt for this quiz before 1.0 hour(s)')
+ msg = u'You cannot start the next attempt ' +\
+ 'for this quiz before1.0 hour(s)'
+ result = (False, msg)
self.assertEquals(
- self.question_paper_with_time_between_attempts.can_attempt_now(self.user, self.course.id), result
+ self.question_paper_with_time_between_attempts.can_attempt_now(
+ self.user, self.course.id), result
)
-
def test_create_trial_paper_to_test_quiz(self):
qu_list = [str(self.questions_list[0]), str(self.questions_list[1])]
- trial_paper = QuestionPaper.objects.create_trial_paper_to_test_quiz\
- (self.trial_quiz,
- self.quiz.id
- )
+ trial_paper = \
+ QuestionPaper.objects.create_trial_paper_to_test_quiz(
+ self.trial_quiz, self.quiz.id
+ )
trial_paper.random_questions.add(self.question_set_1)
trial_paper.random_questions.add(self.question_set_2)
trial_paper.fixed_question_order = ",".join(qu_list)
self.assertEqual(trial_paper.quiz, self.trial_quiz)
- self.assertSequenceEqual(trial_paper.get_ordered_questions(),
- self.question_paper.get_ordered_questions()
- )
+ self.assertSequenceEqual(
+ trial_paper.get_ordered_questions(),
+ self.question_paper.get_ordered_questions()
+ )
trial_paper_ran = [q_set.id for q_set in
trial_paper.random_questions.all()]
qp_ran = [q_set.id for q_set in
@@ -878,10 +910,10 @@ class QuestionPaperTestCases(unittest.TestCase):
def test_create_trial_paper_to_test_questions(self):
qu_list = [str(self.questions_list[0]), str(self.questions_list[1])]
- trial_paper = QuestionPaper.objects.\
- create_trial_paper_to_test_questions(
- self.trial_quiz, qu_list
- )
+ trial_paper = \
+ QuestionPaper.objects.create_trial_paper_to_test_questions(
+ self.trial_quiz, qu_list
+ )
self.assertEqual(trial_paper.quiz, self.trial_quiz)
fixed_q = self.question_paper.fixed_questions.values_list(
'id', flat=True)
@@ -921,7 +953,8 @@ class AnswerPaperTestCases(unittest.TestCase):
self.question4 = all_questions[3]
# create answerpaper
- self.answerpaper = AnswerPaper(user=self.user,
+ self.answerpaper = AnswerPaper(
+ user=self.user,
question_paper=self.question_paper,
start_time=self.start_time,
end_time=self.end_time,
@@ -943,12 +976,14 @@ class AnswerPaperTestCases(unittest.TestCase):
self.answerpaper.questions_unanswered.add(*self.questions)
self.answerpaper.save()
# answers for the Answer Paper
- self.answer_right = Answer(question=self.question1,
+ self.answer_right = Answer(
+ question=self.question1,
answer="Demo answer",
correct=True, marks=1,
error=json.dumps([])
)
- self.answer_wrong = Answer(question=self.question2,
+ self.answer_wrong = Answer(
+ question=self.question2,
answer="My answer",
correct=False,
marks=0,
@@ -966,7 +1001,8 @@ class AnswerPaperTestCases(unittest.TestCase):
self.answerpaper.answers.add(self.answer1)
# create an answerpaper with only one question
- self.answerpaper_single_question = AnswerPaper(user=self.user,
+ self.answerpaper_single_question = AnswerPaper(
+ user=self.user,
question_paper=self.question_paper,
start_time=self.start_time,
end_time=self.end_time,
@@ -981,10 +1017,13 @@ class AnswerPaperTestCases(unittest.TestCase):
self.answerpaper_single_question.attempt_number = already_attempted + 1
self.answerpaper_single_question.save()
self.answerpaper_single_question.questions.add(self.question4)
- self.answerpaper_single_question.questions_unanswered.add(self.question4)
+ self.answerpaper_single_question.questions_unanswered.add(
+ self.question4
+ )
self.answerpaper_single_question.save()
# answers for the Answer Paper
- self.single_answer = Answer(question=self.question4,
+ self.single_answer = Answer(
+ question=self.question4,
answer="Demo answer",
correct=True, marks=1,
error=json.dumps([])
@@ -1009,23 +1048,23 @@ class AnswerPaperTestCases(unittest.TestCase):
self.assertion_testcase = StandardTestCase(
question=self.question1,
test_case='assert add(1, 3) == 4',
- type = 'standardtestcase'
+ type='standardtestcase'
)
self.assertion_testcase.save()
self.mcq_based_testcase = McqTestCase(
- options = 'a',
+ options='a',
question=self.question2,
- correct = True,
- type = 'mcqtestcase'
+ correct=True,
+ type='mcqtestcase'
)
self.mcq_based_testcase.save()
self.mcc_based_testcase = McqTestCase(
question=self.question3,
- options = 'a',
- correct = True,
- type = 'mcqtestcase'
+ options='a',
+ correct=True,
+ type='mcqtestcase'
)
self.mcc_based_testcase.save()
@@ -1071,7 +1110,9 @@ class AnswerPaperTestCases(unittest.TestCase):
question_id = self.question4.id
expected_score = 1
# When
- score = self.answerpaper_single_question.get_per_question_score(question_id)
+ score = self.answerpaper_single_question.get_per_question_score(
+ question_id
+ )
# Then
self.assertEqual(score, expected_score)
@@ -1098,10 +1139,10 @@ class AnswerPaperTestCases(unittest.TestCase):
# Before questions are answered
self.assertEqual(self.answerpaper_single_question.questions_left(), 1)
- current_question = self.answerpaper_single_question.add_completed_question(
- self.question4.id
- )
-
+ current_question = \
+ self.answerpaper_single_question.add_completed_question(
+ self.question4.id
+ )
# Then
self.assertEqual(
@@ -1123,9 +1164,10 @@ class AnswerPaperTestCases(unittest.TestCase):
self.assertEqual(next_question.summary, "Q4")
# When
- current_question = self.answerpaper_single_question.get_current_question(
- self.answerpaper_single_question.questions.all()
- )
+ current_question = \
+ self.answerpaper_single_question.get_current_question(
+ self.answerpaper_single_question.questions.all()
+ )
# Then
self.assertEqual(self.answerpaper_single_question.questions_left(), 0)
@@ -1173,7 +1215,6 @@ class AnswerPaperTestCases(unittest.TestCase):
def test_validate_and_regrade_code_correct_answer(self):
# Given
# Start code server
-
user_answer = dedent("""\
def add(a,b):
return a+b
@@ -1186,9 +1227,9 @@ class AnswerPaperTestCases(unittest.TestCase):
user = self.answerpaper.user
# When
- json_data = self.question1.consolidate_answer_data(user_answer,
- user
- )
+ json_data = self.question1.consolidate_answer_data(
+ user_answer, user
+ )
get_result = self.answerpaper.validate_answer(user_answer,
self.question1,
json_data,
@@ -1196,7 +1237,7 @@ class AnswerPaperTestCases(unittest.TestCase):
self.SERVER_POOL_PORT
)
url = 'http://localhost:%s' % self.SERVER_POOL_PORT
- check_result = get_result_from_code_server(url,get_result['uid'],
+ check_result = get_result_from_code_server(url, get_result['uid'],
block=True
)
result = json.loads(check_result.get('result'))
@@ -1232,7 +1273,8 @@ class AnswerPaperTestCases(unittest.TestCase):
def test_validate_and_regrade_mcq_correct_answer(self):
# Given
mcq_answer = str(self.mcq_based_testcase.id)
- self.answer = Answer(question=self.question2,
+ self.answer = Answer(
+ question=self.question2,
answer=mcq_answer,
)
self.answer.save()
@@ -1260,7 +1302,8 @@ class AnswerPaperTestCases(unittest.TestCase):
details = self.answerpaper.regrade(self.question2.id)
# Then
- self.answer = self.answerpaper.answers.filter(question=self.question2).last()
+ self.answer = self.answerpaper.answers.filter(
+ question=self.question2).last()
self.assertTrue(details[0])
self.assertEqual(self.answer.marks, 0)
self.assertFalse(self.answer.correct)
@@ -1268,7 +1311,8 @@ class AnswerPaperTestCases(unittest.TestCase):
def test_mcq_incorrect_answer(self):
# Given
mcq_answer = 'b'
- self.answer = Answer(question=self.question2,
+ self.answer = Answer(
+ question=self.question2,
answer=mcq_answer,
)
self.answer.save()
@@ -1381,10 +1425,8 @@ class AnswerPaperTestCases(unittest.TestCase):
# Then
self.assertEqual(questions_unanswered.count(), 2)
self.assertEqual(set([q.id for q in questions_unanswered]),
- set([self.questions[1].id,
- self.questions[2].id]
- )
- )
+ set([self.questions[1].id, self.questions[2].id])
+ )
# Test completed_question and next_question
# When all questions are answered
@@ -1406,7 +1448,9 @@ class AnswerPaperTestCases(unittest.TestCase):
# Then
self.assertEqual(self.answerpaper.questions_left(), 0)
self.assertIsNotNone(current_question)
- self.assertTrue(current_question == self.answerpaper.get_all_ordered_questions()[0])
+ self.assertTrue(
+ current_question == self.answerpaper.get_all_ordered_questions()[0]
+ )
# When
next_question_id = self.answerpaper.next_question(current_question_id)
@@ -1430,7 +1474,7 @@ class AnswerPaperTestCases(unittest.TestCase):
def test_set_end_time(self):
current_time = timezone.now()
self.answerpaper.set_end_time(current_time)
- self.assertEqual(self.answerpaper.end_time,current_time)
+ self.assertEqual(self.answerpaper.end_time, current_time)
def test_get_question_answer(self):
""" Test get_question_answer() method of Answer Paper"""
@@ -1484,7 +1528,7 @@ class AnswerPaperTestCases(unittest.TestCase):
def test_duplicate_attempt_answerpaper(self):
with self.assertRaises(IntegrityError):
- new_answerpaper = AnswerPaper.objects.create(
+ AnswerPaper.objects.create(
user=self.answerpaper.user,
question_paper=self.answerpaper.question_paper,
attempt_number=self.answerpaper.attempt_number,
@@ -1516,22 +1560,22 @@ class CourseTestCases(unittest.TestCase):
enrollment="Enroll Request",
creator=self.creator,
start_enroll_time=datetime(2015, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
end_enroll_time=datetime(2015, 11, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
)
self.open_course = Course.objects.create(
name="Open Course With Enrollment Disabled",
enrollment="Open Course",
creator=self.creator,
start_enroll_time=datetime(2015, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
end_enroll_time=datetime(2015, 11, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
)
# create a course that will be cloned
@@ -1540,20 +1584,20 @@ class CourseTestCases(unittest.TestCase):
enrollment="Open Course",
creator=self.creator,
start_enroll_time=datetime(2015, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
end_enroll_time=datetime(2015, 11, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
)
self.template_quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0,
- tzinfo=pytz.utc
- ),
+ tzinfo=pytz.utc
+ ),
duration=30,
active=False,
attempts_allowed=-1,
@@ -1569,13 +1613,13 @@ class CourseTestCases(unittest.TestCase):
shuffle_questions=True
)
- self.template_question_paper.fixed_questions.add(self.questions[1],
- self.questions[2],
- self.questions[3]
+ self.template_question_paper.fixed_questions.add(
+ self.questions[1], self.questions[2], self.questions[3]
)
self.template_quiz2 = Quiz.objects.create(
- start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0,
+ tzinfo=pytz.utc),
end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
duration=30,
active=True,
@@ -1591,9 +1635,8 @@ class CourseTestCases(unittest.TestCase):
shuffle_questions=True
)
- self.template_question_paper2.fixed_questions.add(self.questions[1],
- self.questions[2],
- self.questions[3]
+ self.template_question_paper2.fixed_questions.add(
+ self.questions[1], self.questions[2], self.questions[3]
)
def test_get_learning_modules(self):
@@ -1689,7 +1732,7 @@ class CourseTestCases(unittest.TestCase):
""" Test to add teachers to a course"""
self.course.add_teachers(self.student1, self.student2)
self.assertSequenceEqual(self.course.get_teachers(),
- [self.student1, self.student2])
+ [self.student1, self.student2])
def test_remove_teachers(self):
""" Test to remove teachers from a course"""
@@ -1770,23 +1813,15 @@ class CourseTestCases(unittest.TestCase):
class TestCaseTestCases(unittest.TestCase):
def setUp(self):
self.user = User.objects.get(username="creator")
- self.question1 = Question(summary='Demo question 1',
- language='Python',
- type='Code',
- active=True,
- description='Write a function',
- points=1.0,
- user=self.user,
- snippet='def myfunc()'
+ self.question1 = Question(
+ summary='Demo question 1', language='Python',
+ type='Code', active=True, description='Write a function',
+ points=1.0, user=self.user, snippet='def myfunc()'
)
- self.question2 = Question(summary='Demo question 2',
- language='Python',
- type='Code',
- active=True,
- description='Write to standard output',
- points=1.0,
- user=self.user,
- snippet='def myfunc()'
+ self.question2 = Question(
+ summary='Demo question 2', language='Python',
+ type='Code', active=True, description='Write to standard output',
+ points=1.0, user=self.user, snippet='def myfunc()'
)
self.question1.save()
self.question2.save()
@@ -1803,30 +1838,31 @@ class TestCaseTestCases(unittest.TestCase):
)
self.assertion_testcase.save()
self.stdout_based_testcase.save()
- answer_data = {'metadata': { 'user_answer': 'demo_answer',
- 'language': 'python',
- 'partial_grading': False
- },
- 'test_case_data': [{'test_case': 'assert myfunc(12, 13) == 15',
+ answer_data = {'metadata': {'user_answer': 'demo_answer',
+ 'language': 'python',
+ 'partial_grading': False
+ },
+ 'test_case_data': [
+ {'test_case': 'assert myfunc(12, 13) == 15',
'test_case_type': 'standardtestcase',
'test_case_args': "",
'weight': 1.0
}]
- }
+ }
self.answer_data_json = json.dumps(answer_data)
def test_assertion_testcase(self):
""" Test question """
self.assertEqual(self.assertion_testcase.question, self.question1)
self.assertEqual(self.assertion_testcase.test_case,
- 'assert myfunc(12, 13) == 15')
+ 'assert myfunc(12, 13) == 15')
def test_stdout_based_testcase(self):
""" Test question """
self.assertEqual(self.stdout_based_testcase.question, self.question2)
self.assertEqual(self.stdout_based_testcase.expected_output,
- 'Hello World'
- )
+ 'Hello World'
+ )
def test_consolidate_answer_data(self):
""" Test consolidate answer data model method """
@@ -1835,8 +1871,10 @@ class TestCaseTestCases(unittest.TestCase):
)
actual_data = json.loads(result)
exp_data = json.loads(self.answer_data_json)
- self.assertEqual(actual_data['metadata']['user_answer'], exp_data['metadata']['user_answer'])
- self.assertEqual(actual_data['test_case_data'], exp_data['test_case_data'])
+ self.assertEqual(actual_data['metadata']['user_answer'],
+ exp_data['metadata']['user_answer'])
+ self.assertEqual(actual_data['test_case_data'],
+ exp_data['test_case_data'])
class AssignmentUploadTestCases(unittest.TestCase):
@@ -1851,30 +1889,26 @@ class AssignmentUploadTestCases(unittest.TestCase):
self.user2.save()
self.quiz = Quiz.objects.get(description="demo quiz 1")
- self.questionpaper = QuestionPaper.objects.create(quiz=self.quiz,
- total_marks=0.0,
- shuffle_questions=True
+ self.questionpaper = QuestionPaper.objects.create(
+ quiz=self.quiz, total_marks=0.0, shuffle_questions=True
)
- self.question = Question.objects.create(summary='Assignment',
- language='Python',
- type='upload',
- active=True,
- description='Upload a file',
- points=1.0,
- snippet='',
+ self.question = Question.objects.create(
+ summary='Assignment', language='Python', type='upload',
+ active=True, description='Upload a file', points=1.0, snippet='',
user=self.user1
)
- self.questionpaper.fixed_question_order = "{0}".format(self.question.id)
+ self.questionpaper.fixed_question_order = "{0}".format(
+ self.question.id)
self.questionpaper.fixed_questions.add(self.question)
file_path1 = os.path.join(tempfile.gettempdir(), "upload1.txt")
file_path2 = os.path.join(tempfile.gettempdir(), "upload2.txt")
- self.assignment1 = AssignmentUpload.objects.create(user=self.user1,
- assignmentQuestion=self.question, assignmentFile=file_path1,
- question_paper=self.questionpaper
+ self.assignment1 = AssignmentUpload.objects.create(
+ user=self.user1, assignmentQuestion=self.question,
+ assignmentFile=file_path1, question_paper=self.questionpaper
)
- self.assignment2 = AssignmentUpload.objects.create(user=self.user2,
- assignmentQuestion=self.question, assignmentFile=file_path2,
- question_paper=self.questionpaper
+ self.assignment2 = AssignmentUpload.objects.create(
+ user=self.user2, assignmentQuestion=self.question,
+ assignmentFile=file_path2, question_paper=self.questionpaper
)
def test_get_assignments_for_user_files(self):
@@ -1912,8 +1946,9 @@ class CourseStatusTestCases(unittest.TestCase):
description='module one')
self.quiz1 = Quiz.objects.create(time_between_attempts=0, weightage=50,
description='qz1')
- self.quiz2 = Quiz.objects.create(time_between_attempts=0, weightage=100,
- description='qz2')
+ self.quiz2 = Quiz.objects.create(
+ time_between_attempts=0, weightage=100, description='qz2'
+ )
question = Question.objects.first()
self.qpaper1 = QuestionPaper.objects.create(quiz=self.quiz1)
self.qpaper2 = QuestionPaper.objects.create(quiz=self.quiz2)
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 33747c8..8592031 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -8,9 +8,7 @@ except ImportError:
from io import BytesIO as string_io
import zipfile
import shutil
-from textwrap import dedent
from markdown import Markdown
-
from django.contrib.auth.models import Group
from django.contrib.auth import authenticate
from django.core.urlresolvers import reverse
@@ -22,11 +20,13 @@ from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.files import File
-from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\
- QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\
- AssignmentUpload, FileUpload, McqTestCase, IntegerTestCase, StringTestCase,\
- FloatTestCase, FIXTURES_DIR_PATH, LearningModule, LearningUnit, Lesson,\
+
+from yaksh.models import (
+ User, Profile, Question, Quiz, QuestionPaper, AnswerPaper, Answer, Course,
+ AssignmentUpload, McqTestCase, IntegerTestCase, StringTestCase,
+ FloatTestCase, FIXTURES_DIR_PATH, LearningModule, LearningUnit, Lesson,
LessonFile, CourseStatus
+)
from yaksh.decorators import user_has_profile
@@ -38,21 +38,23 @@ class TestUserRegistration(TestCase):
self.registered_user.delete()
def test_register_user_post(self):
- response = self.client.post(reverse('yaksh:register'),
- data={'username': 'register_user',
- 'email':'register_user@mail.com', 'password': 'reg_user',
- 'confirm_password': 'reg_user', 'first_name': 'user1_f_name',
- 'last_name': 'user1_l_name', 'roll_number': '1',
- 'institute': 'demo_institute', 'department': 'demo_dept',
- 'position': 'student', 'timezone': pytz.utc.zone
- }
+ self.client.post(
+ reverse('yaksh:register'),
+ data={'username': 'register_user',
+ 'email': 'register_user@mail.com', 'password': 'reg_user',
+ 'confirm_password': 'reg_user', 'first_name': 'user1_f_name',
+ 'last_name': 'user1_l_name', 'roll_number': '1',
+ 'institute': 'demo_institute', 'department': 'demo_dept',
+ 'position': 'student', 'timezone': pytz.utc.zone
+ }
)
self.registered_user = User.objects.get(username='register_user')
self.assertEqual(self.registered_user.email, 'register_user@mail.com')
self.assertEqual(self.registered_user.first_name, 'user1_f_name')
self.assertEqual(self.registered_user.last_name, 'user1_l_name')
self.assertEqual(self.registered_user.profile.roll_number, '1')
- self.assertEqual(self.registered_user.profile.institute, 'demo_institute')
+ self.assertEqual(self.registered_user.profile.institute,
+ 'demo_institute')
self.assertEqual(self.registered_user.profile.department, 'demo_dept')
self.assertEqual(self.registered_user.profile.position, 'student')
self.assertEqual(self.registered_user.profile.timezone, 'UTC')
@@ -94,7 +96,6 @@ class TestProfile(TestCase):
self.user1.delete()
self.user2.delete()
-
def test_user_has_profile_for_user_without_profile(self):
"""
If no profile exists for user passed as argument return False
@@ -109,7 +110,6 @@ class TestProfile(TestCase):
has_profile_status = user_has_profile(self.user2)
self.assertTrue(has_profile_status)
-
def test_view_profile_denies_anonymous(self):
"""
If not logged in redirect to login page
@@ -150,15 +150,16 @@ class TestProfile(TestCase):
username=self.user2.username,
password=self.user2_plaintext_pass
)
- post_response = self.client.post(reverse('yaksh:new_activation'),
- data={'email':self.user2.email}
+ post_response = self.client.post(
+ reverse('yaksh:new_activation'),
+ data={'email': self.user2.email}
)
subject = mail.outbox[0].subject.replace(" ", "_")
activation_key = mail.outbox[0].body.split("\n")[2].split("/")[-1]
- get_response = self.client.get(reverse('yaksh:activate',
- kwargs={'key': activation_key}),
- follow=True
- )
+ get_response = self.client.get(
+ reverse('yaksh:activate', kwargs={'key': activation_key}),
+ follow=True
+ )
updated_profile_user = User.objects.get(id=self.user2.id)
updated_profile = Profile.objects.get(user=updated_profile_user)
self.assertEqual(post_response.status_code, 200)
@@ -167,6 +168,14 @@ class TestProfile(TestCase):
self.assertEqual(updated_profile.is_email_verified, True)
self.assertTemplateUsed(get_response, 'yaksh/activation_status.html')
+ post_response = self.client.post(
+ reverse('yaksh:new_activation'),
+ data={'email': 'user@mail.com'}
+ )
+ self.assertEqual(post_response.status_code, 200)
+ self.assertFalse(post_response.context['success'])
+ self.assertTemplateUsed(get_response, 'yaksh/activation_status.html')
+
def test_edit_profile_post(self):
"""
POST request to edit_profile view should update the user's profile
@@ -175,7 +184,8 @@ class TestProfile(TestCase):
username=self.user2.username,
password=self.user2_plaintext_pass
)
- response = self.client.post(reverse('yaksh:edit_profile'),
+ response = self.client.post(
+ reverse('yaksh:edit_profile'),
data={
'user': self.user2,
'first_name': 'new_first_name',
@@ -207,7 +217,8 @@ class TestProfile(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.post(reverse('yaksh:edit_profile'),
+ response = self.client.post(
+ reverse('yaksh:edit_profile'),
data={
'user': self.user1,
'first_name': 'new_first_name',
@@ -275,10 +286,11 @@ class TestProfile(TestCase):
username=self.user2.username,
password=self.user2_plaintext_pass
)
- response = self.client.post(reverse('yaksh:update_email'),
+ response = self.client.post(
+ reverse('yaksh:update_email'),
data={
'username': self.user2.username,
- 'email':"demo_user2@mail.com"
+ 'email': "demo_user2@mail.com"
}
)
updated_user = User.objects.get(id=self.user2.id)
@@ -339,12 +351,15 @@ class TestStudentDashboard(TestCase):
timezone='UTC'
)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user
+ )
- self.hidden_course = Course.objects.create(name="Hidden Course",
- enrollment="Enroll Request", creator=self.user, code="hide",
- hidden=True)
+ self.hidden_course = Course.objects.create(
+ name="Hidden Course", enrollment="Enroll Request",
+ creator=self.user, code="hide", hidden=True
+ )
def tearDown(self):
self.client.logout()
@@ -388,7 +403,7 @@ class TestStudentDashboard(TestCase):
def test_student_dashboard_all_courses_get(self):
"""
- Check student dashboard for all non hidden courses
+ Check student dashboard for all non hidden courses
"""
self.client.login(
username=self.student.username,
@@ -404,7 +419,7 @@ class TestStudentDashboard(TestCase):
def test_student_dashboard_enrolled_courses_get(self):
"""
- Check student dashboard for all courses in which student is
+ Check student dashboard for all courses in which student is
enrolled
"""
self.client.login(
@@ -413,7 +428,7 @@ class TestStudentDashboard(TestCase):
)
self.course.students.add(self.student)
response = self.client.get(reverse('yaksh:quizlist_user',
- kwargs={'enrolled': "enrolled"}),
+ kwargs={'enrolled': "enrolled"}),
follow=True
)
self.assertEqual(response.status_code, 200)
@@ -431,8 +446,8 @@ class TestStudentDashboard(TestCase):
password=self.student_plaintext_pass
)
response = self.client.post(reverse('yaksh:quizlist_user'),
- data={'course_code': 'hide'}
- )
+ data={'course_code': 'hide'}
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/quizzes_user.html")
self.assertEqual(response.context['title'], 'Search')
@@ -486,8 +501,10 @@ class TestMonitor(TestCase):
# Add to moderator group
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Open Enrollment", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Open Enrollment", creator=self.user
+ )
self.quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
@@ -510,13 +527,16 @@ class TestMonitor(TestCase):
points=1.0, language="python", type="code", user=self.user
)
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz,
total_marks=1.0, fixed_question_order=str(self.question)
)
self.question_paper.fixed_questions.add(self.question)
user_answer = "def add(a, b)\n\treturn a+b"
- self.new_answer = Answer(question=self.question, answer=user_answer,
- correct=True, error=json.dumps([]))
+ self.new_answer = Answer(
+ question=self.question, answer=user_answer,
+ correct=True, error=json.dumps([])
+ )
self.new_answer.save()
self.answerpaper = AnswerPaper.objects.create(
user=self.student, question_paper=self.question_paper,
@@ -579,17 +599,19 @@ class TestMonitor(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:monitor',
- kwargs={'quiz_id': self.quiz.id,
- 'course_id': self.course.id}),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:monitor',
+ kwargs={'quiz_id': self.quiz.id,
+ 'course_id': self.course.id}),
+ follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/monitor.html")
self.assertEqual(response.context['msg'], "Quiz Results")
self.assertEqual(response.context['papers'][0], self.answerpaper)
- self.assertEqual(response.context['latest_attempts'][0], self.answerpaper)
+ self.assertEqual(response.context['latest_attempts'][0],
+ self.answerpaper)
def test_get_quiz_user_data(self):
"""
@@ -599,19 +621,23 @@ class TestMonitor(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:user_data',
- kwargs={'user_id':self.student.id,
- 'questionpaper_id': self.question_paper.id,
- 'course_id': self.course.id}),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:user_data',
+ kwargs={'user_id': self.student.id,
+ 'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}),
+ follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/user_data.html')
- self.assertEqual(response.context['data']['papers'][0], self.answerpaper)
- self.assertEqual(response.context['data']['profile'], self.student.profile)
+ self.assertEqual(response.context['data']['papers'][0],
+ self.answerpaper)
+ self.assertEqual(response.context['data']['profile'],
+ self.student.profile)
self.assertEqual(response.context['data']['user'], self.student)
self.assertEqual(response.context['data']['questionpaperid'],
- str(self.question_paper.id))
+ str(self.question_paper.id))
+
class TestGradeUser(TestCase):
def setUp(self):
@@ -660,7 +686,8 @@ class TestGradeUser(TestCase):
# Add to moderator group
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
+ self.course = Course.objects.create(
+ name="Python Course",
enrollment="Open Enrollment", creator=self.user)
self.quiz = Quiz.objects.create(
@@ -684,13 +711,16 @@ class TestGradeUser(TestCase):
points=1.0, language="python", type="code", user=self.user
)
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz,
total_marks=1.0, fixed_question_order=str(self.question.id)
)
self.question_paper.fixed_questions.add(self.question)
user_answer = "def add(a, b)\n\treturn a+b"
- self.new_answer = Answer(question=self.question, answer=user_answer,
- correct=True, error=json.dumps([]), marks=0.5)
+ self.new_answer = Answer(
+ question=self.question, answer=user_answer,
+ correct=True, error=json.dumps([]), marks=0.5
+ )
self.new_answer.save()
self.answerpaper = AnswerPaper.objects.create(
user=self.student, question_paper=self.question_paper,
@@ -753,15 +783,16 @@ class TestGradeUser(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:grade_user',
- kwargs={"quiz_id": self.quiz.id,
- 'course_id': self.course.id}),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:grade_user',
+ kwargs={"quiz_id": self.quiz.id,
+ 'course_id': self.course.id}),
+ follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/grade_user.html")
self.assertEqual(response.context['users'][0]['user__first_name'],
- self.student.first_name)
+ self.student.first_name)
self.assertEqual(response.context['quiz'], self.quiz)
self.assertFalse(response.context['has_quiz_assignments'])
@@ -773,12 +804,13 @@ class TestGradeUser(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:grade_user',
- kwargs={"quiz_id": self.quiz.id,
- "course_id": self.course.id,
- "user_id": self.student.id}),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:grade_user',
+ kwargs={"quiz_id": self.quiz.id,
+ "course_id": self.course.id,
+ "user_id": self.student.id}),
+ follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/grade_user.html")
self.assertFalse(response.context['has_user_assignments'])
@@ -794,25 +826,28 @@ class TestGradeUser(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- self.client.get(reverse('yaksh:grade_user',
+ self.client.get(reverse('yaksh:grade_user',
kwargs={"quiz_id": self.quiz.id,
"course_id": self.course.id,
"user_id": self.student.id}),
- follow=True
- )
+ follow=True
+ )
question_marks = "q{0}_marks".format(self.question.id)
- response = self.client.post(reverse('yaksh:grade_user',
- kwargs={"quiz_id": self.quiz.id,
- "user_id": self.student.id,
- "course_id": self.course.id,
- "attempt_number": self.answerpaper.attempt_number}),
- data={question_marks: 1.0}
- )
+ response = self.client.post(
+ reverse(
+ 'yaksh:grade_user',
+ kwargs={"quiz_id": self.quiz.id,
+ "user_id": self.student.id,
+ "course_id": self.course.id,
+ "attempt_number": self.answerpaper.attempt_number}
+ ),
+ data={question_marks: 1.0}
+ )
- updated_ans_paper = AnswerPaper.objects.get(user=self.student,
- question_paper=self.question_paper,
- attempt_number=self.answerpaper.attempt_number
- )
+ updated_ans_paper = AnswerPaper.objects.get(
+ user=self.student, question_paper=self.question_paper,
+ attempt_number=self.answerpaper.attempt_number
+ )
updated_ans = Answer.objects.get(question=self.question)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/grade_user.html")
@@ -867,8 +902,10 @@ class TestDownloadAssignment(TestCase):
email='demo_student2@test.com'
)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user
+ )
self.quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
@@ -890,7 +927,8 @@ class TestDownloadAssignment(TestCase):
points=1.0, language="python", type="upload", user=self.user
)
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz,
total_marks=1.0, fixed_question_order=str(self.question.id)
)
self.question_paper.fixed_questions.add(self.question)
@@ -898,16 +936,14 @@ class TestDownloadAssignment(TestCase):
# create assignment file
assignment_file1 = SimpleUploadedFile("file1.txt", b"Test")
assignment_file2 = SimpleUploadedFile("file2.txt", b"Test")
- assignment_file3 = SimpleUploadedFile("file3.txt", b"Test")
- self.assignment1 = AssignmentUpload.objects.create(user=self.student1,
- assignmentQuestion=self.question,
- assignmentFile=assignment_file1,
- question_paper=self.question_paper
+ SimpleUploadedFile("file3.txt", b"Test")
+ self.assignment1 = AssignmentUpload.objects.create(
+ user=self.student1, assignmentQuestion=self.question,
+ assignmentFile=assignment_file1, question_paper=self.question_paper
)
- self.assignment2 = AssignmentUpload.objects.create(user=self.student2,
- assignmentQuestion=self.question,
- assignmentFile=assignment_file2,
- question_paper=self.question_paper
+ self.assignment2 = AssignmentUpload.objects.create(
+ user=self.student2, assignmentQuestion=self.question,
+ assignmentFile=assignment_file2, question_paper=self.question_paper
)
def tearDown(self):
@@ -935,7 +971,7 @@ class TestDownloadAssignment(TestCase):
password=self.student1_plaintext_pass
)
response = self.client.get(reverse('yaksh:download_quiz_assignment',
- kwargs={'quiz_id': self.quiz.id}),
+ kwargs={'quiz_id': self.quiz.id}),
follow=True
)
self.assertEqual(response.status_code, 404)
@@ -956,7 +992,7 @@ class TestDownloadAssignment(TestCase):
file_name = file_name.replace(" ", "_")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get('Content-Disposition'),
- "attachment; filename={0}".format(file_name))
+ "attachment; filename={0}".format(file_name))
zip_file = string_io(response.content)
zipped_file = zipfile.ZipFile(zip_file, 'r')
self.assertIsNone(zipped_file.testzip())
@@ -973,18 +1009,19 @@ class TestDownloadAssignment(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:download_user_assignment',
- kwargs={'quiz_id': self.quiz.id,
- 'question_id': self.question.id,
- 'user_id': self.student2.id
- }),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:download_user_assignment',
+ kwargs={'quiz_id': self.quiz.id,
+ 'question_id': self.question.id,
+ 'user_id': self.student2.id
+ }),
+ follow=True
+ )
file_name = "{0}.zip".format(self.student2.get_full_name())
file_name = file_name.replace(" ", "_")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get('Content-Disposition'),
- "attachment; filename={0}".format(file_name))
+ "attachment; filename={0}".format(file_name))
zip_file = string_io(response.content)
zipped_file = zipfile.ZipFile(zip_file, 'r')
self.assertIsNone(zipped_file.testzip())
@@ -1031,8 +1068,10 @@ class TestAddQuiz(TestCase):
# Add to moderator group
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user
+ )
self.quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
@@ -1076,7 +1115,6 @@ class TestAddQuiz(TestCase):
username=self.student.username,
password=self.student_plaintext_pass
)
- course_id = self.course.id
response = self.client.get(reverse('yaksh:add_quiz'),
follow=True
)
@@ -1105,8 +1143,9 @@ class TestAddQuiz(TestCase):
password=self.user_plaintext_pass
)
tzone = pytz.timezone('UTC')
- response = self.client.post(reverse('yaksh:edit_quiz',
- kwargs={'quiz_id': self.quiz.id}),
+ response = self.client.post(
+ reverse('yaksh:edit_quiz',
+ kwargs={'quiz_id': self.quiz.id}),
data={
'start_date_time': '2016-01-10 09:00:15',
'end_date_time': '2016-01-15 09:00:15',
@@ -1122,10 +1161,12 @@ class TestAddQuiz(TestCase):
)
updated_quiz = Quiz.objects.get(id=self.quiz.id)
- self.assertEqual(updated_quiz.start_date_time,
+ self.assertEqual(
+ updated_quiz.start_date_time,
datetime(2016, 1, 10, 9, 0, 15, 0, tzone)
)
- self.assertEqual(updated_quiz.end_date_time,
+ self.assertEqual(
+ updated_quiz.end_date_time,
datetime(2016, 1, 15, 9, 0, 15, 0, tzone)
)
self.assertEqual(updated_quiz.duration, 30)
@@ -1148,7 +1189,8 @@ class TestAddQuiz(TestCase):
)
tzone = pytz.timezone('UTC')
- response = self.client.post(reverse('yaksh:add_quiz'),
+ response = self.client.post(
+ reverse('yaksh:add_quiz'),
data={
'start_date_time': '2016-01-10 09:00:15',
'end_date_time': '2016-01-15 09:00:15',
@@ -1164,10 +1206,12 @@ class TestAddQuiz(TestCase):
)
quiz_list = Quiz.objects.all().order_by('-id')
new_quiz = quiz_list[0]
- self.assertEqual(new_quiz.start_date_time,
+ self.assertEqual(
+ new_quiz.start_date_time,
datetime(2016, 1, 10, 9, 0, 15, 0, tzone)
)
- self.assertEqual(new_quiz.end_date_time,
+ self.assertEqual(
+ new_quiz.end_date_time,
datetime(2016, 1, 15, 9, 0, 15, 0, tzone)
)
self.assertEqual(new_quiz.duration, 50)
@@ -1198,7 +1242,6 @@ class TestAddQuiz(TestCase):
username=self.student.username,
password=self.student_plaintext_pass
)
- course_id = self.course.id
response = self.client.get(reverse('yaksh:add_exercise'),
follow=True
)
@@ -1226,9 +1269,9 @@ class TestAddQuiz(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- tzone = pytz.timezone('UTC')
- response = self.client.post(reverse('yaksh:edit_exercise',
- kwargs={'quiz_id': self.exercise.id}),
+ response = self.client.post(
+ reverse('yaksh:edit_exercise',
+ kwargs={'quiz_id': self.exercise.id}),
data={
'description': 'updated demo exercise',
'active': True
@@ -1254,9 +1297,8 @@ class TestAddQuiz(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
-
- tzone = pytz.timezone('UTC')
- response = self.client.post(reverse('yaksh:add_exercise'),
+ response = self.client.post(
+ reverse('yaksh:add_exercise'),
data={
'description': "Demo Exercise",
'active': True
@@ -1328,8 +1370,10 @@ class TestAddTeacher(TestCase):
# Add to moderator group
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user
+ )
self.pre_req_quiz = Quiz.objects.create(
start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0, tzone),
@@ -1361,13 +1405,16 @@ class TestAddTeacher(TestCase):
"""
If not logged in redirect to login page
"""
- response = self.client.get(reverse('yaksh:add_teacher',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:add_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
- redirect_destination = ('/exam/login/?next=/exam'
- '/manage/addteacher/{0}/'.format(self.course.id))
+ redirect_destination = (
+ '/exam/login/?next=/exam/manage/addteacher/{0}/'.format(
+ self.course.id)
+ )
self.assertRedirects(response, redirect_destination)
def test_add_teacher_denies_non_moderator(self):
@@ -1379,9 +1426,10 @@ class TestAddTeacher(TestCase):
password=self.student_plaintext_pass
)
- response = self.client.get(reverse('yaksh:add_teacher',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:add_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
self.assertEqual(response.status_code, 404)
@@ -1394,9 +1442,10 @@ class TestAddTeacher(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:add_teacher',
- kwargs={'course_id': self.course.id}
- )
+ response = self.client.get(
+ reverse('yaksh:add_teacher',
+ kwargs={'course_id': self.course.id}
+ )
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/addteacher.html')
@@ -1422,7 +1471,7 @@ class TestAddTeacher(TestCase):
email='demo{}@test.com'.format(i)
)
- teacher_profile = Profile.objects.create(
+ Profile.objects.create(
user=teacher,
roll_number='T{}'.format(i),
institute='IIT',
@@ -1432,9 +1481,10 @@ class TestAddTeacher(TestCase):
)
teacher_id_list.append(teacher.id)
- response = self.client.post(reverse('yaksh:add_teacher',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.post(
+ reverse('yaksh:add_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
data={'check': teacher_id_list}
)
@@ -1486,7 +1536,8 @@ class TestRemoveTeacher(TestCase):
# Add to moderator group
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
+ self.course = Course.objects.create(
+ name="Python Course",
enrollment="Enroll Request", creator=self.user)
self.pre_req_quiz = Quiz.objects.create(
@@ -1506,6 +1557,7 @@ class TestRemoveTeacher(TestCase):
description='demo quiz', pass_criteria=40,
creator=self.user
)
+
def tearDown(self):
self.client.logout()
self.user.delete()
@@ -1518,13 +1570,16 @@ class TestRemoveTeacher(TestCase):
"""
If not logged in redirect to login page
"""
- response = self.client.get(reverse('yaksh:remove_teacher',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:remove_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
- redirect_destination = ('/exam/login/?next=/exam'
- '/manage/remove_teachers/{0}/'.format(self.course.id))
+ redirect_destination = (
+ '/exam/login/?next=/exam/manage/remove_teachers/{0}/'.format(
+ self.course.id)
+ )
self.assertRedirects(response, redirect_destination)
def test_remove_teacher_denies_non_moderator(self):
@@ -1536,9 +1591,10 @@ class TestRemoveTeacher(TestCase):
password=self.student_plaintext_pass
)
- response = self.client.get(reverse('yaksh:remove_teacher',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:remove_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
self.assertEqual(response.status_code, 404)
@@ -1562,7 +1618,7 @@ class TestRemoveTeacher(TestCase):
email='remove_teacher{}@test.com'.format(i)
)
- teacher_profile = Profile.objects.create(
+ Profile.objects.create(
user=teacher,
roll_number='RT{}'.format(i),
institute='IIT',
@@ -1573,16 +1629,17 @@ class TestRemoveTeacher(TestCase):
teacher_id_list.append(teacher.id)
self.course.teachers.add(teacher)
- response = self.client.post(reverse('yaksh:remove_teacher',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.post(
+ reverse('yaksh:remove_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
data={'remove': teacher_id_list}
)
self.assertEqual(response.status_code, 302)
redirect_destination = '/exam/manage/courses'
- self.assertRedirects(response, redirect_destination,
- status_code=302,
+ self.assertRedirects(
+ response, redirect_destination, status_code=302,
target_status_code=301
)
for t_id in teacher_id_list:
@@ -1715,11 +1772,8 @@ class TestCourses(TestCase):
"""
If not logged in redirect to login page
"""
- response = self.client.get(reverse('yaksh:courses'),
- follow=True
- )
- redirect_destination = ('/exam/login/?next=/exam'
- '/manage/courses/')
+ response = self.client.get(reverse('yaksh:courses'), follow=True)
+ redirect_destination = ('/exam/login/?next=/exam/manage/courses/')
self.assertRedirects(response, redirect_destination)
def test_courses_denies_non_moderator(self):
@@ -1731,9 +1785,7 @@ class TestCourses(TestCase):
password=self.student_plaintext_pass
)
- response = self.client.get(reverse('yaksh:courses'),
- follow=True
- )
+ response = self.client.get(reverse('yaksh:courses'), follow=True)
self.assertEqual(response.status_code, 404)
def test_courses_get(self):
@@ -1744,9 +1796,7 @@ class TestCourses(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.get(reverse('yaksh:courses'),
- follow=True
- )
+ response = self.client.get(reverse('yaksh:courses'), follow=True)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/courses.html')
@@ -2012,7 +2062,8 @@ class TestAddCourse(TestCase):
self.mod_group.user_set.add(self.user)
self.mod_group.user_set.add(self.teacher)
- self.course = Course.objects.create(name="Python Course",
+ self.course = Course.objects.create(
+ name="Python Course",
enrollment="Enroll Request", creator=self.user)
self.course.teachers.add(self.teacher)
@@ -2050,8 +2101,7 @@ class TestAddCourse(TestCase):
response = self.client.get(reverse('yaksh:add_course'),
follow=True
)
- redirect_destination = ('/exam/login/?next=/'
- 'exam/manage/add_course/')
+ redirect_destination = ('/exam/login/?next=/exam/manage/add_course/')
self.assertRedirects(response, redirect_destination)
def test_add_course_denies_non_moderator(self):
@@ -2062,10 +2112,7 @@ class TestAddCourse(TestCase):
username=self.student.username,
password=self.student_plaintext_pass
)
- course_id = self.course.id
- response = self.client.get(reverse('yaksh:add_course'),
- follow=True
- )
+ response = self.client.get(reverse('yaksh:add_course'), follow=True)
self.assertEqual(response.status_code, 404)
def test_add_course_get(self):
@@ -2090,13 +2137,14 @@ class TestAddCourse(TestCase):
password=self.user_plaintext_pass
)
- response = self.client.post(reverse('yaksh:add_course'),
+ response = self.client.post(
+ reverse('yaksh:add_course'),
data={'name': 'new_demo_course_1',
- 'active': True,
- 'enrollment': 'open',
- 'start_enroll_time': '2016-01-10 09:00:15',
- 'end_enroll_time': '2016-01-15 09:00:15',
- }
+ 'active': True,
+ 'enrollment': 'open',
+ 'start_enroll_time': '2016-01-10 09:00:15',
+ 'end_enroll_time': '2016-01-15 09:00:15',
+ }
)
new_course = Course.objects.latest('created_on')
self.assertEqual(new_course.name, 'new_demo_course_1')
@@ -2115,14 +2163,15 @@ class TestAddCourse(TestCase):
password=self.teacher_plaintext_pass
)
- response = self.client.post(reverse('yaksh:edit_course',
- kwargs={"course_id": self.course.id}),
+ response = self.client.post(
+ reverse('yaksh:edit_course',
+ kwargs={"course_id": self.course.id}),
data={'name': 'Teacher_course',
- 'active': True,
- 'enrollment': 'open',
- 'start_enroll_time': '2016-01-10 09:00:15',
- 'end_enroll_time': '2016-01-15 09:00:15',
- }
+ 'active': True,
+ 'enrollment': 'open',
+ 'start_enroll_time': '2016-01-10 09:00:15',
+ 'end_enroll_time': '2016-01-15 09:00:15',
+ }
)
updated_course = Course.objects.get(id=self.course.id)
self.assertEqual(updated_course.name, 'Teacher_course')
@@ -2200,8 +2249,9 @@ class TestCourseDetail(TestCase):
self.mod_group.user_set.add(self.user2)
self.user1_course = Course.objects.create(
- name="Python Course", enrollment="Enroll Request",
- creator=self.user1)
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user1
+ )
self.learning_module = LearningModule.objects.create(
name="test module", description="test description module",
html_data="test html description module", creator=self.user1,
@@ -2232,9 +2282,10 @@ class TestCourseDetail(TestCase):
upload_file = SimpleUploadedFile(csv_file_path, csv_file.read())
# When
- response = self.client.post(reverse('yaksh:upload_users',
- kwargs={'course_id': self.user1_course.id}),
- data={'csv_file': upload_file})
+ response = self.client.post(
+ reverse('yaksh:upload_users',
+ kwargs={'course_id': self.user1_course.id}),
+ data={'csv_file': upload_file})
csv_file.close()
# Then
@@ -2256,9 +2307,10 @@ class TestCourseDetail(TestCase):
upload_file = SimpleUploadedFile(csv_file_path, csv_file.read())
# When
- response = self.client.post(reverse('yaksh:upload_users',
- kwargs={'course_id': self.user1_course.id}),
- data={'csv_file': upload_file})
+ response = self.client.post(
+ reverse('yaksh:upload_users',
+ kwargs={'course_id': self.user1_course.id}),
+ data={'csv_file': upload_file})
csv_file.close()
# Then
@@ -2283,9 +2335,10 @@ class TestCourseDetail(TestCase):
message = "The file uploaded is not a CSV file."
# When
- response = self.client.post(reverse('yaksh:upload_users',
- kwargs={'course_id': self.user1_course.id}),
- data={'csv_file': upload_file})
+ response = self.client.post(
+ reverse('yaksh:upload_users',
+ kwargs={'course_id': self.user1_course.id}),
+ data={'csv_file': upload_file})
csv_file.close()
# Then
@@ -2301,15 +2354,17 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- csv_file_path = os.path.join(FIXTURES_DIR_PATH, "users_some_headers_missing.csv")
+ csv_file_path = os.path.join(FIXTURES_DIR_PATH,
+ "users_some_headers_missing.csv")
csv_file = open(csv_file_path, 'rb')
upload_file = SimpleUploadedFile(csv_file_path, csv_file.read())
message = "The CSV file does not contain the required headers"
# When
- response = self.client.post(reverse('yaksh:upload_users',
- kwargs={'course_id': self.user1_course.id}),
- data={'csv_file': upload_file})
+ response = self.client.post(
+ reverse('yaksh:upload_users',
+ kwargs={'course_id': self.user1_course.id}),
+ data={'csv_file': upload_file})
csv_file.close()
# Then
@@ -2325,21 +2380,24 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- csv_file_path = os.path.join(FIXTURES_DIR_PATH, "users_with_no_values.csv")
+ csv_file_path = os.path.join(FIXTURES_DIR_PATH,
+ "users_with_no_values.csv")
csv_file = open(csv_file_path, 'rb')
upload_file = SimpleUploadedFile(csv_file_path, csv_file.read())
# When
- response = self.client.post(reverse('yaksh:upload_users',
- kwargs={'course_id': self.user1_course.id}),
- data={'csv_file': upload_file})
+ response = self.client.post(
+ reverse('yaksh:upload_users',
+ kwargs={'course_id': self.user1_course.id}),
+ data={'csv_file': upload_file})
csv_file.close()
# Then
self.assertEqual(response.status_code, 200)
self.assertIn('upload_details', response.context)
self.assertNotIn('message', response.context)
- self.assertIn("No rows in the CSV file", response.context['upload_details'])
+ self.assertIn("No rows in the CSV file",
+ response.context['upload_details'])
self.assertTemplateUsed(response, 'yaksh/course_detail.html')
def test_upload_users_csv_with_missing_values(self):
@@ -2360,14 +2418,17 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- csv_file_path = os.path.join(FIXTURES_DIR_PATH, "users_some_values_missing.csv")
+ csv_file_path = os.path.join(FIXTURES_DIR_PATH,
+ "users_some_values_missing.csv")
csv_file = open(csv_file_path, 'rb')
upload_file = SimpleUploadedFile(csv_file_path, csv_file.read())
# When
- response = self.client.post(reverse('yaksh:upload_users',
- kwargs={'course_id': self.user1_course.id}),
- data={'csv_file': upload_file})
+ response = self.client.post(
+ reverse('yaksh:upload_users',
+ kwargs={'course_id': self.user1_course.id}),
+ data={'csv_file': upload_file}
+ )
csv_file.close()
# Then
@@ -2382,13 +2443,16 @@ class TestCourseDetail(TestCase):
"""
If not logged in redirect to login page
"""
- response = self.client.get(reverse('yaksh:course_detail',
- kwargs={'course_id': self.user1_course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:course_detail',
+ kwargs={'course_id': self.user1_course.id}
+ ),
follow=True
)
- redirect_destination = ('/exam/login/?next=/exam/'
- 'manage/course_detail/{0}/'.format(self.user1_course.id))
+ redirect_destination = (
+ '/exam/login/?next=/exam/manage/course_detail/{0}/'.format(
+ self.user1_course.id)
+ )
self.assertRedirects(response, redirect_destination)
def test_course_detail_denies_non_moderator(self):
@@ -2400,9 +2464,10 @@ class TestCourseDetail(TestCase):
password=self.student_plaintext_pass
)
- response = self.client.get(reverse('yaksh:course_detail',
- kwargs={'course_id': self.user1_course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:course_detail',
+ kwargs={'course_id': self.user1_course.id}
+ ),
follow=True
)
self.assertEqual(response.status_code, 404)
@@ -2415,9 +2480,10 @@ class TestCourseDetail(TestCase):
username=self.user2.username,
password=self.user2_plaintext_pass
)
- response = self.client.get(reverse('yaksh:course_detail',
- kwargs={'course_id': self.user1_course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:course_detail',
+ kwargs={'course_id': self.user1_course.id}
+ ),
follow=True
)
self.assertEqual(response.status_code, 404)
@@ -2430,9 +2496,10 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.get(reverse('yaksh:course_detail',
- kwargs={'course_id': self.user1_course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:course_detail',
+ kwargs={'course_id': self.user1_course.id}
+ ),
follow=True
)
self.assertEqual(self.user1_course, response.context['course'])
@@ -2447,7 +2514,8 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.get(reverse('yaksh:enroll_user',
+ response = self.client.get(
+ reverse('yaksh:enroll_user',
kwargs={'course_id': self.user1_course.id,
'user_id': self.student.id})
)
@@ -2463,10 +2531,11 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.post(reverse('yaksh:enroll_users',
+ response = self.client.post(
+ reverse('yaksh:enroll_users',
kwargs={'course_id': self.user1_course.id}),
- data={'check': self.student1.id}
- )
+ data={'check': self.student1.id}
+ )
enrolled_student = self.user1_course.students.all()
self.assertEqual(response.status_code, 200)
self.assertSequenceEqual([self.student1], enrolled_student)
@@ -2479,7 +2548,8 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.get(reverse('yaksh:reject_user',
+ response = self.client.get(
+ reverse('yaksh:reject_user',
kwargs={'course_id': self.user1_course.id,
'user_id': self.student.id})
)
@@ -2495,10 +2565,11 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.post(reverse('yaksh:reject_users',
+ response = self.client.post(
+ reverse('yaksh:reject_users',
kwargs={'course_id': self.user1_course.id}),
- data={'check': self.student1.id}
- )
+ data={'check': self.student1.id}
+ )
enrolled_student = self.user1_course.rejected.all()
self.assertEqual(response.status_code, 200)
self.assertSequenceEqual([self.student1], enrolled_student)
@@ -2508,9 +2579,10 @@ class TestCourseDetail(TestCase):
username=self.user1.username,
password=self.user1_plaintext_pass
)
- response = self.client.post(reverse('yaksh:toggle_course_status',
+ response = self.client.post(
+ reverse('yaksh:toggle_course_status',
kwargs={'course_id': self.user1_course.id})
- )
+ )
self.assertEqual(response.status_code, 302)
course = Course.objects.get(name="Python Course")
self.assertFalse(course.active)
@@ -2671,10 +2743,11 @@ class TestCourseDetail(TestCase):
response = self.client.get(reverse('yaksh:get_user_data',
kwargs={'course_id': self.user1_course.id,
'student_id': self.student.id}))
- err_msg = response.json()['user_data'].replace("\n", "").strip()
- actual_err = dedent("""\
- You are neither course creator nor course teacher for {0}""".format(
- self.user1_course.name))
+ err_msg = response.json()['user_data'].strip()
+ actual_err = ('You are neither course creator '
+ 'nor course teacher for {0}'.format(
+ self.user1_course.name)
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(err_msg, actual_err)
@@ -2750,8 +2823,10 @@ class TestEnrollRequest(TestCase):
self.mod_group.user_set.add(self.user1)
self.mod_group.user_set.add(self.user2)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user1)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user1
+ )
def tearDown(self):
self.client.logout()
@@ -2764,13 +2839,16 @@ class TestEnrollRequest(TestCase):
"""
If not logged in redirect to login page
"""
- response = self.client.get(reverse('yaksh:enroll_request',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:enroll_request',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
- redirect_destination = ('/exam/login/?next=/exam'
- '/enroll_request/{}/'.format(self.course.id))
+ redirect_destination = (
+ '/exam/login/?next=/exam/enroll_request/{}/'.format(
+ self.course.id)
+ )
self.assertRedirects(response, redirect_destination)
def test_enroll_request_get_for_student(self):
@@ -2779,9 +2857,10 @@ class TestEnrollRequest(TestCase):
password=self.student_plaintext_pass
)
- response = self.client.get(reverse('yaksh:enroll_request',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:enroll_request',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
self.assertRedirects(response, '/exam/quizzes/')
@@ -2792,9 +2871,10 @@ class TestEnrollRequest(TestCase):
password=self.user2_plaintext_pass
)
- response = self.client.get(reverse('yaksh:enroll_request',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:enroll_request',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
self.assertRedirects(response, '/exam/manage/courses/')
@@ -2816,26 +2896,31 @@ class TestViewAnswerPaper(TestCase):
self.user1 = User.objects.get(username="demo_user1")
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request",
- creator=self.user1)
+ self.course = Course.objects.create(
+ name="Python Course", enrollment="Enroll Request",
+ creator=self.user1
+ )
- self.question = Question.objects.create(summary='Dummy', points=1,
- type='code', user=self.user1)
+ self.question = Question.objects.create(
+ summary='Dummy', points=1,
+ type='code', user=self.user1
+ )
self.quiz = Quiz.objects.create(time_between_attempts=0,
description='demo quiz')
self.user3 = User.objects.get(username="demo_user3")
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
- total_marks=1.0)
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz, total_marks=1.0
+ )
self.question_paper.fixed_questions.add(self.question)
self.question_paper.save()
- self.ans_paper = AnswerPaper.objects.create(user=self.user3,
- attempt_number=1, question_paper=self.question_paper,
- start_time=timezone.now(), user_ip='101.0.0.1',
- end_time=timezone.now()+timezone.timedelta(minutes=20),
- course=self.course)
+ self.ans_paper = AnswerPaper.objects.create(
+ user=self.user3, attempt_number=1,
+ question_paper=self.question_paper, start_time=timezone.now(),
+ user_ip='101.0.0.1', course=self.course,
+ end_time=timezone.now()+timezone.timedelta(minutes=20)
+ )
def tearDown(self):
User.objects.all().delete()
@@ -2847,15 +2932,17 @@ class TestViewAnswerPaper(TestCase):
def test_anonymous_user(self):
# Given, user not logged in
- redirect_destination = ('/exam/login/?next=/exam'
- '/view_answerpaper/{0}/{1}'.format(
- self.question_paper.id, self.course.id))
+ redirect_destination = (
+ '/exam/login/?next=/exam/view_answerpaper/{0}/{1}'.format(
+ self.question_paper.id, self.course.id)
+ )
# When
- response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': self.question_paper.id,
- 'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:view_answerpaper',
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
+ ),
follow=True
)
@@ -2875,10 +2962,11 @@ class TestViewAnswerPaper(TestCase):
)
# When
- response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': self.question_paper.id,
- 'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:view_answerpaper',
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
+ ),
follow=True
)
@@ -2890,7 +2978,6 @@ class TestViewAnswerPaper(TestCase):
user3 = User.objects.get(username="demo_user3")
self.course.students.add(user3)
self.course.save()
- answerpaper = AnswerPaper.objects.get(pk=self.ans_paper.id)
self.quiz.view_answerpaper = True
self.quiz.save()
self.client.login(
@@ -2899,10 +2986,11 @@ class TestViewAnswerPaper(TestCase):
)
# When
- response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': self.question_paper.id,
- 'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:view_answerpaper',
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
+ ),
follow=True
)
@@ -2912,19 +3000,18 @@ class TestViewAnswerPaper(TestCase):
self.assertTrue('quiz' in response.context)
self.assertTemplateUsed(response, 'yaksh/view_answerpaper.html')
-
# When, wrong question paper id
- response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': 190,
- 'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:view_answerpaper',
+ kwargs={'questionpaper_id': 190,
+ 'course_id': self.course.id}
+ ),
follow=True
)
# Then
self.assertEqual(response.status_code, 404)
-
def test_view_when_not_enrolled(self):
# Given, user tries to view when not enrolled in the course
user2 = User.objects.get(username="demo_user2")
@@ -2938,10 +3025,11 @@ class TestViewAnswerPaper(TestCase):
self.quiz.save()
# When
- response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': self.question_paper.id,
- 'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:view_answerpaper',
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
+ ),
follow=True
)
@@ -3004,8 +3092,10 @@ class TestSelfEnroll(TestCase):
self.mod_group.user_set.add(self.user1)
self.mod_group.user_set.add(self.user2)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user1)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user1
+ )
def tearDown(self):
self.client.logout()
@@ -3015,13 +3105,15 @@ class TestSelfEnroll(TestCase):
self.course.delete()
def test_self_enroll_denies_anonymous(self):
- response = self.client.get(reverse('yaksh:self_enroll',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:self_enroll',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
- redirect_destination = ('/exam/login/?next=/exam'
- '/self_enroll/{}/'.format(self.course.id))
+ redirect_destination = (
+ '/exam/login/?next=/exam/self_enroll/{}/'.format(self.course.id)
+ )
self.assertRedirects(response, redirect_destination)
def test_enroll_request_get_for_student(self):
@@ -3030,9 +3122,10 @@ class TestSelfEnroll(TestCase):
password=self.student_plaintext_pass
)
- response = self.client.get(reverse('yaksh:self_enroll',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:self_enroll',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
self.assertRedirects(response, '/exam/quizzes/')
@@ -3043,9 +3136,10 @@ class TestSelfEnroll(TestCase):
password=self.user2_plaintext_pass
)
- response = self.client.get(reverse('yaksh:self_enroll',
- kwargs={'course_id': self.course.id}
- ),
+ response = self.client.get(
+ reverse('yaksh:self_enroll',
+ kwargs={'course_id': self.course.id}
+ ),
follow=True
)
self.assertRedirects(response, '/exam/manage/')
@@ -3108,25 +3202,30 @@ class TestGrader(TestCase):
self.mod_group.user_set.add(self.user1)
self.mod_group.user_set.add(self.user2)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user1)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user1
+ )
- self.question = Question.objects.create(summary='Dummy', points=1,
- type='code', user=self.user1)
+ self.question = Question.objects.create(
+ summary='Dummy', points=1, type='code', user=self.user1
+ )
self.quiz = Quiz.objects.create(time_between_attempts=0,
description='demo quiz')
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
- total_marks=1.0)
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz, total_marks=1.0
+ )
self.question_paper.fixed_questions.add(self.question)
self.question_paper.save()
- self.answerpaper = AnswerPaper.objects.create(user=self.user2,
- attempt_number=1, question_paper=self.question_paper,
- start_time=timezone.now(), user_ip='101.0.0.1',
- end_time=timezone.now()+timezone.timedelta(minutes=20),
- course=self.course)
+ self.answerpaper = AnswerPaper.objects.create(
+ user=self.user2, attempt_number=1,
+ question_paper=self.question_paper, start_time=timezone.now(),
+ user_ip='101.0.0.1', course=self.course,
+ end_time=timezone.now()+timezone.timedelta(minutes=20),
+ )
def tearDown(self):
User.objects.all().delete()
@@ -3146,7 +3245,6 @@ class TestGrader(TestCase):
# Then
self.assertRedirects(response, redirect_destination)
-
def test_grader_denies_students(self):
# Given
self.client.login(
@@ -3160,25 +3258,26 @@ class TestGrader(TestCase):
# Then
self.assertEqual(response.status_code, 404)
-
def test_regrade_denies_anonymous(self):
# Given
- redirect_destination = dedent('''\
- /exam/login/?next=/exam/manage/regrade/answerpaper/{}/{}/{}/'''.format(
+ url = "/exam/login/?next=/exam/manage/regrade/answerpaper"
+ redirect_destination = (
+ url + "/{}/{}/{}/".format(
self.course.id, self.question.id, self.answerpaper.id)
)
# When
- response = self.client.get(reverse('yaksh:regrade',
- kwargs={'course_id': self.course.id,
- 'question_id': self.question.id,
- 'answerpaper_id': self.answerpaper.id}),
- follow=True)
+ response = self.client.get(
+ reverse('yaksh:regrade',
+ kwargs={'course_id': self.course.id,
+ 'question_id': self.question.id,
+ 'answerpaper_id': self.answerpaper.id}),
+ follow=True
+ )
# Then
self.assertRedirects(response, redirect_destination)
-
def test_regrade_denies_students(self):
# Given
self.client.login(
@@ -3187,16 +3286,17 @@ class TestGrader(TestCase):
)
# When
- response = self.client.get(reverse('yaksh:regrade',
- kwargs={'course_id': self.course.id,
- 'question_id': self.question.id,
- 'answerpaper_id': self.answerpaper.id}),
- follow=True)
+ response = self.client.get(
+ reverse('yaksh:regrade',
+ kwargs={'course_id': self.course.id,
+ 'question_id': self.question.id,
+ 'answerpaper_id': self.answerpaper.id}),
+ follow=True
+ )
# Then
self.assertEqual(response.status_code, 404)
-
def test_grader_by_moderator(self):
# Given
self.client.login(
@@ -3205,15 +3305,13 @@ class TestGrader(TestCase):
)
# When
- response = self.client.get(reverse('yaksh:grader'),
- follow=True)
+ response = self.client.get(reverse('yaksh:grader'), follow=True)
# Then
self.assertEqual(response.status_code, 200)
self.assertTrue('courses' in response.context)
self.assertTemplateUsed(response, 'yaksh/regrade.html')
-
def test_regrade_by_moderator(self):
# Given
self.client.login(
@@ -3222,10 +3320,24 @@ class TestGrader(TestCase):
)
# When
- response = self.client.get(reverse('yaksh:regrade',
- kwargs={'course_id': self.course.id,
- 'question_id': self.question.id,
- 'answerpaper_id': self.answerpaper.id}),
+ response = self.client.get(
+ reverse('yaksh:regrade',
+ kwargs={'course_id': self.course.id,
+ 'question_id': self.question.id,
+ 'answerpaper_id': self.answerpaper.id}),
+ follow=True)
+
+ # Then
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue('courses' in response.context)
+ self.assertTrue('details' in response.context)
+ self.assertTemplateUsed(response, 'yaksh/regrade.html')
+
+ # When
+ response = self.client.get(
+ reverse('yaksh:regrade',
+ kwargs={'course_id': self.course.id,
+ 'answerpaper_id': self.answerpaper.id}),
follow=True)
# Then
@@ -3234,6 +3346,19 @@ class TestGrader(TestCase):
self.assertTrue('details' in response.context)
self.assertTemplateUsed(response, 'yaksh/regrade.html')
+ # When
+ response = self.client.get(
+ reverse('yaksh:regrade',
+ kwargs={'course_id': self.course.id,
+ 'question_id': self.question.id,
+ 'questionpaper_id': self.question_paper.id}),
+ follow=True)
+
+ # Then
+ self.assertEqual(response.status_code, 200)
+ self.assertTrue('courses' in response.context)
+ self.assertTrue('details' in response.context)
+ self.assertTemplateUsed(response, 'yaksh/regrade.html')
def test_regrade_denies_moderator_not_in_course(self):
# Given
@@ -3242,15 +3367,19 @@ class TestGrader(TestCase):
password=self.user2_plaintext_pass
)
+ self.mod_group.user_set.remove(self.user2)
# When
- response = self.client.get(reverse('yaksh:regrade',
- kwargs={'course_id': self.course.id,
- 'question_id': self.question.id,
- 'answerpaper_id': self.answerpaper.id}),
+ response = self.client.get(
+ reverse('yaksh:regrade',
+ kwargs={'course_id': self.course.id,
+ 'question_id': self.question.id,
+ 'answerpaper_id': self.answerpaper.id}),
follow=True)
# Then
self.assertEqual(response.status_code, 404)
+ self.mod_group.user_set.add(self.user2)
+
class TestPasswordReset(TestCase):
def setUp(self):
@@ -3281,7 +3410,8 @@ class TestPasswordReset(TestCase):
POST request to password_reset view should return a valid response
"""
# When
- response = self.client.post(reverse('password_reset'),
+ response = self.client.post(
+ reverse('password_reset'),
data={
'email': self.user1.email,
}
@@ -3303,7 +3433,8 @@ class TestPasswordReset(TestCase):
)
# When
- response = self.client.post(reverse('password_change'),
+ response = self.client.post(
+ reverse('password_change'),
data={
'old_password': self.user1_plaintext_pass,
'new_password1': 'new_demo1_pass',
@@ -3312,7 +3443,8 @@ class TestPasswordReset(TestCase):
)
# Then
- self.assertIsNotNone(authenticate(username='demo_user1', password='new_demo1_pass'))
+ self.assertIsNotNone(authenticate(username='demo_user1',
+ password='new_demo1_pass'))
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, '/exam/reset/password_change/done/')
@@ -3373,8 +3505,10 @@ class TestModeratorDashboard(TestCase):
)
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user
+ )
self.quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
@@ -3390,15 +3524,18 @@ class TestModeratorDashboard(TestCase):
points=1.0, language="python", type="code", user=self.user
)
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz,
total_marks=1.0, fixed_question_order=str(self.question.id)
)
self.question_paper.fixed_questions.add(self.question)
# student answerpaper
user_answer = "def add(a, b)\n\treturn a+b"
- self.new_answer = Answer(question=self.question, answer=user_answer,
- correct=True, error=json.dumps([]), marks=0.5)
+ self.new_answer = Answer(
+ question=self.question, answer=user_answer,
+ correct=True, error=json.dumps([]), marks=0.5
+ )
self.new_answer.save()
self.answerpaper = AnswerPaper.objects.create(
user=self.student, question_paper=self.question_paper,
@@ -3413,8 +3550,10 @@ class TestModeratorDashboard(TestCase):
self.answerpaper.questions.add(self.question)
# moderator trial answerpaper
- self.trial_course = Course.objects.create(name="Trial Course",
- enrollment="Enroll Request", creator=self.user, is_trial=True)
+ self.trial_course = Course.objects.create(
+ name="Trial Course",
+ enrollment="Enroll Request", creator=self.user, is_trial=True
+ )
self.trial_quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone),
@@ -3430,8 +3569,10 @@ class TestModeratorDashboard(TestCase):
)
self.trial_question_paper.fixed_questions.add(self.question)
- self.new_answer1 = Answer(question=self.question, answer=user_answer,
- correct=True, error=json.dumps([]), marks=0.5)
+ self.new_answer1 = Answer(
+ question=self.question, answer=user_answer,
+ correct=True, error=json.dumps([]), marks=0.5
+ )
self.new_answer1.save()
self.trial_answerpaper = AnswerPaper.objects.create(
user=self.user, question_paper=self.trial_question_paper,
@@ -3499,12 +3640,11 @@ class TestModeratorDashboard(TestCase):
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:manage'),
- follow=True
- )
+ response = self.client.get(reverse('yaksh:manage'), follow=True)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/moderator_dashboard.html")
- self.assertEqual(response.context['trial_paper'][0], self.trial_answerpaper)
+ self.assertEqual(response.context['trial_paper'][0],
+ self.trial_answerpaper)
self.assertEqual(response.context['courses'][0], self.course)
def test_moderator_dashboard_delete_trial_papers(self):
@@ -3515,16 +3655,17 @@ class TestModeratorDashboard(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- self.course.is_trial=True
+ self.course.is_trial = True
self.course.save()
- response = self.client.post(reverse('yaksh:manage'),
- data={'delete_paper': [self.trial_answerpaper.id]}
- )
+ response = self.client.post(
+ reverse('yaksh:manage'),
+ data={'delete_paper': [self.trial_answerpaper.id]}
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/moderator_dashboard.html")
updated_answerpaper = AnswerPaper.objects.filter(user=self.user)
- updated_quiz = Quiz.objects.filter(
+ updated_quiz = Quiz.objects.filter(
description=self.trial_question_paper.quiz.description
)
updated_course = Course.objects.filter(
@@ -3533,6 +3674,7 @@ class TestModeratorDashboard(TestCase):
self.assertSequenceEqual(updated_quiz, [])
self.assertSequenceEqual(updated_course, [])
+
class TestUserLogin(TestCase):
def setUp(self):
self.client = Client()
@@ -3565,10 +3707,11 @@ class TestUserLogin(TestCase):
"""
Check if user is successfully logged in
"""
- response = self.client.post(reverse('yaksh:login'),
- data={'username': self.user1.username,
- 'password': self.user1_plaintext_pass}
- )
+ response = self.client.post(
+ reverse('yaksh:login'),
+ data={'username': self.user1.username,
+ 'password': self.user1_plaintext_pass}
+ )
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, '/exam/quizzes/')
@@ -3588,10 +3731,11 @@ class TestUserLogin(TestCase):
Check email verified decorator to check for user login
"""
settings.IS_DEVELOPMENT = False
- response = self.client.post(reverse('yaksh:login'),
- data={'username': self.user1.username,
- 'password': self.user1_plaintext_pass}
- )
+ response = self.client.post(
+ reverse('yaksh:login'),
+ data={'username': self.user1.username,
+ 'password': self.user1_plaintext_pass}
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/activation_status.html")
@@ -3639,8 +3783,10 @@ class TestDownloadcsv(TestCase):
timezone='UTC'
)
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Enroll Request", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Enroll Request", creator=self.user
+ )
self.course.students.add(self.student)
self.quiz = Quiz.objects.create(
@@ -3657,15 +3803,18 @@ class TestDownloadcsv(TestCase):
points=1.0, language="python", type="code", user=self.user
)
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz,
total_marks=1.0, fixed_question_order=str(self.question.id)
)
self.question_paper.fixed_questions.add(self.question)
# student answerpaper
user_answer = "def add(a, b)\n\treturn a+b"
- self.new_answer = Answer(question=self.question, answer=user_answer,
- correct=True, error=json.dumps([]), marks=0.5)
+ self.new_answer = Answer(
+ question=self.question, answer=user_answer,
+ correct=True, error=json.dumps([]), marks=0.5
+ )
self.new_answer.save()
self.answerpaper = AnswerPaper.objects.create(
user=self.student, question_paper=self.question_paper,
@@ -3754,14 +3903,15 @@ class TestDownloadcsv(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:download_course_csv',
- kwargs={'course_id': self.course.id}),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:download_course_csv',
+ kwargs={'course_id': self.course.id}),
+ follow=True
+ )
file_name = "{0}.csv".format(self.course.name.lower())
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get('Content-Disposition'),
- 'attachment; filename="{0}"'.format(file_name))
+ 'attachment; filename="{0}"'.format(file_name))
def test_download_quiz_csv(self):
"""
@@ -3771,23 +3921,24 @@ class TestDownloadcsv(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:download_quiz_csv',
- kwargs={"course_id": self.course.id,
- "quiz_id": self.quiz.id}),
-
- follow=True
- )
- file_name = "{0}-{1}-attempt{2}.csv".format(self.course.name.replace('.', ''),
- self.quiz.description.replace('.', ''), 1)
+ response = self.client.get(
+ reverse('yaksh:download_quiz_csv',
+ kwargs={"course_id": self.course.id,
+ "quiz_id": self.quiz.id}),
+ follow=True
+ )
+ file_name = "{0}-{1}-attempt{2}.csv".format(
+ self.course.name.replace('.', ''),
+ self.quiz.description.replace('.', ''), 1
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get('Content-Disposition'),
- 'attachment; filename="{0}"'.format(file_name))
+ 'attachment; filename="{0}"'.format(file_name))
class TestShowQuestions(TestCase):
def setUp(self):
self.client = Client()
- tzone = pytz.timezone("utc")
self.mod_group = Group.objects.create(name='moderator')
# student
self.student_plaintext_pass = 'student'
@@ -3859,9 +4010,9 @@ class TestShowQuestions(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:show_questions'),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:show_questions'), follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/showquestions.html')
self.assertEqual(response.context['questions'][0], self.question)
@@ -3874,14 +4025,15 @@ class TestShowQuestions(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.post(reverse('yaksh:show_questions'),
- data={'question': [self.question.id],
- 'download': 'download'}
- )
+ response = self.client.post(
+ reverse('yaksh:show_questions'),
+ data={'question': [self.question.id],
+ 'download': 'download'}
+ )
file_name = "{0}_questions.zip".format(self.user)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get('Content-Disposition'),
- "attachment; filename={0}".format(file_name))
+ "attachment; filename={0}".format(file_name))
zip_file = string_io(response.content)
zipped_file = zipfile.ZipFile(zip_file, 'r')
self.assertIsNone(zipped_file.testzip())
@@ -3889,15 +4041,15 @@ class TestShowQuestions(TestCase):
zip_file.close()
zipped_file.close()
- response = self.client.post(reverse('yaksh:show_questions'),
- data={'question': [],
- 'download': 'download'}
- )
+ response = self.client.post(
+ reverse('yaksh:show_questions'),
+ data={'question': [],
+ 'download': 'download'}
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/showquestions.html')
self.assertIn("download", response.context['msg'])
-
def test_upload_questions(self):
"""
Check for uploading questions zip file
@@ -3908,30 +4060,32 @@ class TestShowQuestions(TestCase):
)
ques_file = os.path.join(FIXTURES_DIR_PATH, "demo_questions.zip")
f = open(ques_file, 'rb')
- questions_file = SimpleUploadedFile(ques_file, f.read(),
+ questions_file = SimpleUploadedFile(ques_file, f.read(),
content_type="application/zip")
- response = self.client.post(reverse('yaksh:show_questions'),
- data={'file': questions_file,
- 'upload': 'upload'}
- )
+ response = self.client.post(
+ reverse('yaksh:show_questions'),
+ data={'file': questions_file,
+ 'upload': 'upload'}
+ )
summaries = ['Roots of quadratic equation', 'Print Output',
'Adding decimals', 'For Loop over String',
'Hello World in File', 'Extract columns from files',
'Check Palindrome', 'Add 3 numbers', 'Reverse a string'
]
- uploaded_ques = Question.objects.filter(active=True,
- summary__in=summaries,
- user=self.user).count()
+ uploaded_ques = Question.objects.filter(
+ active=True, summary__in=summaries,
+ user=self.user).count()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/showquestions.html')
self.assertEqual(uploaded_ques, 9)
f.close()
dummy_file = SimpleUploadedFile("test.txt", b"test")
- response = self.client.post(reverse('yaksh:show_questions'),
- data={'file': dummy_file,
- 'upload': 'upload'}
- )
+ response = self.client.post(
+ reverse('yaksh:show_questions'),
+ data={'file': dummy_file,
+ 'upload': 'upload'}
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/showquestions.html')
self.assertIn("ZIP file", response.context['message'])
@@ -3944,10 +4098,11 @@ class TestShowQuestions(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.post(reverse('yaksh:show_questions'),
- data={'question': [self.question.id],
- 'test': 'test'}
- )
+ response = self.client.post(
+ reverse('yaksh:show_questions'),
+ data={'question': [self.question.id],
+ 'test': 'test'}
+ )
trial_que_paper = QuestionPaper.objects.get(
quiz__description="trial_questions"
)
@@ -3961,18 +4116,19 @@ class TestShowQuestions(TestCase):
def test_ajax_questions_filter(self):
"""
- Check for filter questions based type, marks and
+ Check for filter questions based type, marks and
language of a question
"""
self.client.login(
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.post(reverse('yaksh:questions_filter'),
- data={'question_type': 'mcq',
- 'marks': '1.0', 'language': 'python'
- }
- )
+ response = self.client.post(
+ reverse('yaksh:questions_filter'),
+ data={'question_type': 'mcq',
+ 'marks': '1.0', 'language': 'python'
+ }
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/ajax_question_filter.html')
self.assertEqual(response.context['questions'][0], self.question1)
@@ -3998,6 +4154,37 @@ class TestShowQuestions(TestCase):
self.assertEqual(response.get('Content-Disposition'),
'attachment; filename="questions_dump.yaml"')
+ def test_delete_questions(self):
+ """ Test to check if questions are set to not active when deleted """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.post(
+ reverse('yaksh:show_questions'),
+ data={'question': [self.question.id],
+ 'delete': 'delete'}
+ )
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/showquestions.html')
+ updated_que = Question.objects.get(id=self.question.id)
+ self.assertFalse(updated_que.active)
+
+ def test_search_tags(self):
+ """ Test to check if questions are obtained with tags """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ self.question.tags.add('code')
+ response = self.client.post(
+ reverse('yaksh:show_questions'),
+ data={'question_tags': ['code']}
+ )
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/showquestions.html')
+ self.assertEqual(response.context['questions'][0], self.question)
+
class TestShowStatistics(TestCase):
def setUp(self):
@@ -4046,8 +4233,10 @@ class TestShowStatistics(TestCase):
# Add to moderator group
self.mod_group.user_set.add(self.user)
- self.course = Course.objects.create(name="Python Course",
- enrollment="Open Enrollment", creator=self.user)
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Open Enrollment", creator=self.user
+ )
self.quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
@@ -4063,13 +4252,16 @@ class TestShowStatistics(TestCase):
points=1.0, language="python", type="code", user=self.user
)
- self.question_paper = QuestionPaper.objects.create(quiz=self.quiz,
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz,
total_marks=1.0, fixed_question_order=str(self.question)
)
self.question_paper.fixed_questions.add(self.question)
user_answer = "def add(a, b)\n\treturn a+b"
- self.new_answer = Answer(question=self.question, answer=user_answer,
- correct=True, error=json.dumps([]))
+ self.new_answer = Answer(
+ question=self.question, answer=user_answer,
+ correct=True, error=json.dumps([])
+ )
self.new_answer.save()
self.answerpaper = AnswerPaper.objects.create(
user=self.student, question_paper=self.question_paper,
@@ -4102,11 +4294,12 @@ class TestShowStatistics(TestCase):
username=self.student.username,
password=self.student_plaintext_pass
)
- response = self.client.get(reverse('yaksh:show_statistics',
- kwargs={"questionpaper_id": self.question_paper.id,
- "course_id": self.course.id}),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:show_statistics',
+ kwargs={"questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id}),
+ follow=True
+ )
self.assertEqual(response.status_code, 404)
def test_show_statistics_for_student(self):
@@ -4117,18 +4310,19 @@ class TestShowStatistics(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:show_statistics',
- kwargs={'questionpaper_id': self.question_paper.id,
- "course_id": self.course.id}),
- follow=True
- )
+ response = self.client.get(
+ reverse('yaksh:show_statistics',
+ kwargs={'questionpaper_id': self.question_paper.id,
+ "course_id": self.course.id}),
+ follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/statistics_question.html')
self.assertEqual(response.context['quiz'], self.quiz)
self.assertEqual(response.context['attempts'][0],
- self.answerpaper.attempt_number)
+ self.answerpaper.attempt_number)
self.assertEqual(response.context['questionpaper_id'],
- str(self.question_paper.id))
+ str(self.question_paper.id))
def test_show_statistics_for_student_per_attempt(self):
"""
@@ -4138,16 +4332,18 @@ class TestShowStatistics(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:show_statistics',
+ response = self.client.get(
+ reverse('yaksh:show_statistics',
kwargs={'questionpaper_id': self.question_paper.id,
'attempt_number': self.answerpaper.attempt_number,
"course_id": self.course.id}),
- follow=True
- )
+ follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/statistics_question.html')
- self.assertSequenceEqual(response.context['question_stats'][self.question],
- [1, 1])
+ self.assertSequenceEqual(
+ response.context['question_stats'][self.question], [1, 1]
+ )
self.assertEqual(response.context['attempts'][0], 1)
self.assertEqual(response.context['total'], 1)
@@ -4247,6 +4443,16 @@ class TestQuestionPaper(TestCase):
self.learning_module.learning_unit.add(self.learning_unit.id)
self.course.learning_module.add(self.learning_module)
+ # Questions for random set
+ self.random_que1 = Question.objects.create(
+ summary="Random 1", description="Test Random 1",
+ points=1.0, language="python", type="code", user=self.user
+ )
+ self.random_que2 = Question.objects.create(
+ summary="Random 2", description="Test Random 2",
+ points=1.0, language="python", type="code", user=self.user
+ )
+
# Mcq Question
self.question_mcq = Question.objects.create(
summary="Test_mcq_question", description="Test MCQ",
@@ -4359,8 +4565,8 @@ class TestQuestionPaper(TestCase):
response = self.client.get(
reverse('yaksh:preview_questionpaper',
kwargs={"questionpaper_id": self.question_paper.id}
+ )
)
- )
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/preview_questionpaper.html')
self.assertEqual(
@@ -4379,8 +4585,8 @@ class TestQuestionPaper(TestCase):
response = self.client.get(
reverse('yaksh:preview_questionpaper',
kwargs={"questionpaper_id": self.question_paper.id}
+ )
)
- )
self.assertEqual(response.status_code, 404)
def test_preview_qustionpaper_without_quiz_owner(self):
@@ -4393,8 +4599,8 @@ class TestQuestionPaper(TestCase):
response = self.client.get(
reverse('yaksh:preview_questionpaper',
kwargs={"questionpaper_id": self.question_paper.id}
+ )
)
- )
self.assertEqual(response.status_code, 404)
def test_mcq_attempt_right_after_wrong(self):
@@ -4713,6 +4919,23 @@ class TestQuestionPaper(TestCase):
self.questions_list)
self.assertEqual(response.context['qpaper'], self.question_paper)
+ response = self.client.post(
+ reverse('yaksh:designquestionpaper',
+ kwargs={"quiz_id": self.quiz.id,
+ "course_id": self.course.id,
+ "questionpaper_id": self.question_paper.id}),
+ data={'random_questions': [self.random_que1.id,
+ self.random_que2.id],
+ 'marks': ['1.0'], 'question_type': ['code'],
+ 'add-random': ['']}
+ )
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/design_questionpaper.html')
+ random_set = response.context['random_sets'][0]
+ added_random_ques = random_set.questions.all()
+ self.assertIn(self.random_que1, added_random_ques)
+ self.assertIn(self.random_que2, added_random_ques)
+
class TestLearningModule(TestCase):
def setUp(self):
diff --git a/yaksh/tests/test_code_server.py b/yaksh/tests/test_code_server.py
index e2781df..8237256 100644
--- a/yaksh/tests/test_code_server.py
+++ b/yaksh/tests/test_code_server.py
@@ -128,10 +128,9 @@ class TestCodeServer(unittest.TestCase):
# With correct answer and test case
testdata["metadata"]["user_answer"] = 'def f(): return 2'
testdata["test_case_data"] = [{'test_case': 'assert f() == 2',
- 'test_case_type': 'standardtestcase',
- 'weight': 0.0
- }
- ]
+ 'test_case_type': 'standardtestcase',
+ 'weight': 0.0
+ }]
# When
submit(self.url, '0', json.dumps(testdata), '')
result = get_result(self.url, '0', block=True)
diff --git a/yaksh/urls.py b/yaksh/urls.py
index 2af1e70..1e1def6 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -9,47 +9,54 @@ urlpatterns = [
url(r'^activate/(?P<key>.+)$', views.activate_user, name="activate"),
url(r'^new_activation/$', views.new_activation, name='new_activation'),
url(r'^quizzes/$', views.quizlist_user, name='quizlist_user'),
- url(r'^quizzes/(?P<enrolled>\w+)/$', views.quizlist_user, name='quizlist_user'),
+ url(r'^quizzes/(?P<enrolled>\w+)/$', views.quizlist_user,
+ name='quizlist_user'),
url(r'^results/$', views.results_user),
- url(r'^start/(?P<questionpaper_id>\d+)/(?P<module_id>\d+)/(?P<course_id>\d+)/$',
- views.start),
- url(r'^start/(?P<attempt_num>\d+)/(?P<module_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
- views.start),
- url(r'^quit/(?P<attempt_num>\d+)/(?P<module_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
- views.quit),
+ url(r'^start/(?P<questionpaper_id>\d+)/(?P<module_id>\d+)/'
+ '(?P<course_id>\d+)/$', views.start),
+ url(r'^start/(?P<attempt_num>\d+)/(?P<module_id>\d+)/'
+ '(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$', views.start),
+ url(r'^quit/(?P<attempt_num>\d+)/(?P<module_id>\d+)/'
+ '(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$', views.quit),
url(r'^complete/$', views.complete),
- url(r'^complete/(?P<attempt_num>\d+)/(?P<module_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',\
- views.complete),
+ url(r'^complete/(?P<attempt_num>\d+)/(?P<module_id>\d+)/'
+ '(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$', views.complete),
url(r'^register/$', views.user_register, name="register"),
url(r'^(?P<q_id>\d+)/check/$', views.check, name="check"),
url(r'^get_result/(?P<uid>\d+)/(?P<course_id>\d+)/(?P<module_id>\d+)/$',
views.get_result),
- url(r'^(?P<q_id>\d+)/check/(?P<attempt_num>\d+)/(?P<module_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',\
- views.check, name="check"),
- url(r'^(?P<q_id>\d+)/skip/(?P<attempt_num>\d+)/(?P<module_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
+ url(r'^(?P<q_id>\d+)/check/(?P<attempt_num>\d+)/(?P<module_id>\d+)/'
+ '(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
+ views.check, name="check"),
+ url(r'^(?P<q_id>\d+)/skip/(?P<attempt_num>\d+)/(?P<module_id>\d+)/'
+ '(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
views.skip),
- url(r'^(?P<q_id>\d+)/skip/(?P<next_q>\d+)/(?P<attempt_num>\d+)/(?P<module_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
+ url(r'^(?P<q_id>\d+)/skip/(?P<next_q>\d+)/(?P<attempt_num>\d+)/'
+ '(?P<module_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
views.skip),
- url(r'^enroll_request/(?P<course_id>\d+)/$', views.enroll_request, name='enroll_request'),
- url(r'^self_enroll/(?P<course_id>\d+)/$', views.self_enroll, name='self_enroll'),
+ url(r'^enroll_request/(?P<course_id>\d+)/$', views.enroll_request,
+ name='enroll_request'),
+ url(r'^self_enroll/(?P<course_id>\d+)/$', views.self_enroll,
+ name='self_enroll'),
url(r'^view_answerpaper/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)$',
views.view_answerpaper, name='view_answerpaper'),
- url(r'^show_lesson/(?P<lesson_id>\d+)/(?P<module_id>\d+)/(?P<course_id>\d+)/$',
- views.show_lesson, name='show_lesson'),
+ url(r'^show_lesson/(?P<lesson_id>\d+)/(?P<module_id>\d+)/'
+ '(?P<course_id>\d+)/$', views.show_lesson, name='show_lesson'),
url(r'^quizzes/view_module/(?P<module_id>\d+)/(?P<course_id>\d+)/$',
views.view_module, name='view_module'),
- url(r'^next_unit/(?P<course_id>\d+)/(?P<module_id>\d+)/(?P<current_unit_id>\d+)/$',
- views.get_next_unit, name='next_unit'),
+ url(r'^next_unit/(?P<course_id>\d+)/(?P<module_id>\d+)/'
+ '(?P<current_unit_id>\d+)/$', views.get_next_unit, name='next_unit'),
url(r'^next_unit/(?P<course_id>\d+)/(?P<module_id>\d+)/$',
views.get_next_unit, name='next_unit'),
- url(r'^next_unit/(?P<course_id>\d+)/(?P<module_id>\d+)/(?P<current_unit_id>\d+)/(?P<first_unit>\d+)/$',
+ url(r'^next_unit/(?P<course_id>\d+)/(?P<module_id>\d+)/'
+ '(?P<current_unit_id>\d+)/(?P<first_unit>\d+)/$',
views.get_next_unit, name='next_unit'),
url(r'^course_modules/(?P<course_id>\d+)/$',
views.course_modules, name='course_modules'),
url(r'^manage/$', views.prof_manage, name='manage'),
url(r'^manage/addquestion/$', views.add_question, name="add_question"),
url(r'^manage/addquestion/(?P<question_id>\d+)/$', views.add_question,
- name="add_question"),
+ name="add_question"),
url(r'^manage/addquiz/$', views.add_quiz, name='add_quiz'),
url(r'^manage/add_exercise/$', views.add_exercise, name='add_exercise'),
url(r'^manage/add_exercise/(?P<quiz_id>\d+)/$', views.add_exercise,
@@ -62,27 +69,35 @@ urlpatterns = [
views.add_quiz, name='edit_quiz'),
url(r'^manage/gradeuser/$', views.grade_user, name="grade_user"),
url(r'^manage/gradeuser/(?P<quiz_id>\d+)/(?P<course_id>\d+)/$',
- views.grade_user, name="grade_user"),
- url(r'^manage/gradeuser/(?P<quiz_id>\d+)/(?P<user_id>\d+)/(?P<course_id>\d+)/$',
- views.grade_user, name="grade_user"),
- url(r'^manage/gradeuser/(?P<quiz_id>\d+)/(?P<user_id>\d+)/(?P<attempt_number>\d+)/(?P<course_id>\d+)/$',
- views.grade_user, name="grade_user"),
- url(r'^manage/questions/$', views.show_all_questions, name="show_questions"),
+ views.grade_user, name="grade_user"),
+ url(r'^manage/gradeuser/(?P<quiz_id>\d+)/(?P<user_id>\d+)/'
+ '(?P<course_id>\d+)/$',
+ views.grade_user, name="grade_user"),
+ url(r'^manage/gradeuser/(?P<quiz_id>\d+)/(?P<user_id>\d+)/'
+ '(?P<attempt_number>\d+)/(?P<course_id>\d+)/$',
+ views.grade_user, name="grade_user"),
+ url(r'^manage/questions/$', views.show_all_questions,
+ name="show_questions"),
url(r'^manage/monitor/$', views.monitor, name="monitor"),
url(r'^manage/monitor/(?P<quiz_id>\d+)/(?P<course_id>\d+)/$',
views.monitor, name="monitor"),
- url(r'^manage/user_data/(?P<user_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
+ url(r'^manage/user_data/(?P<user_id>\d+)/(?P<questionpaper_id>\d+)/'
+ '(?P<course_id>\d+)/$',
views.user_data, name="user_data"),
url(r'^manage/user_data/(?P<user_id>\d+)/$', views.user_data),
- url(r'^manage/quiz/designquestionpaper/(?P<quiz_id>\d+)/$', views.design_questionpaper,
- name='design_questionpaper'),
- url(r'^manage/designquestionpaper/(?P<quiz_id>\d+)/(?P<questionpaper_id>\d+)/$',
+ url(r'^manage/quiz/designquestionpaper/(?P<quiz_id>\d+)/$',
+ views.design_questionpaper, name='design_questionpaper'),
+ url(r'^manage/designquestionpaper/(?P<quiz_id>\d+)/'
+ '(?P<questionpaper_id>\d+)/$',
views.design_questionpaper, name='designquestionpaper'),
- url(r'^manage/designquestionpaper/(?P<quiz_id>\d+)/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
+ url(r'^manage/designquestionpaper/(?P<quiz_id>\d+)/'
+ '(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
views.design_questionpaper, name='designquestionpaper'),
- url(r'^manage/statistics/question/(?P<questionpaper_id>\d+)/(?P<course_id>\d+)/$',
+ url(r'^manage/statistics/question/(?P<questionpaper_id>\d+)/'
+ '(?P<course_id>\d+)/$',
views.show_statistics, name="show_statistics"),
- url(r'^manage/statistics/question/(?P<questionpaper_id>\d+)/(?P<attempt_number>\d+)/(?P<course_id>\d+)/$',
+ url(r'^manage/statistics/question/(?P<questionpaper_id>\d+)/'
+ '(?P<attempt_number>\d+)/(?P<course_id>\d+)/$',
views.show_statistics, name="show_statistics"),
url(r'^manage/download_quiz_csv/(?P<course_id>\d+)/(?P<quiz_id>\d+)/$',
views.download_quiz_csv, name="download_quiz_csv"),
@@ -90,51 +105,61 @@ urlpatterns = [
views.duplicate_course, name='duplicate_course'),
url(r'manage/courses/$', views.courses, name='courses'),
url(r'manage/add_course/$', views.add_course, name='add_course'),
- url(r'manage/edit_course/(?P<course_id>\d+)$', views.add_course, name='edit_course'),
- url(r'manage/course_detail/(?P<course_id>\d+)/$', views.course_detail, name='course_detail'),
+ url(r'manage/edit_course/(?P<course_id>\d+)$', views.add_course,
+ name='edit_course'),
+ url(r'manage/course_detail/(?P<course_id>\d+)/$', views.course_detail,
+ name='course_detail'),
url(r'manage/enroll/(?P<course_id>\d+)/(?P<user_id>\d+)/$', views.enroll,
- name="enroll_user"),
+ name="enroll_user"),
url(r'manage/enroll/rejected/(?P<course_id>\d+)/(?P<user_id>\d+)/$',
views.enroll, {'was_rejected': True}),
- url(r'manage/upload_users/(?P<course_id>\d+)/$', views.upload_users, name="upload_users"),
- url(r'manage/send_mail/(?P<course_id>\d+)/$', views.send_mail, name="send_mail"),
+ url(r'manage/upload_users/(?P<course_id>\d+)/$', views.upload_users,
+ name="upload_users"),
+ url(r'manage/send_mail/(?P<course_id>\d+)/$', views.send_mail,
+ name="send_mail"),
url(r'manage/reject/(?P<course_id>\d+)/(?P<user_id>\d+)/$', views.reject,
- name="reject_user"),
+ name="reject_user"),
url(r'manage/enrolled/reject/(?P<course_id>\d+)/(?P<user_id>\d+)/$',
views.reject, {'was_enrolled': True}, name="reject_user"),
- url(r'manage/toggle_status/(?P<course_id>\d+)/$', views.toggle_course_status,
- name="toggle_course_status"),
+ url(r'manage/toggle_status/(?P<course_id>\d+)/$',
+ views.toggle_course_status, name="toggle_course_status"),
url(r'^ajax/questions/filter/$', views.ajax_questions_filter,
- name="questions_filter"),
+ name="questions_filter"),
url(r'^editprofile/$', views.edit_profile, name='edit_profile'),
url(r'^viewprofile/$', views.view_profile, name='view_profile'),
- url(r'^manage/enroll/(?P<course_id>\d+)/$', views.enroll, name="enroll_users"),
+ url(r'^manage/enroll/(?P<course_id>\d+)/$', views.enroll,
+ name="enroll_users"),
url(r'manage/enroll/rejected/(?P<course_id>\d+)/$',
views.enroll, {'was_rejected': True}),
url(r'manage/enrolled/reject/(?P<course_id>\d+)/$',
views.reject, {'was_enrolled': True}, name="reject_users"),
url(r'^manage/searchteacher/(?P<course_id>\d+)/$', views.search_teacher),
- url(r'^manage/addteacher/(?P<course_id>\d+)/$', views.add_teacher, name='add_teacher'),
- url(r'^manage/remove_teachers/(?P<course_id>\d+)/$', views.remove_teachers, name='remove_teacher'),
+ url(r'^manage/addteacher/(?P<course_id>\d+)/$', views.add_teacher,
+ name='add_teacher'),
+ url(r'^manage/remove_teachers/(?P<course_id>\d+)/$', views.remove_teachers,
+ name='remove_teacher'),
url(r'^manage/download_questions/$', views.show_all_questions,
- name="show_questions"),
+ name="show_questions"),
url(r'^manage/upload_questions/$', views.show_all_questions,
- name="show_questions"),
+ name="show_questions"),
url(r'^manage/grader/$', views.grader, name='grader'),
url(r'^manage/regrade/question/(?P<course_id>\d+)/(?P<question_id>\d+)/$',
- views.regrade, name='regrade'),
- url(r'^manage/regrade/questionpaper/(?P<course_id>\d+)/(?P<question_id>\d+)/(?P<questionpaper_id>\d+)/$',
- views.regrade, name='regrade'),
- url(r'^manage/regrade/answerpaper/(?P<course_id>\d+)/(?P<question_id>\d+)/(?P<answerpaper_id>\d+)/$',
- views.regrade, name='regrade'),
+ views.regrade, name='regrade'),
+ url(r'^manage/regrade/questionpaper/(?P<course_id>\d+)/'
+ '(?P<question_id>\d+)/(?P<questionpaper_id>\d+)/$',
+ views.regrade, name='regrade'),
+ url(r'^manage/regrade/answerpaper/(?P<course_id>\d+)/'
+ '(?P<question_id>\d+)/(?P<answerpaper_id>\d+)/$',
+ views.regrade, name='regrade'),
url(r'^manage/regrade/paper/(?P<course_id>\d+)/(?P<answerpaper_id>\d+)/$',
- views.regrade, name='regrade'),
- url(r'^manage/(?P<mode>godmode|usermode)/(?P<quiz_id>\d+)/(?P<course_id>\d+)/$',
- views.test_quiz),
+ views.regrade, name='regrade'),
+ url(r'^manage/(?P<mode>godmode|usermode)/(?P<quiz_id>\d+)/'
+ '(?P<course_id>\d+)/$', views.test_quiz),
url(r'^manage/create_demo_course/$', views.create_demo_course),
url(r'^manage/courses/download_course_csv/(?P<course_id>\d+)/$',
views.download_course_csv, name="download_course_csv"),
- url(r'^manage/download/user_assignment/(?P<question_id>\d+)/(?P<user_id>\d+)/(?P<quiz_id>\d+)/$',
+ url(r'^manage/download/user_assignment/(?P<question_id>\d+)/'
+ '(?P<user_id>\d+)/(?P<quiz_id>\d+)/$',
views.download_assignment_file, name="download_user_assignment"),
url(r'^manage/download/quiz_assignments/(?P<quiz_id>\d+)/$',
views.download_assignment_file, name="download_quiz_assignment"),
@@ -150,8 +175,8 @@ urlpatterns = [
views.edit_lesson, name="edit_lesson"),
url(r'^manage/courses/designmodule/(?P<module_id>\d+)/$',
views.design_module, name="design_module"),
- url(r'^manage/courses/designmodule/(?P<module_id>\d+)/(?P<course_id>\d+)/$',
- views.design_module, name="design_module"),
+ url(r'^manage/courses/designmodule/(?P<module_id>\d+)/'
+ '(?P<course_id>\d+)/$', views.design_module, name="design_module"),
url(r'^manage/courses/all_quizzes/$',
views.show_all_quizzes, name="show_all_quizzes"),
url(r'^manage/courses/all_lessons/$',
diff --git a/yaksh/views.py b/yaksh/views.py
index d8d630b..3341aca 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -1,30 +1,20 @@
-import random
-import string
import os
-from datetime import datetime, timedelta
-import collections
import csv
from django.http import HttpResponse, JsonResponse
-from django.core.urlresolvers import reverse
from django.contrib.auth import login, logout, authenticate
from django.shortcuts import render, get_object_or_404, redirect
-from django.template import RequestContext, Context, Template
-from django.template.loader import get_template, render_to_string
+from django.template import Context, Template
from django.http import Http404
-from django.db.models import Sum, Max, Q, F
+from django.db.models import Max, Q, F
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
from django.forms.models import inlineformset_factory
from django.utils import timezone
-from django.core.validators import URLValidator
from django.core.exceptions import (
- MultipleObjectsReturned, ObjectDoesNotExist, ValidationError
+ MultipleObjectsReturned, ObjectDoesNotExist
)
-from django.conf import settings
-import pytz
from taggit.models import Tag
-from itertools import chain
import json
import six
from textwrap import dedent
@@ -38,24 +28,22 @@ import re
# Local imports.
from yaksh.code_server import get_result as get_result_from_code_server
from yaksh.models import (
- Answer, AnswerPaper, AssignmentUpload, Course, FileUpload, FloatTestCase,
- HookTestCase, IntegerTestCase, McqTestCase, Profile,
- QuestionPaper, QuestionSet, Quiz, Question, StandardTestCase,
- StdIOBasedTestCase, StringTestCase, TestCase, User,
- get_model_class, FIXTURES_DIR_PATH, Lesson, LessonFile,
- LearningUnit, LearningModule,
+ Answer, AnswerPaper, AssignmentUpload, Course, FileUpload, Profile,
+ QuestionPaper, QuestionSet, Quiz, Question, TestCase, User,
+ FIXTURES_DIR_PATH, Lesson, LessonFile, LearningUnit, LearningModule,
CourseStatus
)
from yaksh.forms import (
UserRegisterForm, UserLoginForm, QuizForm, QuestionForm,
- RandomQuestionForm, QuestionFilterForm, CourseForm, ProfileForm,
- UploadFileForm, get_object_form, FileForm, QuestionPaperForm, LessonForm,
+ QuestionFilterForm, CourseForm, ProfileForm,
+ UploadFileForm, FileForm, QuestionPaperForm, LessonForm,
LessonFileForm, LearningModuleForm, ExerciseForm
)
-from yaksh.settings import SERVER_POOL_PORT, SERVER_HOST_NAME
+from yaksh.settings import SERVER_POOL_PORT, SERVER_HOST_NAME
from .settings import URL_ROOT
from .file_utils import extract_files, is_csv
-from .send_emails import send_user_mail, generate_activation_key, send_bulk_mail
+from .send_emails import (send_user_mail,
+ generate_activation_key, send_bulk_mail)
from .decorators import email_verified, has_profile
@@ -88,8 +76,9 @@ def add_to_group(users):
if not is_moderator(user):
user.groups.add(group)
+
CSV_FIELDS = ['name', 'username', 'roll_number', 'institute', 'department',
- 'questions', 'marks_obtained', 'out_of', 'percentage', 'status']
+ 'questions', 'marks_obtained', 'out_of', 'percentage', 'status']
def get_html_text(md_text):
@@ -121,7 +110,6 @@ def user_register(request):
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
- data = form.cleaned_data
u_name, pwd, user_email, key = form.save()
new_user = authenticate(username=u_name, password=pwd)
login(request, new_user)
@@ -549,7 +537,7 @@ def start(request, questionpaper_id=None, attempt_num=None, course_id=None,
raise Http404(msg)
new_paper = quest_paper.make_answerpaper(user, ip, attempt_number,
course_id)
- if new_paper.status == 'inprogress':
+ if new_paper.status == 'inprogress':
return show_question(
request, new_paper.current_question(),
new_paper, course_id=course_id,
@@ -559,12 +547,13 @@ def start(request, questionpaper_id=None, attempt_num=None, course_id=None,
msg = 'You have already finished the quiz!'
raise Http404(msg)
+
@login_required
@email_verified
-def show_question(request, question, paper, error_message=None, notification=None,
- course_id=None, module_id=None, previous_question=None):
+def show_question(request, question, paper, error_message=None,
+ notification=None, course_id=None, module_id=None,
+ previous_question=None):
"""Show a question if possible."""
- user = request.user
quiz = paper.question_paper.quiz
quiz_type = 'Exam'
can_skip = False
@@ -574,7 +563,8 @@ def show_question(request, question, paper, error_message=None, notification=Non
delay_time = paper.time_left_on_question(question)
if previous_question and quiz.is_exercise:
- if delay_time <= 0 or previous_question in paper.questions_answered.all():
+ if (delay_time <= 0 or previous_question in
+ paper.questions_answered.all()):
can_skip = True
question = previous_question
if not question:
@@ -640,7 +630,6 @@ def show_question(request, question, paper, error_message=None, notification=Non
@email_verified
def skip(request, q_id, next_q=None, attempt_num=None, questionpaper_id=None,
course_id=None, module_id=None):
- user = request.user
paper = get_object_or_404(
AnswerPaper, user=request.user, attempt_number=attempt_num,
question_paper=questionpaper_id, course_id=course_id
@@ -727,7 +716,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
previous_question=current_question
)
for fname in assignment_filename:
- fname._name = fname._name.replace(" ","_")
+ fname._name = fname._name.replace(" ", "_")
assignment_files = AssignmentUpload.objects.filter(
assignmentQuestion=current_question,
assignmentFile__icontains=fname, user=user,
@@ -766,34 +755,36 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
previous_question=current_question
)
if current_question in paper.get_questions_answered()\
- and current_question.type not in ['code', 'upload']:
+ and current_question.type not in ['code', 'upload']:
new_answer = paper.get_latest_answer(current_question.id)
new_answer.answer = user_answer
new_answer.correct = False
else:
new_answer = Answer(
- question=current_question, answer=user_answer,
- correct=False, error=json.dumps([])
- )
+ question=current_question, answer=user_answer,
+ correct=False, error=json.dumps([])
+ )
new_answer.save()
uid = new_answer.id
paper.answers.add(new_answer)
# If we were not skipped, we were asked to check. For any non-mcq
# questions, we obtain the results via XML-RPC with the code executed
# safely in a separate process (the code_server.py) running as nobody.
- json_data = current_question.consolidate_answer_data(user_answer, user) \
- if current_question.type == 'code' or \
+ json_data = current_question.consolidate_answer_data(
+ user_answer, user) if current_question.type == 'code' or \
current_question.type == 'upload' else None
result = paper.validate_answer(
user_answer, current_question, json_data, uid
)
if current_question.type in ['code', 'upload']:
- if paper.time_left() <= 0 and not paper.question_paper.quiz.is_exercise:
+ if (paper.time_left() <= 0 and not
+ paper.question_paper.quiz.is_exercise):
url = '{0}:{1}'.format(SERVER_HOST_NAME, SERVER_POOL_PORT)
- result_details = get_result_from_code_server(url, uid, block=True)
+ result_details = get_result_from_code_server(url, uid,
+ block=True)
result = json.loads(result_details.get('result'))
- next_question, error_message, paper = _update_paper(request, uid,
- result)
+ next_question, error_message, paper = _update_paper(
+ request, uid, result)
return show_question(request, next_question, paper,
error_message, course_id=course_id,
module_id=module_id,
@@ -801,7 +792,8 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
else:
return JsonResponse(result)
else:
- next_question, error_message, paper = _update_paper(request, uid, result)
+ next_question, error_message, paper = _update_paper(
+ request, uid, result)
return show_question(request, next_question, paper, error_message,
course_id=course_id, module_id=module_id,
previous_question=current_question)
@@ -850,22 +842,25 @@ def _update_paper(request, uid, result):
if result.get('success'):
new_answer.marks = (current_question.points * result['weight'] /
- current_question.get_maximum_test_case_weight()) \
+ current_question.get_maximum_test_case_weight()) \
if current_question.partial_grading and \
- current_question.type == 'code' or current_question.type == 'upload' \
- else current_question.points
+ current_question.type == 'code' or \
+ current_question.type == 'upload' else current_question.points
new_answer.correct = result.get('success')
error_message = None
new_answer.error = json.dumps(result.get('error'))
next_question = paper.add_completed_question(current_question.id)
else:
new_answer.marks = (current_question.points * result['weight'] /
- current_question.get_maximum_test_case_weight()) \
+ current_question.get_maximum_test_case_weight()) \
if current_question.partial_grading and \
- current_question.type == 'code' or current_question.type == 'upload' \
+ current_question.type == 'code' or \
+ current_question.type == 'upload' \
else 0
- error_message = result.get('error') if current_question.type == 'code' \
- or current_question.type == 'upload' else None
+ error_message = result.get('error') \
+ if current_question.type == 'code' or \
+ current_question.type == 'upload' \
+ else None
new_answer.error = json.dumps(result.get('error'))
next_question = current_question if current_question.type == 'code' \
or current_question.type == 'upload' \
@@ -1301,20 +1296,19 @@ def design_questionpaper(request, quiz_id, questionpaper_id=None,
marks = None
state = None
if questionpaper_id is None:
- question_paper = QuestionPaper.objects.get_or_create(quiz_id=quiz_id)[0]
+ question_paper = QuestionPaper.objects.get_or_create(
+ quiz_id=quiz_id)[0]
else:
question_paper = get_object_or_404(QuestionPaper, id=questionpaper_id,
quiz_id=quiz_id)
qpaper_form = QuestionPaperForm(instance=question_paper)
if request.method == 'POST':
-
filter_form = QuestionFilterForm(request.POST, user=user)
qpaper_form = QuestionPaperForm(request.POST, instance=question_paper)
question_type = request.POST.get('question_type', None)
marks = request.POST.get('marks', None)
state = request.POST.get('is_active', None)
-
if 'add-fixed' in request.POST:
question_ids = request.POST.get('checked_ques', None)
if question_paper.fixed_question_order:
@@ -1345,10 +1339,11 @@ def design_questionpaper(request, quiz_id, questionpaper_id=None,
question_ids = request.POST.getlist('random_questions', None)
num_of_questions = request.POST.get('num_of_questions', 1)
if question_ids and marks:
- random_set = QuestionSet(marks=marks, num_questions=num_of_questions)
+ random_set = QuestionSet(marks=marks,
+ num_questions=num_of_questions)
random_set.save()
- for question in Question.objects.filter(id__in=question_ids):
- random_set.questions.add(question)
+ random_ques = Question.objects.filter(id__in=question_ids)
+ random_set.questions.add(*random_ques)
question_paper.random_questions.add(random_set)
if 'remove-random' in request.POST:
@@ -1395,7 +1390,7 @@ def show_all_questions(request):
questions = Question.objects.filter(user_id=user.id, active=True)
form = QuestionFilterForm(user=user)
user_tags = questions.values_list('tags', flat=True).distinct()
- all_tags = Tag.objects.filter(id__in = user_tags)
+ all_tags = Tag.objects.filter(id__in=user_tags)
upload_form = UploadFileForm()
context['questions'] = questions
context['all_tags'] = all_tags
@@ -1408,8 +1403,8 @@ def show_all_questions(request):
if request.POST.get('delete') == 'delete':
data = request.POST.getlist('question')
if data is not None:
- questions = Question.objects.filter(id__in=data, user_id=user.id,
- active=True)
+ questions = Question.objects.filter(
+ id__in=data, user_id=user.id, active=True)
for question in questions:
question.active = False
question.save()
@@ -1441,7 +1436,8 @@ def show_all_questions(request):
response.write(zip_file.read())
return response
else:
- context['msg'] = "Please select atleast one question to download"
+ context['msg'] = ("Please select atleast" +
+ "one question to download")
if request.POST.get('test') == 'test':
question_ids = request.POST.getlist("question")
@@ -1459,7 +1455,7 @@ def show_all_questions(request):
question_tags = request.POST.getlist("question_tags")
search_tags = []
for tags in question_tags:
- search_tags.extend(re.split('[; |, |\*|\n]',tags))
+ search_tags.extend(re.split('[; |, |\*|\n]', tags))
search_result = Question.objects.filter(tags__name__in=search_tags,
user=user).distinct()
context['questions'] = search_result
@@ -1485,8 +1481,9 @@ def _expand_questions(questions, field_list):
i = field_list.index('questions')
field_list.remove('questions')
for question in questions:
- field_list.insert(i, '{0}-{1}'.format(question.summary, question.points))
- return field_list
+ field_list.insert(
+ i, '{0}-{1}'.format(question.summary, question.points))
+ return field_list
@login_required
@@ -1497,7 +1494,8 @@ def download_quiz_csv(request, course_id, quiz_id):
raise Http404('You are not allowed to view this page!')
course = get_object_or_404(Course, id=course_id)
quiz = get_object_or_404(Quiz, id=quiz_id)
- if not course.is_creator(current_user) and not course.is_teacher(current_user):
+ if not course.is_creator(current_user) and \
+ not course.is_teacher(current_user):
raise Http404('The quiz does not belong to your course')
users = course.get_enrolled().order_by('first_name')
if not users:
@@ -1509,19 +1507,22 @@ def download_quiz_csv(request, course_id, quiz_id):
question_paper.id, course.id).last()
if request.method == 'POST':
csv_fields = request.POST.getlist('csv_fields')
- attempt_number = request.POST.get('attempt_number', last_attempt_number)
+ attempt_number = request.POST.get('attempt_number',
+ last_attempt_number)
if not csv_fields:
csv_fields = CSV_FIELDS
if not attempt_number:
attempt_number = last_attempt_number
questions = question_paper.get_question_bank()
- answerpapers = AnswerPaper.objects.filter(question_paper=question_paper,
- attempt_number=attempt_number, course_id=course_id)
+ answerpapers = AnswerPaper.objects.filter(
+ question_paper=question_paper,
+ attempt_number=attempt_number, course_id=course_id)
if not answerpapers:
return monitor(request, quiz_id, course_id)
response = HttpResponse(content_type='text/csv')
- response['Content-Disposition'] = 'attachment; filename="{0}-{1}-attempt{2}.csv"'.format(
+ response['Content-Disposition'] = \
+ 'attachment; filename="{0}-{1}-attempt{2}.csv"'.format(
course.name.replace('.', ''), quiz.description.replace('.', ''),
attempt_number)
writer = csv.writer(response)
@@ -1529,21 +1530,24 @@ def download_quiz_csv(request, course_id, quiz_id):
csv_fields = _expand_questions(questions, csv_fields)
writer.writerow(csv_fields)
- csv_fields_values = {'name': 'user.get_full_name().title()',
+ csv_fields_values = {
+ 'name': 'user.get_full_name().title()',
'roll_number': 'user.profile.roll_number',
'institute': 'user.profile.institute',
'department': 'user.profile.department',
'username': 'user.username',
'marks_obtained': 'answerpaper.marks_obtained',
'out_of': 'question_paper.total_marks',
- 'percentage': 'answerpaper.percent', 'status': 'answerpaper.status'}
+ 'percentage': 'answerpaper.percent',
+ 'status': 'answerpaper.status'}
questions_scores = {}
for question in questions:
questions_scores['{0}-{1}'.format(question.summary, question.points)] \
- = 'answerpaper.get_per_question_score({0})'.format(question.id)
+ = 'answerpaper.get_per_question_score({0})'.format(question.id)
csv_fields_values.update(questions_scores)
- users = users.exclude(id=course.creator.id).exclude(id__in=course.teachers.all())
+ users = users.exclude(id=course.creator.id).exclude(
+ id__in=course.teachers.all())
for user in users:
row = []
answerpaper = None
@@ -1626,7 +1630,8 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None,
if request.method == "POST":
papers = data['papers']
for paper in papers:
- for question, answers in six.iteritems(paper.get_question_answers()):
+ for question, answers in six.iteritems(
+ paper.get_question_answers()):
marks = float(request.POST.get('q%d_marks' % question.id, 0))
answer = answers[-1]['answer']
answer.set_marks(marks)
@@ -1742,7 +1747,7 @@ def add_teacher(request, course_id):
context = {}
course = get_object_or_404(Course, pk=course_id)
- if user == course.creator or user in course.teachers.all():
+ if course.is_creator(user) or course.is_teacher(user):
context['course'] = course
else:
raise Http404('You are not allowed to view this page!')
@@ -1764,8 +1769,8 @@ def remove_teachers(request, course_id):
user = request.user
course = get_object_or_404(Course, pk=course_id)
- if not is_moderator(user) and (user != course.creator and user
- not in course.teachers.all()):
+ if not is_moderator(user) and (not course.is_creator(user) and
+ course.is_teacher(user)):
raise Http404('You are not allowed to view this page!')
if request.method == "POST":
@@ -1782,9 +1787,10 @@ def test_mode(user, godmode=False, questions_list=None, quiz_id=None,
if questions_list is not None:
trial_course = Course.objects.create_trial_course(user)
trial_quiz = Quiz.objects.create_trial_quiz(user)
- trial_questionpaper = QuestionPaper.objects.create_trial_paper_to_test_questions(
- trial_quiz, questions_list
- )
+ trial_questionpaper = QuestionPaper.objects. \
+ create_trial_paper_to_test_questions(
+ trial_quiz, questions_list
+ )
trial_unit, created = LearningUnit.objects.get_or_create(
order=1, type="quiz", quiz=trial_quiz,
check_prerequisite=False)
@@ -1797,9 +1803,10 @@ def test_mode(user, godmode=False, questions_list=None, quiz_id=None,
trial_quiz, trial_course, module = Quiz.objects.create_trial_from_quiz(
quiz_id, user, godmode, course_id
)
- trial_questionpaper = QuestionPaper.objects.create_trial_paper_to_test_quiz(
- trial_quiz, quiz_id
- )
+ trial_questionpaper = QuestionPaper.objects. \
+ create_trial_paper_to_test_quiz(
+ trial_quiz, quiz_id
+ )
return trial_questionpaper, trial_course, module
@@ -1864,7 +1871,8 @@ def grader(request, extra_context=None):
if not is_moderator(user):
raise Http404('You are not allowed to view this page!')
courses = Course.objects.filter(is_trial=False)
- user_courses = list(courses.filter(creator=user)) + list(courses.filter(teachers=user))
+ user_courses = list(courses.filter(creator=user)) + \
+ list(courses.filter(teachers=user))
context = {'courses': user_courses}
if extra_context:
context.update(extra_context)
@@ -1877,24 +1885,26 @@ def regrade(request, course_id, question_id=None, answerpaper_id=None,
questionpaper_id=None):
user = request.user
course = get_object_or_404(Course, pk=course_id)
- if not is_moderator(user) or (user != course.creator and user not in course.teachers.all()):
+ if not is_moderator(user) or (course.is_creator(user) and
+ course.is_teacher(user)):
raise Http404('You are not allowed to view this page!')
details = []
if answerpaper_id is not None and question_id is None:
answerpaper = get_object_or_404(AnswerPaper, pk=answerpaper_id)
for question in answerpaper.questions.all():
details.append(answerpaper.regrade(question.id))
- course_status = CourseStatus.objects.filter(user=answerpaper.user,
- course=answerpaper.course)
+ course_status = CourseStatus.objects.filter(
+ user=answerpaper.user, course=answerpaper.course)
if course_status.exists():
course_status.first().set_grade()
if questionpaper_id is not None and question_id is not None:
- answerpapers = AnswerPaper.objects.filter(questions=question_id,
- question_paper_id=questionpaper_id, course_id=course_id)
+ answerpapers = AnswerPaper.objects.filter(
+ questions=question_id,
+ question_paper_id=questionpaper_id, course_id=course_id)
for answerpaper in answerpapers:
details.append(answerpaper.regrade(question_id))
- course_status = CourseStatus.objects.filter(user=answerpaper.user,
- course=answerpaper.course)
+ course_status = CourseStatus.objects.filter(
+ user=answerpaper.user, course=answerpaper.course)
if course_status.exists():
course_status.first().set_grade()
if answerpaper_id is not None and question_id is not None:
@@ -1931,8 +1941,8 @@ def download_course_csv(request, course_id):
total_course_marks = 0.0
user_course_marks = 0.0
for quiz in quizzes:
- quiz_best_marks = AnswerPaper.objects.get_user_best_of_attempts_marks\
- (quiz, student["id"], course_id)
+ quiz_best_marks = AnswerPaper.objects. \
+ get_user_best_of_attempts_marks(quiz, student["id"], course_id)
user_course_marks += quiz_best_marks
total_course_marks += quiz.questionpaper_set.values_list(
"total_marks", flat=True)[0]
@@ -1943,7 +1953,7 @@ def download_course_csv(request, course_id):
response['Content-Disposition'] = 'attachment; filename="{0}.csv"'.format(
(course.name).lower().replace('.', ''))
header = ['first_name', 'last_name', "roll_number", "email", "institute"]\
- + [quiz.description for quiz in quizzes] + ['total_scored', 'out_of']
+ + [quiz.description for quiz in quizzes] + ['total_scored', 'out_of']
writer = csv.DictWriter(response, fieldnames=header, extrasaction='ignore')
writer.writeheader()
for student in students:
@@ -1993,7 +2003,9 @@ def new_activation(request, email=None):
context['success'] = False
context['msg'] = "Your account is not verified. \
Please verify your account"
- return render_to_response('yaksh/activation_status.html', context)
+ return my_render_to_response(
+ request, 'yaksh/activation_status.html', context
+ )
if not user.profile.is_email_verified:
user.profile.activation_key = generate_activation_key(user.username)
@@ -2088,17 +2100,20 @@ def upload_users(request, course_id):
)
required_fields = ['firstname', 'lastname', 'email']
try:
- reader = csv.DictReader(csv_file.read().decode('utf-8').splitlines(),
- dialect=dialect)
+ reader = csv.DictReader(
+ csv_file.read().decode('utf-8').splitlines(),
+ dialect=dialect)
except TypeError:
context['message'] = "Bad CSV file"
return my_render_to_response(
request, 'yaksh/course_detail.html', context
)
- stripped_fieldnames = [field.strip().lower() for field in reader.fieldnames]
+ stripped_fieldnames = [
+ field.strip().lower() for field in reader.fieldnames]
for field in required_fields:
if field not in stripped_fieldnames:
- context['message'] = "The CSV file does not contain the required headers"
+ context['message'] = "The CSV file does not contain the"\
+ " required headers"
return my_render_to_response(
request, 'yaksh/course_detail.html', context
)
@@ -2136,9 +2151,11 @@ def _read_user_csv(reader, course):
continue
user_defaults = {'email': email, 'first_name': first_name,
'last_name': last_name}
- user, created = _create_or_update_user(username, password, user_defaults)
+ user, created = _create_or_update_user(username, password,
+ user_defaults)
profile_defaults = {'institute': institute, 'roll_number': roll_no,
- 'department': department, 'is_email_verified': True}
+ 'department': department,
+ 'is_email_verified': True}
_create_or_update_profile(user, profile_defaults)
if created:
state = "Added"
@@ -2174,8 +2191,8 @@ def _get_csv_values(row, fields):
username = row['username'].strip()
if 'remove' in fields:
remove = row['remove']
- return (username, email, first_name, last_name, password, roll_no, institute,
- department, remove)
+ return (username, email, first_name, last_name, password,
+ roll_no, institute, department, remove)
def _remove_from_course(user, course):
@@ -2681,8 +2698,10 @@ def course_modules(request, course_id, msg=None):
context = {"course": course, "user": user, "msg": msg}
course_status = CourseStatus.objects.filter(course=course, user=user)
context['course_percentage'] = course.get_completion_percent(user)
- context['modules'] = [(module, module.get_module_complete_percent(course, user))
- for module in learning_modules]
+ context['modules'] = [
+ (module, module.get_module_complete_percent(course, user))
+ for module in learning_modules
+ ]
if course_status.exists():
course_status = course_status.first()
if not course_status.grade:
@@ -2761,16 +2780,21 @@ def get_user_data(request, course_id, student_id):
data['msg'] = 'You are not a moderator'
data['status'] = False
elif not course.is_creator(user) and not course.is_teacher(user):
- msg = 'You are neither course creator nor course teacher for {0}'.format(
- course.name)
+ msg = dedent(
+ """\
+ You are neither course creator nor course teacher for {0}
+ """.format(course.name)
+ )
data['msg'] = msg
data['status'] = False
else:
student = User.objects.get(id=student_id)
data['status'] = True
modules = course.get_learning_modules()
- module_percent = [(module, module.get_module_complete_percent(course, student))
- for module in modules]
+ module_percent = [
+ (module, module.get_module_complete_percent(course, student))
+ for module in modules
+ ]
data['modules'] = module_percent
_update_course_percent(course, student)
data['course_percentage'] = course.get_completion_percent(student)