diff --git a/conda_recipe_v2_schema/model.py b/conda_recipe_v2_schema/model.py index d6c54aa..6228028 100644 --- a/conda_recipe_v2_schema/model.py +++ b/conda_recipe_v2_schema/model.py @@ -473,6 +473,26 @@ class PythonTestElement(StrictBaseModel): python: PythonTestElementInner = Field(..., description="Python specific test configuration") +class PerlTestElementInner(StrictBaseModel): + uses: ConditionalList[NonEmptyStr] = Field( + ..., description="A list of Perl modules to check after having installed the built package." + ) + + +class PerlTestElement(StrictBaseModel): + perl: PerlTestElementInner = Field(..., description="Perl specific test configuration") + + +class RTestElementInner(StrictBaseModel): + libraries: ConditionalList[NonEmptyStr] = Field( + ..., description="A list of R libraries to check after having installed the built package." + ) + + +class RTestElement(StrictBaseModel): + r: RTestElementInner = Field(..., description="R specific test configuration") + + class DownstreamTestElement(StrictBaseModel): downstream: MatchSpec = Field( ..., @@ -508,7 +528,14 @@ class PackageContentTest(StrictBaseModel): ) -TestElement = ScriptTestElement | PythonTestElement | DownstreamTestElement | PackageContentTest +TestElement = ( + ScriptTestElement + | PythonTestElement + | PerlTestElement + | RTestElement + | DownstreamTestElement + | PackageContentTest +) ######### # About # diff --git a/schema.json b/schema.json index fc18de8..3a481ed 100644 --- a/schema.json +++ b/schema.json @@ -1858,7 +1858,7 @@ "title": "IfStatement[Annotated[str, StringConstraints]]", "type": "object" }, - "IfStatement_Union_ScriptTestElement__PythonTestElement__DownstreamTestElement__PackageContentTest__": { + "IfStatement_Union_ScriptTestElement__PythonTestElement__PerlTestElement__RTestElement__DownstreamTestElement__PackageContentTest__": { "additionalProperties": false, "properties": { "if": { @@ -1873,6 +1873,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, @@ -1888,6 +1894,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, @@ -1909,6 +1921,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, @@ -1924,6 +1942,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, @@ -1946,7 +1970,7 @@ "if", "then" ], - "title": "IfStatement[Union[ScriptTestElement, PythonTestElement, DownstreamTestElement, PackageContentTest]]", + "title": "IfStatement[Union[ScriptTestElement, PythonTestElement, PerlTestElement, RTestElement, DownstreamTestElement, PackageContentTest]]", "type": "object" }, "IfStatement_Union_UrlSource__GitRev__GitTag__GitBranch__BaseGitSource__LocalSource__": { @@ -2430,6 +2454,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, @@ -2437,7 +2467,7 @@ "$ref": "#/$defs/PackageContentTest" }, { - "$ref": "#/$defs/IfStatement_Union_ScriptTestElement__PythonTestElement__DownstreamTestElement__PackageContentTest__" + "$ref": "#/$defs/IfStatement_Union_ScriptTestElement__PythonTestElement__PerlTestElement__RTestElement__DownstreamTestElement__PackageContentTest__" }, { "items": { @@ -2448,6 +2478,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, @@ -2455,7 +2491,7 @@ "$ref": "#/$defs/PackageContentTest" }, { - "$ref": "#/$defs/IfStatement_Union_ScriptTestElement__PythonTestElement__DownstreamTestElement__PackageContentTest__" + "$ref": "#/$defs/IfStatement_Union_ScriptTestElement__PythonTestElement__PerlTestElement__RTestElement__DownstreamTestElement__PackageContentTest__" } ] }, @@ -3045,6 +3081,61 @@ "title": "PackageContentTestInner", "type": "object" }, + "PerlTestElement": { + "additionalProperties": false, + "properties": { + "perl": { + "allOf": [ + { + "$ref": "#/$defs/PerlTestElementInner" + } + ], + "description": "Perl specific test configuration" + } + }, + "required": [ + "perl" + ], + "title": "PerlTestElement", + "type": "object" + }, + "PerlTestElementInner": { + "additionalProperties": false, + "properties": { + "uses": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "$ref": "#/$defs/IfStatement" + }, + { + "items": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "$ref": "#/$defs/IfStatement" + } + ] + }, + "type": "array" + } + ], + "description": "A list of Perl modules to check after having installed the built package.", + "title": "Uses" + } + }, + "required": [ + "uses" + ], + "title": "PerlTestElementInner", + "type": "object" + }, "PrefixDetection": { "additionalProperties": false, "properties": { @@ -3379,6 +3470,61 @@ "title": "PythonTestElementInner", "type": "object" }, + "RTestElement": { + "additionalProperties": false, + "properties": { + "r": { + "allOf": [ + { + "$ref": "#/$defs/RTestElementInner" + } + ], + "description": "R specific test configuration" + } + }, + "required": [ + "r" + ], + "title": "RTestElement", + "type": "object" + }, + "RTestElementInner": { + "additionalProperties": false, + "properties": { + "libraries": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "$ref": "#/$defs/IfStatement" + }, + { + "items": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "$ref": "#/$defs/IfStatement" + } + ] + }, + "type": "array" + } + ], + "description": "A list of R libraries to check after having installed the built package.", + "title": "Libraries" + } + }, + "required": [ + "libraries" + ], + "title": "RTestElementInner", + "type": "object" + }, "Requirements": { "additionalProperties": false, "properties": { @@ -3920,6 +4066,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, @@ -3938,6 +4090,12 @@ { "$ref": "#/$defs/PythonTestElement" }, + { + "$ref": "#/$defs/PerlTestElement" + }, + { + "$ref": "#/$defs/RTestElement" + }, { "$ref": "#/$defs/DownstreamTestElement" }, diff --git a/tests/test_recipy.py b/tests/test_recipy.py index 3c473d2..bc7f69d 100644 --- a/tests/test_recipy.py +++ b/tests/test_recipy.py @@ -90,3 +90,61 @@ def test_patches_invalid_conditional(): # This should raise a validation error with pytest.raises(PydanticValidationError): Recipe.validate_python(recipe_dict) + + +def test_perl_test_valid(): + """Test that recipes with a Perl test pass validation.""" + recipe_yaml = """ + package: + name: test + version: 1.0.0 + tests: + - perl: + uses: + - Call::Context + """ + recipe_dict = yaml.safe_load(recipe_yaml) + Recipe.validate_python(recipe_dict) + + +def test_perl_test_invalid_missing_uses(): + """Test that a Perl test without uses fails validation.""" + recipe_yaml = """ + package: + name: test + version: 1.0.0 + tests: + - perl: {} + """ + recipe_dict = yaml.safe_load(recipe_yaml) + with pytest.raises(PydanticValidationError): + Recipe.validate_python(recipe_dict) + + +def test_r_test_valid(): + """Test that recipes with an R test pass validation.""" + recipe_yaml = """ + package: + name: test + version: 1.0.0 + tests: + - r: + libraries: + - ggplot2 + """ + recipe_dict = yaml.safe_load(recipe_yaml) + Recipe.validate_python(recipe_dict) + + +def test_r_test_invalid_missing_libraries(): + """Test that an R test without libraries fails validation.""" + recipe_yaml = """ + package: + name: test + version: 1.0.0 + tests: + - r: {} + """ + recipe_dict = yaml.safe_load(recipe_yaml) + with pytest.raises(PydanticValidationError): + Recipe.validate_python(recipe_dict)