From f6c927ac0018e271e9a54608c4ed24fb3dd2a109 Mon Sep 17 00:00:00 2001 From: Izaguirj Date: Fri, 8 Nov 2019 22:39:26 -0500 Subject: [PATCH] Templates built for tests.py files for unit testing --- .vscode/settings.json | 3 ++ unicode/editor/models.py | 13 +++++-- unicode/editor/tests.py | 40 +++++++++++++++++++++- unicode/eval_engine/result.py | 53 +++++++++++++++++++++++++++++ unicode/eval_engine/services.py | 60 +++++++++++++++++++++++++++++++++ unicode/eval_engine/settings.py | 15 +++++++++ unicode/eval_engine/tests.py | 17 +++++++++- unicode/global/tests.py | 17 +++++++++- unicode/problems/forms.py | 10 +++--- unicode/problems/models.py | 4 +++ unicode/problems/tests.py | 36 +++++++++++++++++++- unicode/users/models.py | 2 ++ unicode/users/tests.py | 23 ++++++++++++- 13 files changed, 281 insertions(+), 12 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 unicode/eval_engine/result.py create mode 100644 unicode/eval_engine/services.py create mode 100644 unicode/eval_engine/settings.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f2d90cb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.linting.enabled": true +} \ No newline at end of file diff --git a/unicode/editor/models.py b/unicode/editor/models.py index ebf36b1..5f9a58d 100644 --- a/unicode/editor/models.py +++ b/unicode/editor/models.py @@ -2,14 +2,23 @@ from django.db import models from problems.models import Problem +Language_Options = { + ('Java', 'Java'), + ('C', 'C'), + ('C++', 'C++'), + ('JavaScript', 'JavaScript'), + ('C#', 'C#'), + ('Python', 'Python'), + ('Clojure', 'Clojure') +} -# Create your models here. class UserSubmission(models.Model): submitter = models.ForeignKey(User, on_delete=models.CASCADE) problem = models.ForeignKey(Problem, on_delete=models.CASCADE) submission = models.CharField(max_length=1000) + language = models.CharField(max_length=50, choices=Language_Options, default='Java') created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) def __str__(self): - return self.title + return f'{self.submitter} - {self.problem} - {self.language} - ({self.created})' \ No newline at end of file diff --git a/unicode/editor/tests.py b/unicode/editor/tests.py index 7ce503c..34f39ae 100644 --- a/unicode/editor/tests.py +++ b/unicode/editor/tests.py @@ -1,3 +1,41 @@ +import unittest + +from datetime import datetime +from django.apps import apps from django.test import TestCase +from editor.apps import EditorConfig +from editor.models import UserSubmission + +# app.py test +class AppsTest(unittest.TestCase): + def problem_config(self): + self.assertEqual(EditorConfig.name, 'editor') + self.assertEqual(apps.get_app_config('editor').name, 'editor') + +# models.py test +class UserSubmissionModelTest(TestCase): + #def test_submitter(self): + + + #def test_problem(self): + + #Testing __str__(self) for the correct string return + ''' + def test_string_representation(self): + test_submission = UserSubmission(submitter = "This is my First Submission") + test_problem = UserSubmission(problem = "This is my First Problem") + test_language = UserSubmission(language = "Python") + test_created = UserSubmission(created = "11/6/2019 12:30") + test_return = test_submission + " - " + test_problem + " - " + test_language + " - " + test_created + self.assertEqual(str(test_return), UserSubmission.__str__(self)) + ''' + #def test_created(self): + + + #def test_modified(self): + +''' +class UrlsTest(TestCase): -# Create your tests here. +class ViewsTest(TestCase): +''' \ No newline at end of file diff --git a/unicode/eval_engine/result.py b/unicode/eval_engine/result.py new file mode 100644 index 0000000..e8bcad4 --- /dev/null +++ b/unicode/eval_engine/result.py @@ -0,0 +1,53 @@ +import json + + +class BaseAPIResult(object): + """Represents a response from the HackerEarth API. + """ + def __init__(self, response): + self._transform_to_attrs(response) + + def _desiarialize_response(self, response): + response = json.loads(response) + return response + + def _transform_to_attrs(self, response): + """Sets the key/value pairs in the given dict as + attributes of this result object. + """ + response_dict = self._desiarialize_response(response) + self.__dict__.update(response_dict) + + +class CompileResult(BaseAPIResult): + """Represents the compilation results from the compile + end point. + """ + def __init__(self, response): + super(CompileResult, self).__init__(response) + + +class RunResult(BaseAPIResult): + """Represents the excecution results from the run end point of the + HackerEarth API. + """ + + def __init__(self, response): + super(RunResult, self).__init__(response) + + def _transform_to_attrs(self, response): + response_dict = self._desiarialize_response(response) + response_dict = self._flatten_dict(response_dict) + self.__dict__.update(response_dict) + + def _flatten_dict(self, dict_): + """Modifies the given dict into a flat dict consisting of only + key/value pairs. + """ + flattened_dict = {} + for (key, value) in dict_.items(): + if isinstance(value, dict): + flattened_dict.update(self._flatten_dict(value)) + else: + flattened_dict[key] = value + return flattened_dict diff --git a/unicode/eval_engine/services.py b/unicode/eval_engine/services.py new file mode 100644 index 0000000..bbfb4d2 --- /dev/null +++ b/unicode/eval_engine/services.py @@ -0,0 +1,60 @@ +import requests +from . import settings + +lang = { + 'C': 4, + 'C++': 10, + 'C#': 16, + 'Clojure': 18, + 'Java': 26, + 'JavaScript': 29, + 'Octave': 32, + 'Python': 34, + 'Ruby': 38 +} +def eval_engine(source, lang, test_in, test_out): + url = settings.CODE_EVAL_REQUEST_ENDPOINT # wait=true makes the API call synchronous, halving the number of requests needed + params = { + 'source_code': source, + 'language_id': lang, + 'stdin': test_in, + 'expected_output': test_out + } + r = requests.post(url, params=params) + eval_output = r.json() + return eval_output + + +def eval_setup(submission): + submission_info= submission['user_submission'] + test_cases= submission['test_cases'] + + source_code= submission_info.submission + language= submission_info.language + + ''' + Collects all test case statuses in one object + ''' + + result={} + index=0 + for case in test_cases: + status="" + test_input=case.test_input + test_output= case.test_output + eval_object = eval_engine(source_code, lang[language], test_input, test_output) + print(eval_object) + + #Checks for error + if 'Error' in eval_object['status']['description']: + error= eval_object['status']['description'] + return {'error': error} + elif eval_object['status']['description']=="Wrong Answer": + status='fail' + else: + status='pass' + + #Adds test case object to result every iteration + result[index]=({"test_input":test_input,"test_output":test_output,"status":status}) + index+=1 + return result \ No newline at end of file diff --git a/unicode/eval_engine/settings.py b/unicode/eval_engine/settings.py new file mode 100644 index 0000000..6012744 --- /dev/null +++ b/unicode/eval_engine/settings.py @@ -0,0 +1,15 @@ +# v3 API endpoints of HackerEarth Code Checker API +COMPILE_API_ENDPOINT = 'https://api.hackerearth.com/v3/code/compile/' +RUN_API_ENDPOINT = 'https://api.hackerearth.com/v3/code/run/' +CODE_EVAL_REQUEST_ENDPOINT='http://159.89.93.145:3000/submissions/?base64_encoded=false&wait=true' + + +# Max run time of a program in seconds +RUN_TIME_UPPER_LIMIT = 5 + + +# Max memory consumption allowed for a program +MEMORY_UPPER_LIMIT = 1024*256 + +# please keep this secret +CLIENT_SECRET = '' \ No newline at end of file diff --git a/unicode/eval_engine/tests.py b/unicode/eval_engine/tests.py index 7ce503c..0fd5fb8 100644 --- a/unicode/eval_engine/tests.py +++ b/unicode/eval_engine/tests.py @@ -1,3 +1,18 @@ +import unittest + +from django.apps import apps from django.test import TestCase +from eval_engine.apps import EvalEngineConfig -# Create your tests here. +# app.py test +class AppsTest(unittest.TestCase): + def problem_config(self): + self.assertEqual(EvalEngineConfig.name, 'eval_engine') + self.assertEqual(apps.get_app_config('eval_engine').name, 'eval_engine') +''' +# models.py test +class ModelsTest(TestCase): + +# views.py test +class ViewsTest(TestCase): +''' \ No newline at end of file diff --git a/unicode/global/tests.py b/unicode/global/tests.py index 7ce503c..7e455b4 100644 --- a/unicode/global/tests.py +++ b/unicode/global/tests.py @@ -1,3 +1,18 @@ +import unittest + +from django.apps import apps from django.test import TestCase +from apps import GlobalConfig + +# app.py test +class AppsTest(unittest.TestCase): + def problem_config(self): + self.assertEqual(GlobalConfig.name, 'global') + self.assertEqual(apps.get_app_config('global').name, 'global') +''' +# models.py test +class ModelsTest(TestCase): -# Create your tests here. +# views.py test +class ViewsTest(TestCase): +''' \ No newline at end of file diff --git a/unicode/problems/forms.py b/unicode/problems/forms.py index b114989..7532399 100644 --- a/unicode/problems/forms.py +++ b/unicode/problems/forms.py @@ -8,8 +8,8 @@ class Meta: fields = ('title', 'description', 'datatype', 'example_solution') -#class TestCaseForm(forms.ModelForm): -# -# class Meta: -# model = ProblemTestCase -# fields = ('test_input', 'test_output') +class ProblemTestCaseForm(forms.ModelForm): + + class Meta: + model = ProblemTestCase + fields = ('test_input', 'test_output') diff --git a/unicode/problems/models.py b/unicode/problems/models.py index 29a43a4..328b812 100644 --- a/unicode/problems/models.py +++ b/unicode/problems/models.py @@ -22,5 +22,9 @@ class ProblemTestCase(models.Model): test_input = models.CharField(max_length=1000) test_output = models.CharField(max_length=1000) + def __str__(self): return f'{self.problem} testcase {self.id}' + + + diff --git a/unicode/problems/tests.py b/unicode/problems/tests.py index 7ce503c..27aa754 100644 --- a/unicode/problems/tests.py +++ b/unicode/problems/tests.py @@ -1,3 +1,37 @@ +import unittest + +from django.apps import apps from django.test import TestCase +from problems.apps import ProblemsConfig +from problems.forms import ProblemForm, ProblemTestCaseForm +from problems.models import Problem, ProblemTestCase + +# app.py test +class AppsTest(unittest.TestCase): + def problem_config(self): + self.assertEqual(ProblemsConfig.name, 'problems') + self.assertEqual(apps.get_app_config('problems').name, 'problems') + +# forms.py test +''' +class ProblemFormTest(TestCase): + +class ProblemTestCaseFormTest(TestCase): + ''' + +# models.py test +class ProblemModelTest(TestCase): + + #Testing the models.CharField variables as strings + def test_title_string_representation(self): + test_title = Problem(title = "This is an Amazing Title!") + self.assertEqual(str(test_title), test_title.title) +''' +class ProblemTestCaseModelTest(TestCase): + +# urls.py test +class UrlsTest(TestCase): -# Create your tests here. +# views.py test +class ViewsTest(TestCase): +''' diff --git a/unicode/users/models.py b/unicode/users/models.py index 2d3b61d..b0e11a6 100644 --- a/unicode/users/models.py +++ b/unicode/users/models.py @@ -18,3 +18,5 @@ class Profile(models.Model): school = models.CharField(max_length=50) graduation_year = models.IntegerField() + + diff --git a/unicode/users/tests.py b/unicode/users/tests.py index 7ce503c..364af02 100644 --- a/unicode/users/tests.py +++ b/unicode/users/tests.py @@ -1,3 +1,24 @@ +import unittest + +from django.apps import apps from django.test import TestCase +from users.apps import UsersConfig +from users.forms import UserRegistrationForm +from users.models import Profile + +# app.py test +class AppsTest(unittest.TestCase): + def problem_config(self): + self.assertEqual(UsersConfig.name, 'users') + self.assertEqual(apps.get_app_config('users').name, 'users') + +''' +# forms.py test +class UserRegistrationFormTest(TestCase): + +# models.py test +class ProfileModelTest(TestCase): -# Create your tests here. +# views.py test +class ViewsTest(TestCase): +''' \ No newline at end of file