mirror of
https://github.com/kjanat/articulate-parser.git
synced 2026-10-13 01:35:27 +02:00
refactor: comprehensive code quality improvements
- Add logger to all exporters for consistent error handling - Add Course.Validate() method with ValidationError type - Create shared test fixtures in internal/testdata - Refactor config passing: NewArticulateParser now takes *config.Config - Add NewLoggerFromConfig() factory for logger creation - Add context cancellation with signal handling (SIGINT/SIGTERM) - Add godoc examples for loggers and exporters - Add HTML exporter error path tests - Add fuzz tests for parser and HTMLCleaner - Fix markdown output: trim whitespace, collapse blank lines - Remove test output files from repo
This commit is contained in:
@@ -5,7 +5,10 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/kjanat/articulate-parser/internal/config"
|
||||
"github.com/kjanat/articulate-parser/internal/services"
|
||||
)
|
||||
|
||||
@@ -14,8 +17,8 @@ func ExampleNewArticulateParser() {
|
||||
// Create a no-op logger for this example
|
||||
logger := services.NewNoOpLogger()
|
||||
|
||||
// Create parser with defaults
|
||||
parser := services.NewArticulateParser(logger, "", 0)
|
||||
// Create parser with defaults (nil config uses defaults)
|
||||
parser := services.NewArticulateParser(logger, nil)
|
||||
|
||||
fmt.Printf("Parser created: %T\n", parser)
|
||||
// Output: Parser created: *services.ArticulateParser
|
||||
@@ -26,11 +29,11 @@ func ExampleNewArticulateParser_custom() {
|
||||
logger := services.NewNoOpLogger()
|
||||
|
||||
// Create parser with custom base URL and timeout
|
||||
parser := services.NewArticulateParser(
|
||||
logger,
|
||||
"https://custom.articulate.com",
|
||||
60_000_000_000, // 60 seconds in nanoseconds
|
||||
)
|
||||
cfg := &config.Config{
|
||||
BaseURL: "https://custom.articulate.com",
|
||||
RequestTimeout: 60 * time.Second,
|
||||
}
|
||||
parser := services.NewArticulateParser(logger, cfg)
|
||||
|
||||
fmt.Printf("Parser configured: %T\n", parser)
|
||||
// Output: Parser configured: *services.ArticulateParser
|
||||
@@ -39,7 +42,7 @@ func ExampleNewArticulateParser_custom() {
|
||||
// ExampleArticulateParser_LoadCourseFromFile demonstrates loading a course from a file.
|
||||
func ExampleArticulateParser_LoadCourseFromFile() {
|
||||
logger := services.NewNoOpLogger()
|
||||
parser := services.NewArticulateParser(logger, "", 0)
|
||||
parser := services.NewArticulateParser(logger, nil)
|
||||
|
||||
// In a real scenario, you'd have an actual file
|
||||
// This example shows the API usage
|
||||
@@ -52,7 +55,7 @@ func ExampleArticulateParser_LoadCourseFromFile() {
|
||||
// ExampleArticulateParser_FetchCourse demonstrates fetching a course from a URI.
|
||||
func ExampleArticulateParser_FetchCourse() {
|
||||
logger := services.NewNoOpLogger()
|
||||
parser := services.NewArticulateParser(logger, "", 0)
|
||||
parser := services.NewArticulateParser(logger, nil)
|
||||
|
||||
// Create a context with timeout
|
||||
ctx := context.Background()
|
||||
@@ -64,6 +67,54 @@ func ExampleArticulateParser_FetchCourse() {
|
||||
}
|
||||
}
|
||||
|
||||
// ExampleNewSlogLogger demonstrates creating a JSON logger.
|
||||
func ExampleNewSlogLogger() {
|
||||
// Create a JSON structured logger at Info level
|
||||
// Output goes to stdout in JSON format
|
||||
logger := services.NewSlogLogger(slog.LevelInfo)
|
||||
|
||||
// Logger is ready to use - calls like logger.Info("msg") output JSON
|
||||
fmt.Printf("Logger type: %T\n", logger)
|
||||
// Output: Logger type: *services.SlogLogger
|
||||
}
|
||||
|
||||
// ExampleNewTextLogger demonstrates creating a human-readable text logger.
|
||||
func ExampleNewTextLogger() {
|
||||
// Create a text logger, more readable for development
|
||||
logger := services.NewTextLogger(slog.LevelDebug)
|
||||
|
||||
// Logger is ready - calls like logger.Debug("msg") output text
|
||||
fmt.Printf("Logger type: %T\n", logger)
|
||||
// Output: Logger type: *services.SlogLogger
|
||||
}
|
||||
|
||||
// ExampleNewNoOpLogger demonstrates creating a no-op logger for testing.
|
||||
func ExampleNewNoOpLogger() {
|
||||
logger := services.NewNoOpLogger()
|
||||
|
||||
// All log calls are silently discarded
|
||||
logger.Debug("this won't appear")
|
||||
logger.Info("neither will this")
|
||||
logger.Error("or this")
|
||||
|
||||
fmt.Println("Logging silently completed")
|
||||
// Output: Logging silently completed
|
||||
}
|
||||
|
||||
// ExampleSlogLogger_With demonstrates creating a child logger with context.
|
||||
func ExampleSlogLogger_With() {
|
||||
logger := services.NewNoOpLogger()
|
||||
|
||||
// Create a child logger with additional context
|
||||
requestLogger := logger.With("request_id", "abc123", "user", "john")
|
||||
|
||||
// All logs from requestLogger will include request_id and user
|
||||
requestLogger.Info("processing request")
|
||||
|
||||
fmt.Printf("Child logger type: %T\n", requestLogger)
|
||||
// Output: Child logger type: *services.NoOpLogger
|
||||
}
|
||||
|
||||
// ExampleHTMLCleaner demonstrates cleaning HTML content.
|
||||
func ExampleHTMLCleaner() {
|
||||
cleaner := services.NewHTMLCleaner()
|
||||
|
||||
Reference in New Issue
Block a user