Пример #1
0
    def test_adapt_db_expected_list(self):
        """Test for adapting dictionaries in initial_db and expected_result to unitary lists """
        collection = Collection(name_md='Colección', position=8, description_md='Colección de pruebas', author=None)
        collection.save()

        # Problems with dictionaries or already with [dict]
        problems = [
            SelectProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                          author=None, expected_result=dict()),
            DMLProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                       author=None, expected_result=dict()),
            FunctionProblem(title_html="titulo", text_html="enunciado", initial_db=dict(),
                            collection=collection, author=None, expected_result=dict()),
            ProcProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                        author=None, expected_result=dict()),
            TriggerProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                           author=None, expected_result=dict()),
            SelectProblem(title_html="titulo", text_html="enunciado", initial_db=[dict()], collection=collection,
                          author=None, expected_result=[dict()]),  # already has the right representation
        ]

        for prob in problems:
            prob.save()

        adapt_db_result_to_list()
        for prob in Problem.objects.all().select_subclasses():
            self.assertIs(type(prob.initial_db), list)
            self.assertIs(type(prob.initial_db[0]), dict)
            self.assertIs(type(prob.expected_result), list)
            self.assertIs(type(prob.expected_result[0]), dict)

        for prob in Problem.objects.all():
            prob.delete()

        # Problems with wrong types in initial_db or expected_result
        wrong_problems = [
            SelectProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                          author=None, expected_result=3),
            DMLProblem(title_html="titulo", text_html="enunciado", initial_db=6, collection=collection,
                       author=None, expected_result=dict()),
            FunctionProblem(title_html="titulo", text_html="enunciado", initial_db=[],
                            collection=collection, author=None, expected_result=dict()),
            ProcProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                        author=None, expected_result=[3]),
            TriggerProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                           author=None, expected_result=[]),
            TriggerProblem(title_html="titulo", text_html="enunciado", initial_db=dict(), collection=collection,
                           author=None, expected_result=[dict(), dict(), False]),
        ]

        # Tries every wrong program individually (removing it after checking the exception)
        for prob in wrong_problems:
            prob.save()
            with self.assertRaises(TypeError):
                adapt_db_result_to_list()
            prob.delete()
Пример #2
0
    def test_individual_zip(self):
        """Load problem data from valid ZIP"""
        curr_path = os.path.dirname(__file__)
        zip_select_path = os.path.join(curr_path, self.ZIP_FOLDER,
                                       self.SELECT_OK)
        zip_dml_path = os.path.join(curr_path, self.ZIP_FOLDER, self.DML_OK)
        zip_function_path = os.path.join(curr_path, self.ZIP_FOLDER,
                                         self.FUNCTION_OK)
        zip_proc_path = os.path.join(curr_path, self.ZIP_FOLDER, self.PROC_OK)
        zip_trigger_path = os.path.join(curr_path, self.ZIP_FOLDER,
                                        self.TRIGGER_OK)
        zip_discriminant_path = os.path.join(curr_path, self.ZIP_FOLDER,
                                             self.DISCRIMINANT_OK)

        select_problem = SelectProblem(zipfile=zip_select_path)
        dml_problem = DMLProblem(zipfile=zip_dml_path)
        function_problem = FunctionProblem(zipfile=zip_function_path)
        proc_problem = ProcProblem(zipfile=zip_proc_path)
        trigger_problem = TriggerProblem(zipfile=zip_trigger_path)
        discriminant_problem = DiscriminantProblem(
            zipfile=zip_discriminant_path)

        for problem in [
                select_problem, dml_problem, function_problem, proc_problem,
                trigger_problem, discriminant_problem
        ]:
            self.assertFalse(problem.text_md)
            problem.clean()
            self.assertTrue(problem.text_md)
            self.assertTrue('.html' in problem.template())
            self.assertTrue(str(problem))
            self.assertEqual(problem.language, 'es')
