navkast commited on
Commit
e261f25
Β·
unverified Β·
1 Parent(s): 145d03b

Add a test for main.py (#3)

Browse files

* Add a test for main.py

* Improved nesting on the test classes

src/vsp/app/classifiers/education_classifier.py CHANGED
@@ -51,6 +51,7 @@ class EducationClassification(BaseModel):
51
  output: SchoolType = Field(description="The classified school type")
52
  confidence: float = Field(description="Confidence level between 0.0 and 1.0")
53
  reasoning: str = Field(description="Explanation for the classification")
 
54
 
55
 
56
  class EducationClassifier:
 
51
  output: SchoolType = Field(description="The classified school type")
52
  confidence: float = Field(description="Confidence level between 0.0 and 1.0")
53
  reasoning: str = Field(description="Explanation for the classification")
54
+ model_config = {"frozen": True} # This makes the model immutable and hashable
55
 
56
 
57
  class EducationClassifier:
src/vsp/app/classifiers/work_experience/general_work_experience_classifier.py CHANGED
@@ -73,6 +73,7 @@ class WorkExperienceClassification(BaseModel):
73
  secondary_job_type: SecondaryJobType = Field(description="The classified secondary job type")
74
  confidence: float = Field(description="Confidence level between 0.0 and 1.0", ge=0.0, le=1.0)
75
  reasoning: str = Field(description="Explanation for the classification")
 
76
 
77
 
78
  class WorkExperienceClassifier:
 
73
  secondary_job_type: SecondaryJobType = Field(description="The classified secondary job type")
74
  confidence: float = Field(description="Confidence level between 0.0 and 1.0", ge=0.0, le=1.0)
75
  reasoning: str = Field(description="Explanation for the classification")
76
+ model_config = {"frozen": True} # This makes the model immutable and hashable
77
 
78
 
79
  class WorkExperienceClassifier:
src/vsp/app/classifiers/work_experience/investment_banking_group_classifier.py CHANGED
@@ -70,6 +70,7 @@ class InvestmentBankingGroupClassification(BaseModel):
70
  investment_banking_group: InvestmentBankingGroup = Field(description="The investment banking group")
71
  confidence: float = Field(description="Confidence level between 0.0 and 1.0", ge=0.0, le=1.0)
72
  reasoning: str = Field(description="Explanation for the classification")
 
73
 
74
 
75
  class InvestmentBankingGroupClassifier:
 
70
  investment_banking_group: InvestmentBankingGroup = Field(description="The investment banking group")
71
  confidence: float = Field(description="Confidence level between 0.0 and 1.0", ge=0.0, le=1.0)
72
  reasoning: str = Field(description="Explanation for the classification")
73
+ model_config = {"frozen": True} # This makes the model immutable and hashable
74
 
75
 
76
  class InvestmentBankingGroupClassifier:
tests/{app β†’ vsp}/__init__.py RENAMED
File without changes
tests/{app/prompts β†’ vsp/app}/__init__.py RENAMED
File without changes
tests/{app β†’ vsp/app}/classifiers/test_education_classifier.py RENAMED
File without changes
tests/{app β†’ vsp/app}/classifiers/work_experience/test_investment_banking_group_classifier.py RENAMED
File without changes
tests/{app β†’ vsp/app}/classifiers/work_experience/test_work_experience_classifier.py RENAMED
File without changes
tests/{llm/__ini__.py β†’ vsp/app/prompts/__init__.py} RENAMED
File without changes
tests/{app β†’ vsp/app}/prompts/test_prompt_loader.py RENAMED
File without changes
tests/{app β†’ vsp/app}/prompts/test_prompts/basic_test/1 - test_human.txt RENAMED
File without changes
tests/{app β†’ vsp/app}/prompts/test_prompts/basic_test/1 - test_system.txt RENAMED
File without changes
tests/{app β†’ vsp/app}/prompts/test_prompts/basic_test/2 - test2_system.txt RENAMED
File without changes
tests/{app β†’ vsp/app}/prompts/test_prompts/basic_test/2 - test2_user.txt RENAMED
File without changes
tests/{app β†’ vsp/app}/prompts/test_prompts/basic_test/nested/1 - nested_test_human.txt RENAMED
File without changes
tests/vsp/app/test_main.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from unittest.mock import AsyncMock, patch
2
+
3
+ import pytest
4
+
5
+ from vsp.app.classifiers.education_classifier import EducationClassification, SchoolType
6
+ from vsp.app.classifiers.work_experience.general_work_experience_classifier import (
7
+ PrimaryJobType,
8
+ SecondaryJobType,
9
+ WorkExperienceClassification,
10
+ )
11
+ from vsp.app.classifiers.work_experience.investment_banking_group_classifier import (
12
+ InvestmentBankingGroup,
13
+ InvestmentBankingGroupClassification,
14
+ )
15
+ from vsp.app.main import LinkedinProfileClassificationResults, process_linkedin_profile
16
+ from vsp.app.model.linkedin.linkedin_models import Education, LinkedinProfile, Position
17
+
18
+
19
+ @pytest.fixture
20
+ def sample_linkedin_profile():
21
+ return LinkedinProfile(
22
+ first_name="John",
23
+ last_name="Doe",
24
+ educations=[
25
+ Education(
26
+ school_name="Test University",
27
+ degree="MBA",
28
+ field_of_study="Business",
29
+ )
30
+ ],
31
+ position=[
32
+ Position(
33
+ title="Investment Banking Analyst",
34
+ company_name="Bank Corp",
35
+ ),
36
+ Position(
37
+ title="Software Engineer",
38
+ company_name="Tech Corp",
39
+ ),
40
+ ],
41
+ )
42
+
43
+
44
+ @pytest.mark.asyncio
45
+ async def test_process_linkedin_profile_investment_banking(sample_linkedin_profile):
46
+ with (
47
+ patch("vsp.app.main.EducationClassifier") as mock_education_classifier,
48
+ patch("vsp.app.main.WorkExperienceClassifier") as mock_work_experience_classifier,
49
+ patch("vsp.app.main.InvestmentBankingGroupClassifier") as mock_investment_banking_group_classifier,
50
+ ):
51
+ mock_education_classifier.return_value.classify_education = AsyncMock(
52
+ return_value=EducationClassification(output=SchoolType.MBA, confidence=1.0, reasoning="Test")
53
+ )
54
+ mock_work_experience_classifier.return_value.classify_work_experience = AsyncMock(
55
+ return_value=WorkExperienceClassification(
56
+ primary_job_type=PrimaryJobType.FULL_TIME,
57
+ secondary_job_type=SecondaryJobType.INVESTMENT_BANKING,
58
+ confidence=1.0,
59
+ reasoning="Test",
60
+ )
61
+ )
62
+ mock_investment_banking_group_classifier.return_value.classify_investment_banking_group = AsyncMock(
63
+ return_value=InvestmentBankingGroupClassification(
64
+ investment_banking_group=InvestmentBankingGroup.M_AND_A, confidence=1.0, reasoning="Test"
65
+ )
66
+ )
67
+
68
+ result = await process_linkedin_profile(sample_linkedin_profile)
69
+
70
+ assert isinstance(result, LinkedinProfileClassificationResults)
71
+ assert len(result.classified_educations) == 1
72
+ assert len(result.classified_work_experiences) == 2
73
+
74
+ # Check that the investment banking position has an investment banking group classification
75
+ ib_experience = result.classified_work_experiences[0]
76
+ assert ib_experience.work_experience_classification.secondary_job_type == SecondaryJobType.INVESTMENT_BANKING
77
+ assert ib_experience.investment_banking_classification is not None
78
+ assert (
79
+ ib_experience.investment_banking_classification.investment_banking_group == InvestmentBankingGroup.M_AND_A
80
+ )
81
+
82
+ # Check that the investment banking group classifier was called
83
+ mock_investment_banking_group_classifier.return_value.classify_investment_banking_group.assert_called()
84
+
85
+
86
+ @pytest.mark.asyncio
87
+ async def test_process_linkedin_profile_non_investment_banking(sample_linkedin_profile):
88
+ with (
89
+ patch("vsp.app.main.EducationClassifier") as mock_education_classifier,
90
+ patch("vsp.app.main.WorkExperienceClassifier") as mock_work_experience_classifier,
91
+ patch("vsp.app.main.InvestmentBankingGroupClassifier") as mock_investment_banking_group_classifier,
92
+ ):
93
+ mock_education_classifier.return_value.classify_education = AsyncMock(
94
+ return_value=EducationClassification(output=SchoolType.MBA, confidence=1.0, reasoning="Test")
95
+ )
96
+ mock_work_experience_classifier.return_value.classify_work_experience = AsyncMock(
97
+ return_value=WorkExperienceClassification(
98
+ primary_job_type=PrimaryJobType.FULL_TIME,
99
+ secondary_job_type=SecondaryJobType.ENGINEERING,
100
+ confidence=1.0,
101
+ reasoning="Test",
102
+ )
103
+ )
104
+ mock_investment_banking_group_classifier.return_value.classify_investment_banking_group = AsyncMock()
105
+
106
+ result = await process_linkedin_profile(sample_linkedin_profile)
107
+
108
+ assert isinstance(result, LinkedinProfileClassificationResults)
109
+ assert len(result.classified_educations) == 1
110
+ assert len(result.classified_work_experiences) == 2
111
+
112
+ # Check that none of the work experiences have an investment banking group classification
113
+ for experience in result.classified_work_experiences:
114
+ assert experience.work_experience_classification.secondary_job_type == SecondaryJobType.ENGINEERING
115
+ assert experience.investment_banking_classification is None
116
+
117
+ # Check that the investment banking group classifier was not called
118
+ mock_investment_banking_group_classifier.return_value.classify_investment_banking_group.assert_not_called()
119
+
120
+
121
+ if __name__ == "__main__":
122
+ pytest.main([__file__])
tests/vsp/llm/__ini__.py ADDED
File without changes
tests/{llm β†’ vsp/llm}/test_integration.py RENAMED
File without changes
tests/{llm β†’ vsp/llm}/test_prompt.py RENAMED
File without changes
tests/{llm β†’ vsp/llm}/test_prompt_chain.py RENAMED
File without changes
tests/{llm β†’ vsp/llm}/test_prompt_text.py RENAMED
File without changes