import random
import string
import unittest
import os

# local common lib
import common


"""Test RAPFD metric.

Example is taken from original paper:
title: A Revisit of Metrics for Test Case Prioritization Problems
authors: Wang, Ziyuan and Fang, Chunrong and Chen, Lin and Zhang, Zhiyi
sections
    2.3. Physical explanations of existing APFD series metrics
    4.1. Relative-APFD

faults:
+------+----+----+----+----+----+----+----+----+
|      | φ1 | φ2 | φ3 | φ4 | φ5 | φ6 | φ7 | φ8 |
+------+----+----+----+----+----+----+----+----+
| T1   |    |    |    |    |    |    | x  | x  |
| T2   |    | x  |    |    |    |    |    |    |
| T3   |    | x  |    | x  |    |    | x  |    |
| T4   | x  |    | x  |    |    |    |    |    |
| T5   |    |    |    | x  | x  | x  |    |    |
| T6   | x  |    | x  |    |    |    |    | x  |
+------+----+----+----+----+----+----+----+----+


Taking the prioritized test suite σ₁ : T3  T5  T2  T4  T1
RAPFD(σ₁, 1) = 0
RAPFD(σ₁, 2) = 3/16   = 18.75%
RAPFD(σ₁, 3) = 1/3    = 33.33%
RAPFD(σ₁, 4) = 13/32  = 40.62%
RAPFD(σ₁, 5) = 1/2    = 50.00%
RAPFD(σ₁, 6) = 7/12   = 58.33%
RAPFD(σ₁, 7) = 9/14   = 64.28%

Per test mutation score:
t1 = 2/8 = 0.25
t2 = 1/8 = 0.125
t3 = 3/8 = 0.375
t4 = 2/8 = 0.25
t5 = 3/8 = 0.375
t6 = 3/8 = 0.375

Per-Mutation per-test aggregation stats:
    all muts    kills   survived    per_test_kills   per_test_survives    test_size   
AOR        8        8          0                14                  35            6

kills: overall number of faults are 8
overall number of kills for AOR is 14
overall check count is test_size * all_muts because every test is a potential mutant checker
therefore
survives: 0
"""

# global test call counter, starts at 0 because mutpy first execs w/o mutants
common.initialize_counter()

class TestSuite(unittest.TestCase):

    # executes before every test suite run
    @classmethod
    def setUpClass(cls):
        cls.call_count = common.get_counter()

    # executes after every test suite run
    @classmethod
    def tearDownClass(cls):
        common.last_test_routine()

    def test_1_t3(self):
        """First detector."""
        common.simulate_test_case_run(self.call_count, fault_ids_to_detect=[2,4,7])

    def test_2_t5(self):
        """Second detector."""
        common.simulate_test_case_run(self.call_count, fault_ids_to_detect=[4,5,6])

    def test_3_t2(self):
        """Third detector."""
        common.simulate_test_case_run(self.call_count, fault_ids_to_detect=[2])

    def test_4_t4(self):
        """Fourth detector."""
        common.simulate_test_case_run(self.call_count, fault_ids_to_detect=[1,3])

    def test_5_t1(self):
        """Fifth detector."""
        common.simulate_test_case_run(self.call_count, fault_ids_to_detect=[7,8])

    def test_6_t6(self):
        """Sixth detector, should not be in rapfd for m<=5."""
        common.simulate_test_case_run(self.call_count, fault_ids_to_detect=[1,3,8])