+311
-15
cmd/validate-lexicon/main.go
+311
-15
cmd/validate-lexicon/main.go
···-schemaPath = flag.String("path", "internal/atproto/lexicon", "Path to lexicon schemas directory")+schemaPath = flag.String("path", "internal/atproto/lexicon", "Path to lexicon schemas directory")+testDataPath = flag.String("test-data", "tests/lexicon-test-data", "Path to test data directory for ValidateRecord testing")+schemasOnly = flag.Bool("schemas-only", false, "Only validate schemas, skip test data validation")···+if err := validateTestData(&catalog, *testDataPath, *verbose, *strict, allSchemas); err != nil {func validateSchemaStructure(catalog *lexicon.BaseCatalog, schemaPath string, verbose bool) error {+// e.g., internal/atproto/lexicon/social/coves/actor/profile.json -> social.coves.actor.profile···-validationErrors = append(validationErrors, fmt.Sprintf("Failed to resolve schema %s: %v", schemaID, err))+validationErrors = append(validationErrors, fmt.Sprintf("Failed to resolve schema %s (from %s): %v", schemaID, schemaFiles[i], err))·········+func validateTestData(catalog *lexicon.BaseCatalog, testDataPath string, verbose bool, strict bool, allSchemas []string) error {+validationErrors = append(validationErrors, fmt.Sprintf("Failed to parse JSON in %s: %v", path, err))+validationErrors = append(validationErrors, fmt.Sprintf("Missing or invalid $type field in %s", path))+validationErrors = append(validationErrors, fmt.Sprintf("Invalid test file %s passed validation when it should have failed", path))+validationErrors = append(validationErrors, fmt.Sprintf("Validation failed for %s (type: %s): %v", path, recordType, err))
+110
internal/validation/lexicon.go
+110
internal/validation/lexicon.go
···+func (v *LexiconValidator) ValidateModerationAction(action map[string]interface{}, actionType string) error {
+135
internal/validation/lexicon_test.go
+135
internal/validation/lexicon_test.go
···
-16
scripts/validate-schemas.sh
-16
scripts/validate-schemas.sh
···
+63
tests/lexicon-test-data/README.md
+63
tests/lexicon-test-data/README.md
···+Test files follow a specific naming pattern to distinguish between valid and invalid test cases:
+4
tests/lexicon-test-data/actor/profile-invalid-missing-handle.json
+4
tests/lexicon-test-data/actor/profile-invalid-missing-handle.json
+7
tests/lexicon-test-data/actor/profile-valid.json
+7
tests/lexicon-test-data/actor/profile-valid.json
+10
tests/lexicon-test-data/community/profile-valid.json
+10
tests/lexicon-test-data/community/profile-valid.json
···
+5
tests/lexicon-test-data/interaction/vote-valid.json
+5
tests/lexicon-test-data/interaction/vote-valid.json
+9
tests/lexicon-test-data/moderation/ban-valid.json
+9
tests/lexicon-test-data/moderation/ban-valid.json
···
+11
tests/lexicon-test-data/post/post-invalid-enum-type.json
+11
tests/lexicon-test-data/post/post-invalid-enum-type.json
···
+24
tests/lexicon-test-data/post/post-valid-text.json
+24
tests/lexicon-test-data/post/post-valid-text.json
···+"text": "I've been working with Go for a while now and wanted to share some thoughts on error handling patterns...",
+141
tests/lexicon_validation_test.go
+141
tests/lexicon_validation_test.go
······+err := lexicon.ValidateRecord(&catalog, tt.recordData, tt.recordType, lexicon.AllowLenientDatetime)+err := lexicon.ValidateRecord(&catalog, recordData, "social.coves.actor.profile", lexicon.StrictRecursiveValidation)+err = lexicon.ValidateRecord(&catalog, recordData, "social.coves.actor.profile", lexicon.AllowLenientDatetime)