Пример #3
0
    def test_plsql_correct(self):
        """Accepted submissions to function/procedure/trigger problem"""

        curr_path = os.path.dirname(__file__)
        zip_function_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                         ParseTest.FUNCTION_OK)
        zip_proc_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                     ParseTest.PROC_OK)
        zip_trigger_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                        ParseTest.TRIGGER_OK)

        client = Client()
        collection = create_collection('Colleccion de prueba AAA')
        user = create_user('54522', 'antonio')
        client.login(username='******', password='******')

        function_problem = FunctionProblem(zipfile=zip_function_path,
                                           collection=collection,
                                           author=user)
        proc_problem = ProcProblem(zipfile=zip_proc_path,
                                   collection=collection,
                                   author=user)
        trigger_problem = TriggerProblem(zipfile=zip_trigger_path,
                                         collection=collection,
                                         author=user)

        for problem in [function_problem, proc_problem, trigger_problem]:
            problem.clean()
            problem.save()
            submit_url = reverse('judge:submit', args=[problem.pk])
            response = client.post(submit_url, {'code': problem.solution},
                                   follow=True)
            self.assertEqual(response.json()['veredict'], VeredictCode.AC)
Пример #4
0
    def test_show_problems(self):
        """Shows a problem of each type"""
        curr_path = os.path.dirname(__file__)
        zip_select_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.SELECT_OK)
        zip_dml_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.DML_OK)
        zip_function_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.FUNCTION_OK)
        zip_proc_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.PROC_OK)
        zip_trigger_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER, ParseTest.TRIGGER_OK)

        collection = create_collection('Colleccion de prueba XYZ')
        user = create_user('5555', 'pepe')

        select_problem = SelectProblem(zipfile=zip_select_path, collection=collection, author=user)
        dml_problem = DMLProblem(zipfile=zip_dml_path, collection=collection, author=user)
        function_problem = FunctionProblem(zipfile=zip_function_path, collection=collection, author=user)
        proc_problem = ProcProblem(zipfile=zip_proc_path, collection=collection, author=user)
        trigger_problem = TriggerProblem(zipfile=zip_trigger_path, collection=collection, author=user)

        client = Client()
        client.login(username='******', password='******')

        for problem in [select_problem, dml_problem, function_problem, proc_problem, trigger_problem]:
            problem.clean()
            problem.save()
            problem_url = reverse('judge:problem', args=[problem.pk])
            response = client.get(problem_url, follow=True)
            self.assertEqual(response.status_code, 200)
            self.assertIn(problem.title_html, response.content.decode('utf-8'))
Пример #5
0
    def test_load_hint(self):
        """Test to check if hints.md is loaded correctly"""
        curr_path = os.path.dirname(__file__)
        zip_dml_path = os.path.join(curr_path, self.ZIP_FOLDER, self.DML_HINTS)
        zip_function_path = os.path.join(curr_path, self.ZIP_FOLDER, self.FUNCTION_HINTS)
        zip_proc_path = os.path.join(curr_path, self.ZIP_FOLDER, self.PROC_HINTS)
        zip_trigger_path = os.path.join(curr_path, self.ZIP_FOLDER, self.TRIGGER_HINTS)
        zip_discriminant_path = os.path.join(curr_path, self.ZIP_FOLDER, self.DISCRIMINANT_HINTS)
        collection = create_collection('Coleccion 1')

        dml = DMLProblem(zipfile=zip_dml_path, collection=collection)
        function = FunctionProblem(zipfile=zip_function_path, collection=collection)
        proc = ProcProblem(zipfile=zip_proc_path, collection=collection)
        trigger = TriggerProblem(zipfile=zip_trigger_path, collection=collection)
        discriminant = DiscriminantProblem(zipfile=zip_discriminant_path, collection=collection)

        hints_expected1 = (3, 'descripcion pista 1')
        hints_expected2 = (5, 'descripcion pista 2')
        hints_expected3 = (10, 'descripcion pista 3')

        for problem in [dml, function, proc, trigger, discriminant]:
            problem.clean()
            problem.save()
            hints = Hint.objects.filter(problem=problem).order_by('num_submit')
            self.assertEqual(hints.count(), 3)
            self.assertEqual(hints_expected1[0], hints[0].num_submit)
            self.assertEqual(hints_expected1[1], hints[0].text_md)
            self.assertEqual(hints_expected2[0], hints[1].num_submit)
            self.assertEqual(hints_expected2[1], hints[1].text_md)
            self.assertEqual(hints_expected3[0], hints[2].num_submit)
            self.assertEqual(hints_expected3[1], hints[2].text_md)
