import unittest from pandas.testing import assert_series_equal from pyprojroot import here from features.esm import * from features.esm_JCQ import * class EsmFeatures(unittest.TestCase): @classmethod def setUpClass(cls) -> None: cls.esm = pd.read_csv(here("data/example_esm.csv"), sep=";") cls.esm["esm_json"] = cls.esm["esm_json"].apply(eval) cls.esm_processed = preprocess_esm(cls.esm) cls.esm_clean = clean_up_esm(cls.esm_processed) def test_preprocess_esm(self): self.esm_processed = preprocess_esm(self.esm) # Check for columns which should have been extracted from esm_json. self.assertIn("question_id", self.esm_processed) self.assertIn("questionnaire_id", self.esm_processed) self.assertIn("esm_instructions", self.esm_processed) self.assertIn("esm_type", self.esm_processed) self.assertIn("time", self.esm_processed) # Check for explicitly added column. self.assertIn("datetime_lj", self.esm_processed) # All of these keys are referenced in other functions, so they are expected to be present in preprocessed ESM. # Since all of these are added in a single function, it should be OK to have many assert statements in one test. def test_classify_sessions_by_completion(self): self.esm_classified_sessions = classify_sessions_by_completion( self.esm_processed ) self.assertFalse(self.esm_classified_sessions["session_response"].isna().any()) # Test that all sessions were indeed classified. def test_classify_sessions_by_completion_time(self): self.esm_classified = classify_sessions_by_completion_time(self.esm_processed) session_of_interest = ( self.esm_processed.query( "(device_id == '049df3f8-8541-4cf5-af2b-83f6b3f0cf4b') & (esm_session == 1)" ) .sort_values("_id") .reset_index() ) session_of_interest_reclassified = self.esm_classified.query( "(device_id == '049df3f8-8541-4cf5-af2b-83f6b3f0cf4b') & (esm_session == 1)" ).reset_index() self.assertEqual(session_of_interest.loc[0, "time"], "morning") self.assertEqual(session_of_interest_reclassified.loc[0, "time"], "daytime") # Check that the first (morning) session is reclassified as a daytime session. def test_clean_up_esm(self): self.assertNotIn("esm_user_answer_numeric", self.esm_processed) self.assertIn("esm_user_answer_numeric", self.esm_clean) def test_reverse_jcq_demand_control_scoring(self): esm_reversed = reverse_jcq_demand_control_scoring(self.esm_clean) self.assertEqual( 0, int( self.esm_clean.loc[ self.esm_clean["question_id"] == 73, "esm_user_answer_numeric" ] ), ) self.assertEqual( 1, int(esm_reversed.loc[esm_reversed["question_id"] == 73, "esm_user_score"]), ) # An example of a regular item: the score gets incremented by 1, to shift to 1-4 scoring. self.assertEqual( 0, int( self.esm_clean.loc[ self.esm_clean["question_id"] == 79, "esm_user_answer_numeric" ] ), ) self.assertEqual( 4, int(esm_reversed.loc[esm_reversed["question_id"] == 79, "esm_user_score"]), ) # An example of a reversed item.