Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go

on:
pull_request:
branches: [ "main" ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.24'

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
15 changes: 15 additions & 0 deletions examples/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
statix "github.com/devchris123/statix/pkg/statix"
)

func main() {
// Create a new server instance with the specified address
srv := statix.NewServer(":8080")

// Start the server
if err := srv.Start(); err != nil {
panic(err)
}
}
11 changes: 11 additions & 0 deletions examples/static/hello-world.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
22 changes: 0 additions & 22 deletions pkg/server/server.go

This file was deleted.

40 changes: 40 additions & 0 deletions pkg/statix/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Package server provides a simple HTTP server to serve static files.
package server

import (
"log"
"net/http"
"path/filepath"
)

const defaultStaticDir = "./static"

type server struct {
server http.Server
}

// NewServer creates a new server instance with the specified address.
func NewServer(addr string) *server {
handler := http.DefaultServeMux

handler.HandleFunc("/", staticFileHandler(defaultStaticDir))

return &server{server: http.Server{
Addr: addr,
Handler: handler,
}}
}

func staticFileHandler(dir string) http.HandlerFunc {
log.Printf("statix: Serving static files from %s", dir)
return func(w http.ResponseWriter, r *http.Request) {
log.Printf("statix: Received request for %s", r.URL.Path)
http.ServeFile(w, r, filepath.Join(dir, r.URL.Path))
}
}

// Start starts the HTTP server.
func (s *server) Start() error {
log.Printf("statix: Starting server on %s", s.server.Addr)
return s.server.ListenAndServe()
}
59 changes: 59 additions & 0 deletions pkg/statix/server_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package server

import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
)

// TestStaticFileHandler tests the staticFileHandler function.
// The test creates a dummy directory with dummy files and checks if the handler serves them correctly.
func TestIntegrationStaticFileHandler(t *testing.T) {
dummyFile0 := "testfile0.txt"
dummyFile1 := "testfile1.txt"
dummyFile0Content := "This is a test file."
dummyFile1Content := "This is another test file."
readPerm := os.FileMode(0644)

// Create a temporary directory for testing
staticDir, err := os.MkdirTemp(".", "static_")
if err != nil {
t.Fatalf("could not create temp dir: %v", err)
}
t.Cleanup(func() {
// Remove the temporary directory after the test
if err := os.RemoveAll(staticDir); err != nil {
t.Fatalf("could not remove temp dir: %v", err)
}
})
// Create a dummy file in the temporary directory
if err := os.WriteFile(filepath.Join(staticDir, dummyFile0), []byte(dummyFile0Content), readPerm); err != nil {
t.Fatalf("could not create dummy file: %v", err)
}
// Create another dummy file
if err := os.WriteFile(filepath.Join(staticDir, dummyFile1), []byte(dummyFile1Content), readPerm); err != nil {
t.Fatalf("could not create another dummy file: %v", err)
}

handler := staticFileHandler(staticDir)

if handler == nil {
t.Error("expected handler to be non-nil")
}

// Simulate a request to the handler
req, err := http.NewRequest("GET", dummyFile0, nil)
if err != nil {
t.Fatalf("could not create request: %v", err)
}
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("expected status OK, got %d", rr.Code)
}
if rr.Body.String() != dummyFile0Content {
t.Errorf("expected body %s, got %s", dummyFile0Content, rr.Body.String())
}
}
65 changes: 65 additions & 0 deletions pkg/statix/server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package server

import (
"net/http"
"net/http/httptest"
"testing"
)

// TestNewServer tests the NewServer function.
func TestNewServer(t *testing.T) {
addr := ":8080"
srv := NewServer(addr)

if srv.server.Addr != addr {
t.Errorf("expected server Addr %s, got %s", addr, srv.server.Addr)
}
}

// Test that request.URL.path is always the relative path
// regardless of whether the request is made with a full URL or a relative path.
func TestRequestPath(t *testing.T) {
path := "/testfile.txt"

// Test with a relative path
r, err := http.NewRequest("GET", path, nil)
if err != nil {
t.Fatalf("could not create request: %v", err)
}
if r.URL.Path != path {
t.Errorf("expected request URL path %s, got %s", path, r.URL.Path)
}

// Test with a full URL
r, err = http.NewRequest("GET", "http://example.com"+path, nil)
if err != nil {
t.Fatalf("could not create request: %v", err)
}
if r.URL.Path != path {
t.Errorf("expected request URL path %s, got %s", path, r.URL.Path)
}
}

// TestStaticFileHandler tests the staticFileHandler function.
func TestStaticFileHandler(t *testing.T) {
dir := "/static"
handler := staticFileHandler(dir)

if handler == nil {
t.Error("expected handler to be non-nil")
}

// Simulate a request to the handler
req, err := http.NewRequest("GET", dir+"/testfile.txt", nil)
if err != nil {
t.Fatalf("could not create request: %v", err)
}

// Create a ResponseRecorder to capture the response
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)

if rr.Code != http.StatusNotFound {
t.Errorf("expected status code 404, got %d", rr.Code)
}
}
Loading