Пример #6
0
    def test_zip_errors(self):
        """ValidationError when loading ZIP in all problem types"""
        curr_path = os.path.dirname(__file__)

        # Select problems
        for filename in [
                self.SELECT_MISSING_FILES, self.SELECT_EMPTY_TITLE,
                self.SELECT_TEXT_DECODE
        ]:
            zip_path = os.path.join(curr_path, self.ZIP_FOLDER, filename)
            problem = SelectProblem(zipfile=zip_path)
            self.assertRaises(ValidationError, problem.clean)

        # DML problems
        for filename in [
                self.DML_MISSING_FILES, self.DML_BAD_NUM_STMT,
                self.DML_TEXT_DECODE
        ]:
            zip_path = os.path.join(curr_path, self.ZIP_FOLDER, filename)
            problem = DMLProblem(zipfile=zip_path)
            self.assertRaises(ValidationError, problem.clean)

        # Function problems
        for filename in [
                self.FUNCTION_MISSING_FILES, self.FUNCTION_EMPTY_TITLE,
                self.FUNCTION_TEXT_DECODE
        ]:
            zip_path = os.path.join(curr_path, self.ZIP_FOLDER, filename)
            problem = FunctionProblem(zipfile=zip_path)
            self.assertRaises(ValidationError, problem.clean)

        # Procedure problems
        for filename in [
                self.PROC_MISSING_FILES, self.PROC_EMPTY_TITLE,
                self.PROC_TEXT_DECODE
        ]:
            zip_path = os.path.join(curr_path, self.ZIP_FOLDER, filename)
            problem = ProcProblem(zipfile=zip_path)
            self.assertRaises(ValidationError, problem.clean)

        # Trigger problems
        for filename in [
                self.TRIGGER_MISSING_FILES, self.TRIGGER_EMPTY_TITLE,
                self.TRIGGER_TEXT_DECODE, self.TRIGGER_BAD_INSERT
        ]:
            zip_path = os.path.join(curr_path, self.ZIP_FOLDER, filename)
            problem = TriggerProblem(zipfile=zip_path)
            self.assertRaises(ValidationError, problem.clean)

        # Discriminant problems
        for filename in [
                self.DISCRIMINANT_MISSING_FILES, self.DISCRIMINANT_BAD_STMT,
                self.DISCRIMINANT_TEXT_DECODE
        ]:
            zip_path = os.path.join(curr_path, self.ZIP_FOLDER, filename)
            problem = DiscriminantProblem(zipfile=zip_path)
            self.assertRaises(ValidationError, problem.clean)
Пример #7
0
    def test_download(self):
        """Download the script of a problem (CREATE + INSERT)"""
        curr_path = os.path.dirname(__file__)
        zip_select_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                       ParseTest.SELECT_OK)
        zip_dml_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                    ParseTest.DML_OK)
        zip_function_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                         ParseTest.FUNCTION_OK)
        zip_proc_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                     ParseTest.PROC_OK)
        zip_trigger_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                        ParseTest.TRIGGER_OK)

        collection = create_collection('Colleccion de prueba AAA')
        user = create_user('54522', 'antonio')

        select_problem = SelectProblem(zipfile=zip_select_path,
                                       collection=collection,
                                       author=user)
        dml_problem = DMLProblem(zipfile=zip_dml_path,
                                 collection=collection,
                                 author=user)
        function_problem = FunctionProblem(zipfile=zip_function_path,
                                           collection=collection,
                                           author=user)
        proc_problem = ProcProblem(zipfile=zip_proc_path,
                                   collection=collection,
                                   author=user)
        trigger_problem = TriggerProblem(zipfile=zip_trigger_path,
                                         collection=collection,
                                         author=user)

        client = Client()
        client.login(username='******', password='******')

        for problem in [
                select_problem, dml_problem, function_problem, proc_problem,
                trigger_problem
        ]:
            problem.clean()
            problem.save()
            url = reverse('judge:create_insert', args=[problem.pk])
            response = client.get(url, follow=True)
            script = problem.create_sql + '\n\n' + problem.insert_sql

            self.assertEqual(
                response.get('Content-Disposition'),
                "attachment; filename=create_insert.sql",
            )
            self.assertEqual(response.get('Content-Type'), "application/sql")
            self.assertEqual(response.content.decode('UTF-8'), script)

            self.assertEqual(response.status_code, 200)
