11import csv
22import os
33import re
4+ from django .conf import settings
45from django .test import TestCase
56from pokemon_v2 .models import *
67
@@ -27,69 +28,61 @@ class CSVResourceNameValidationTestCase(TestCase):
2728 # Pattern for valid resource identifiers: lowercase letters, numbers, and hyphens only
2829 VALID_IDENTIFIER_PATTERN = re .compile (r"^[a-z0-9-]+$" )
2930
30- # CSV files that contain an 'identifier' column to validate
31- # Format: (filename, identifier_column_name)
31+ # CSV files with 'identifier' column to validate
3232 CSV_FILES_TO_VALIDATE = [
33- ( "abilities.csv" , "identifier" ) ,
34- ( "berry_firmness.csv" , "identifier" ) ,
35- ( "conquest_episodes.csv" , "identifier" ) ,
36- ( "conquest_kingdoms.csv" , "identifier" ) ,
37- ( "conquest_move_displacements.csv" , "identifier" ) ,
38- ( "conquest_move_ranges.csv" , "identifier" ) ,
39- ( "conquest_stats.csv" , "identifier" ) ,
40- ( "conquest_warrior_archetypes.csv" , "identifier" ) ,
41- ( "conquest_warrior_skills.csv" , "identifier" ) ,
42- ( "conquest_warrior_stats.csv" , "identifier" ) ,
43- ( "conquest_warriors.csv" , "identifier" ) ,
44- ( "contest_types.csv" , "identifier" ) ,
45- ( "egg_groups.csv" , "identifier" ) ,
46- ( "encounter_conditions.csv" , "identifier" ) ,
47- ( "encounter_condition_values.csv" , "identifier" ) ,
48- ( "encounter_methods.csv" , "identifier" ) ,
49- ( "evolution_triggers.csv" , "identifier" ) ,
50- ( "genders.csv" , "identifier" ) ,
51- ( "generations.csv" , "identifier" ) ,
52- ( "growth_rates.csv" , "identifier" ) ,
53- ( "items.csv" , "identifier" ) ,
54- ( "item_categories.csv" , "identifier" ) ,
55- ( "item_flags.csv" , "identifier" ) ,
56- ( "item_fling_effects.csv" , "identifier" ) ,
57- ( "item_pockets.csv" , "identifier" ) ,
58- ( "languages.csv" , "identifier" ) ,
59- ( "locations.csv" , "identifier" ) ,
60- ( "location_areas.csv" , "identifier" ) ,
61- ( "moves.csv" , "identifier" ) ,
62- ( "move_battle_styles.csv" , "identifier" ) ,
63- ( "move_damage_classes.csv" , "identifier" ) ,
64- ( "move_flags.csv" , "identifier" ) ,
65- ( "move_meta_ailments.csv" , "identifier" ) ,
66- ( "move_meta_categories.csv" , "identifier" ) ,
67- ( "move_targets.csv" , "identifier" ) ,
68- ( "natures.csv" , "identifier" ) ,
69- ( "pal_park_areas.csv" , "identifier" ) ,
70- ( "pokeathlon_stats.csv" , "identifier" ) ,
71- ( "pokedexes.csv" , "identifier" ) ,
72- ( "pokemon.csv" , "identifier" ) ,
73- ( "pokemon_colors.csv" , "identifier" ) ,
74- ( "pokemon_forms.csv" , "identifier" ) ,
75- ( "pokemon_habitats.csv" , "identifier" ) ,
76- ( "pokemon_move_methods.csv" , "identifier" ) ,
77- ( "pokemon_shapes.csv" , "identifier" ) ,
78- ( "pokemon_species.csv" , "identifier" ) ,
79- ( "regions.csv" , "identifier" ) ,
80- ( "stats.csv" , "identifier" ) ,
81- ( "types.csv" , "identifier" ) ,
82- ( "versions.csv" , "identifier" ) ,
83- ( "version_groups.csv" , "identifier" ) ,
33+ "abilities.csv" ,
34+ "berry_firmness.csv" ,
35+ "conquest_episodes.csv" ,
36+ "conquest_kingdoms.csv" ,
37+ "conquest_move_displacements.csv" ,
38+ "conquest_move_ranges.csv" ,
39+ "conquest_stats.csv" ,
40+ "conquest_warrior_archetypes.csv" ,
41+ "conquest_warrior_skills.csv" ,
42+ "conquest_warrior_stats.csv" ,
43+ "conquest_warriors.csv" ,
44+ "contest_types.csv" ,
45+ "egg_groups.csv" ,
46+ "encounter_conditions.csv" ,
47+ "encounter_condition_values.csv" ,
48+ "encounter_methods.csv" ,
49+ "evolution_triggers.csv" ,
50+ "genders.csv" ,
51+ "generations.csv" ,
52+ "growth_rates.csv" ,
53+ "items.csv" ,
54+ "item_categories.csv" ,
55+ "item_flags.csv" ,
56+ "item_fling_effects.csv" ,
57+ "item_pockets.csv" ,
58+ "languages.csv" ,
59+ "locations.csv" ,
60+ "location_areas.csv" ,
61+ "moves.csv" ,
62+ "move_battle_styles.csv" ,
63+ "move_damage_classes.csv" ,
64+ "move_flags.csv" ,
65+ "move_meta_ailments.csv" ,
66+ "move_meta_categories.csv" ,
67+ "move_targets.csv" ,
68+ "natures.csv" ,
69+ "pal_park_areas.csv" ,
70+ "pokeathlon_stats.csv" ,
71+ "pokedexes.csv" ,
72+ "pokemon.csv" ,
73+ "pokemon_colors.csv" ,
74+ "pokemon_forms.csv" ,
75+ "pokemon_habitats.csv" ,
76+ "pokemon_move_methods.csv" ,
77+ "pokemon_shapes.csv" ,
78+ "pokemon_species.csv" ,
79+ "regions.csv" ,
80+ "stats.csv" ,
81+ "types.csv" ,
82+ "versions.csv" ,
83+ "version_groups.csv" ,
8484 ]
8585
86- def get_csv_path (self , filename ):
87- """Get the absolute path to a CSV file in data/v2/csv/"""
88- from django .conf import settings
89-
90- base_dir = settings .BASE_DIR
91- return os .path .join (base_dir , "data" , "v2" , "csv" , filename )
92-
9386 def test_all_csv_identifiers_are_ascii_slugs (self ):
9487 """
9588 Validate that all resource identifiers in CSV files follow the ASCII slug format.
@@ -108,8 +101,8 @@ def test_all_csv_identifiers_are_ascii_slugs(self):
108101 violations = []
109102 missing_files = []
110103
111- for filename , identifier_column in self .CSV_FILES_TO_VALIDATE :
112- csv_path = self . get_csv_path ( filename )
104+ for filename in self .CSV_FILES_TO_VALIDATE :
105+ csv_path = os . path . join ( settings . BASE_DIR , "data" , "v2" , "csv" , filename )
113106
114107 # Track missing files to report at the end
115108 if not os .path .exists (csv_path ):
@@ -121,21 +114,19 @@ def test_all_csv_identifiers_are_ascii_slugs(self):
121114 reader = csv .DictReader (csvfile )
122115
123116 # Check if the identifier column exists
124- if identifier_column not in reader .fieldnames :
117+ if "identifier" not in reader .fieldnames :
125118 violations .append (
126119 {
127120 "file" : filename ,
128121 "row" : "N/A" ,
129122 "id" : "N/A" ,
130- "identifier" : f "Column '{ identifier_column } ' not found" ,
123+ "identifier" : "Column 'identifier ' not found" ,
131124 }
132125 )
133126 continue
134127
135- for row_num , row in enumerate (
136- reader , start = 2
137- ): # Start at 2 (after header)
138- identifier = row .get (identifier_column , "" ).strip ()
128+ for row_num , row in enumerate (reader , start = 2 ):
129+ identifier = row .get ("identifier" , "" ).strip ()
139130
140131 # Skip empty identifiers
141132 if not identifier :
0 commit comments