Пример #8
0
    def test_proc_problem_language(self):
        """Test to check if language in proc problem page displays correctly"""
        curr_path = os.path.dirname(__file__)
        client = Client()

        zip_proc_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                     ParseTest.PROC_OK)
        collection = create_collection('Colleccion de prueba XYZ')
        user = create_user('5555', 'pepe')
        problem = ProcProblem(zipfile=zip_proc_path,
                              collection=collection,
                              author=user)
        problem.clean()
        problem.save()
        client.login(username='******', password='******')

        client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'en'})
        url = reverse('judge:problem', args=[problem.pk])
        response = client.get(url, follow=True)
        self.assertIn('Procedure call', response.content.decode('utf-8'))
        self.assertIn('Expected result', response.content.decode('utf-8'))

        client.cookies.load({settings.LANGUAGE_COOKIE_NAME: 'es'})
        url = reverse('judge:problem', args=[problem.pk])
        response = client.get(url, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertIn('Llamada a procedimiento',
                      response.content.decode('utf-8'))
        self.assertIn('Resultado esperado', response.content.decode('utf-8'))
Пример #9
0
    def test_no_type(self):
        """Loading problem details form a ZIP with a JSON file without type field"""
        curr_path = os.path.dirname(__file__)
        zip_path = os.path.join(curr_path, self.ZIP_FOLDER, self.NO_TYPE)

        select_problem = SelectProblem(zipfile=zip_path)
        dml_problem = DMLProblem(zipfile=zip_path)
        function_problem = FunctionProblem(zipfile=zip_path)
        proc_problem = ProcProblem(zipfile=zip_path)
        trigger_problem = TriggerProblem(zipfile=zip_path)
        discriminant_problem = DiscriminantProblem(zipfile=zip_path)

        for problem in [
                select_problem, dml_problem, function_problem, proc_problem,
                trigger_problem, discriminant_problem
        ]:
            self.assertRaises(ValidationError, problem.clean)
Пример #10
0
    def test_zip_other_type(self):
        """Loading a problem data from a ZIP of a different type must raise a ValidationError"""
        curr_path = os.path.dirname(__file__)
        zip_select_path = os.path.join(curr_path, self.ZIP_FOLDER,
                                       self.SELECT_OK)
        zip_dml_path = os.path.join(curr_path, self.ZIP_FOLDER, self.DML_OK)
        zip_function_path = os.path.join(curr_path, self.ZIP_FOLDER,
                                         self.FUNCTION_OK)
        zip_proc_path = os.path.join(curr_path, self.ZIP_FOLDER, self.PROC_OK)
        zip_trigger_path = os.path.join(curr_path, self.ZIP_FOLDER,
                                        self.TRIGGER_OK)

        select_problem = SelectProblem(zipfile=zip_dml_path)
        dml_problem = DMLProblem(zipfile=zip_function_path)
        function_problem = FunctionProblem(zipfile=zip_proc_path)
        proc_problem = ProcProblem(zipfile=zip_trigger_path)
        trigger_problem = TriggerProblem(zipfile=zip_select_path)
        discriminant_problem = TriggerProblem(zipfile=zip_select_path)

        for problem in [
                select_problem, dml_problem, function_problem, proc_problem,
                trigger_problem, discriminant_problem
        ]:
            self.assertRaises(ValidationError, problem.clean)
Пример #11
0
    def test_proc(self):
        """Tests for ProcProblem.judge()"""
        collection = Collection()
        collection.save()
        create = '''CREATE TABLE Club(
                        CIF CHAR(9) PRIMARY KEY, -- No puede ser NULL
                        Nombre VARCHAR2(40) NOT NULL UNIQUE,
                        Sede VARCHAR2(30) NOT NULL,
                        Num_Socios NUMBER(10,0) NOT NULL,
                        CONSTRAINT NumSociosPositivos CHECK (Num_Socios >= 0)
                    );'''
        insert = """INSERT INTO Club VALUES ('11111111X', 'Real Madrid CF', 'Concha Espina', 70000);
                    INSERT INTO Club VALUES ('11111112X', 'Futbol Club Barcelona', 'Aristides Maillol', 80000);
                    INSERT INTO Club VALUES ('11111113X', 'PSG', 'Rue du Commandant Guilbaud', 1000);"""
        solution = """
            CREATE OR REPLACE PROCEDURE inserta(x NUMBER) IS
                num_equipos NUMBER;
            BEGIN
                SELECT COUNT(*) INTO num_equipos FROM Club;
                INSERT INTO CLUB VALUES ('22222222X', 'A', 'B', num_equipos + x);
            END;"""
        call = "inserta(4)"

        # Time-limit
        tle = """
                CREATE OR REPLACE PROCEDURE inserta(x NUMBER) IS
                    num_equipos NUMBER;
                    IN_TIME INT := 11; --num seconds
                    v_now DATE;
                BEGIN
                    SELECT SYSDATE INTO v_now FROM DUAL;
                    SELECT COUNT(*) INTO num_equipos FROM Club;
                    LOOP
                        EXIT WHEN v_now + (IN_TIME * (1/86400)) <= SYSDATE;
                    END LOOP;  
                    INSERT INTO CLUB VALUES ('22222222X', 'A', 'B', num_equipos + x);
                END;"""
        # Error in the procedure code
        compile_error = """
                CREATE OR REPLACE PROCEDURE inserta(x NUMBER) IS
                    num_equipos NUMBER;
                BEGIN
                    SELECT SYSDATE INTO v_now DUAL; -- Falta FROM
                    INSERT INTO CLUB VALUES ('22222222X', 'A', 'B', num_equipos + x);
                END;"""
        # Division by zero
        runtime_error1 = """
                CREATE OR REPLACE PROCEDURE inserta(x NUMBER) IS
                    num_equipos NUMBER;
                BEGIN
                    SELECT COUNT(*) INTO num_equipos FROM Club;
                    INSERT INTO CLUB VALUES ('22222222X', 'A', 'B', num_equipos / 0); -- Division by zero
                END;"""
        # Incompatible type in parameter
        runtime_error2 = """
                CREATE OR REPLACE PROCEDURE inserta(x DATE) IS -- Incorrect parameter when invoked
                    num_equipos NUMBER;
                BEGIN
                    SELECT COUNT(*) INTO num_equipos FROM Club;
                    INSERT INTO CLUB VALUES ('22222222X', 'A', 'B', num_equipos);
                END;"""
        wrong_answer = """
            CREATE OR REPLACE PROCEDURE inserta(x NUMBER) IS
                num_equipos NUMBER;
            BEGIN
                SELECT COUNT(*) INTO num_equipos FROM Club;
                INSERT INTO CLUB VALUES ('22222222X', 'A', 'B', num_equipos + x + 2);
            END;"""
        bad_name = """
                    CREATE OR REPLACE PROCEDURE insertaR(x NUMBER) IS
                        num_equipos NUMBER;
                    BEGIN
                        SELECT COUNT(*) INTO num_equipos FROM Club;
                        INSERT INTO CLUB VALUES ('22222222X', 'A', 'B', num_equipos + x);
                    END;"""

        oracle = OracleExecutor.get()
        problem = ProcProblem(title_md='Test Function',
                              text_md='bla bla bla',
                              create_sql=create,
                              insert_sql=insert,
                              collection=collection,
                              author=None,
                              solution=solution,
                              proc_call=call)
        problem.clean()  # Needed to compute extra HTML fields and solutions
        problem.save()

        # Time-limit
        self.assert_executor_exception(lambda: problem.judge(tle, oracle),
                                       OracleStatusCode.TLE_USER_CODE)

        # Error when compiling user function
        self.assert_executor_exception(
            lambda: problem.judge(compile_error, oracle),
            OracleStatusCode.COMPILATION_ERROR)

        # Error when invoking user function
        self.assert_executor_exception(
            lambda: problem.judge(runtime_error1, oracle),
            OracleStatusCode.EXECUTE_USER_CODE)
        self.assert_executor_exception(
            lambda: problem.judge(runtime_error2, oracle),
            OracleStatusCode.EXECUTE_USER_CODE)
        self.assert_executor_exception(lambda: problem.judge(bad_name, oracle),
                                       OracleStatusCode.EXECUTE_USER_CODE)

        # Correct solution
        self.assertEqual(problem.judge(solution, oracle)[0], VeredictCode.AC)

        # Incorrect solution
        self.assertEqual(
            problem.judge(wrong_answer, oracle)[0], VeredictCode.WA)
Пример #12
0
    def test_compile_error(self):
        """Submitting code for a function/procedure/trigger with a compile error does resturn a
        OracleStatusCode.COMPILATION_ERROR"""
        curr_path = os.path.dirname(__file__)
        zip_function_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                         ParseTest.FUNCTION_OK)
        zip_proc_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                     ParseTest.PROC_OK)
        zip_trigger_path = os.path.join(curr_path, ParseTest.ZIP_FOLDER,
                                        ParseTest.TRIGGER_OK)

        client = Client()
        collection = create_collection('Colleccion de prueba AAA')
        user = create_user('54522', 'antonio')
        client.login(username='******', password='******')

        function_problem = FunctionProblem(zipfile=zip_function_path,
                                           collection=collection,
                                           author=user)
        proc_problem = ProcProblem(zipfile=zip_proc_path,
                                   collection=collection,
                                   author=user)
        trigger_problem = TriggerProblem(zipfile=zip_trigger_path,
                                         collection=collection,
                                         author=user)

        funct_compile_error = """
                            CREATE OR REPLACE FUNCTION golesLocal(resultado VARCHAR2) RETURN NUMBER IS
                              posGuion NUMBER;
                              golesStr VARCHAR2(3);
                            BEGIN
                              posGuion := INSTR(resultado, '-') -- Missing ';'
                              golesStr := SUBSTR(resultado, 0, posGuion - 1);
                              RETURN TO_NUMBER(golesStr); 
                            END;"""
        proc_compile_error = """
            CREATE OR REPLACE PROCEDURE actualiza_socios(club_cif CHAR) IS
                CURSOR cr_partidos IS SELECT CL.Nombre AS ClubL, CV.Nombre AS ClubV, COUNT(*) AS NAsistentes
                                      FROM Enfrenta JOIN Asiste USING(CIF_local, CIF_visitante)
                                           JOIN Club CL ON CL.CIF = CIF_Local
                                           JOIN Club CV ON CV.CIF = CIF_visitante
                                      WHERE CIF_local = club_cif OR CIF_visitante = club_cif
                                      GROUP BY CIF_local, CIF_visitante, CL.Nombre, CV.Nombre;
                incrPartido NUMBER;
                incrTotal NUMBER := 0;
                nPartido NUMBER := 1;
                nombreClub VARCHAR2(200);
            BEGIN
                SELECT Nombre 
                INTO nombreClub
                FROM Club
                WHERE CIF = club_cif;
        
                FOR partido IN cr_partidos LOOP
                  IF partido.NAsistentes > 3 THEN
                    incrPartido := 100;
                  ELSIF partido.NAsistentes > 1 -- Missing 'THEN'
                    incrPartido := 10;
                  ELSE 
                    incrPartido := 0;
                  END IF;
                  incrTotal := incrTotal + incrPartido;
                  nPartido := nPartido + 1;
                END LOOP;
        
                UPDATE Club
                SET Num_Socios = Num_Socios + incrTotal
                WHERE CIF = club_cif;
            END;"""

        trigger_compile_error = """
                                CREATE OR REPLACE TRIGGER DispCantidadFinanciacion
                                BEFORE INSERT OR UPDATE
                                ON Financia FOR EACH ROW
                                DECLARE
                                  numJug NUMBER;
                                BEGIN
                                  SELECT COUNT(*) INTO numJug
                                  FROM Jugador
                                  WHERE CIF = :NEW.CIF_C;
        
                                  IF numJug >= 2 THEN
                                    :NEW.Cantidad := :NEW.Cantidad  1.25; -- Missing operator
                                  END IF;
                                END;"""

        for (problem, code) in [(function_problem, funct_compile_error),
                                (proc_problem, proc_compile_error),
                                (trigger_problem, trigger_compile_error)]:
            problem.clean()
            problem.save()
            submit_url = reverse('judge:submit', args=[problem.pk])
            response = client.post(submit_url, {'code': code}, follow=True)
            self.assertEqual(response.json()['veredict'], VeredictCode.WA)
            self.assertIn('error', response.json()['feedback'])
            self.assertIn('compil', response.json()['feedback'])