gocore

module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2025 License: Apache-2.0

README

Gocore

A foundational Go library (i.e. no main()) containing low level universal cross-platform reusable building blocks, and utilities for all abtransitionit GO projects.


Dev CI Main CI LICENSE


Features

This project template includes the following components:

Component Description
Licensing Predefined open-source license (Apache 2.0) for legal compliance.
Code of Conduct Ensures a welcoming and inclusive environment for all contributors.
README Structured documentation template for clear project onboarding.

This repository contains core packages designed to be used across all of our services, such as:

  • errorx: A package for structured error handling.
  • logx: A package for consistent logging.
  • filex: Utilities for common file system operations.

Getting started

To use this module (library) in your project, run:

Contributing

We welcome contributions! Before participating, please review:

Contributing as developer

updating the go/mod

During local development, we use the replace directive in go.mod to simplify dependency management when working with multiple interdependent Go projects.

For promotion to production:

  • The go.mod file is committed as-is into all branches: feature and dev branches.
  • When code reaches the main (or any production) branch, the CI pipeline automatically removes all replace directives before building and/or generating the release artifacts.

This approach ensures that:

  • Developers benefit from faster iteration and easier local linking during development.
  • Production releases builds always rely on published module versions, ensuring stability and reproducibility.

Updating an interface

  1. Modify the Interface Definition:
    • define and/or update the method signature.
    • This change will immediately break the build for all code that uses a type that implements this interface.
  2. Identify Implementing Types:
    • launch a go vet or go build
    • failures allows to identify code to update
  3. Update the Implementing Types:
    • For each of the types you identified
    • add/update the new method to match the updated interface signature
    • To get your code to compile quickly: providing a method stubs
      • that have the correct signature but contain minimal logic.
      • this allows you to restore a working build and then implement the full functionality later.

Here’s a polished, professional, and production-ready version of your text with consistent tone, grammar, and clarity:

Testing Code

As the Go community, we follow a white-box testing approach, which allows us to test not only public but also private functions. This is achieved by:

  • Keeping test files alongside the source code, ensuring maintainability and readability.
  • Promoting a strong unit testing culture, where tests are considered a first-class part of the codebase.
Go Test Files

A Go test file:

  • Is any file within a package whose name ends with _test.go.
  • Is executed when running the command:
go test ./...
Go Test Functions

A Go test function:

  • Must start with the prefix Test.
  • Must take a single parameter of type *testing.T.

Example:

func TestExample(t *testing.T) {
    // test logic here
}
table-driven testing approach

We also adopt a table-driven testing approach, which makes tests more scalable, consistent, and easier to extend.

Example01

package mathutils

import "testing"

// Function under test
func Add(a, b int) int {
    return a + b
}

// Table-driven test
func TestAdd(t *testing.T) {
    // Define test cases
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"with a negative number", -1, 4, 3},
        {"both negative numbers", -2, -3, -5},
    }

    // Run test cases
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
            }
        })
    }
}

Example02

func TestHelloHandler(t *testing.T) {
    tests := []struct {
        name       string
        url        string
        wantStatus int
        wantBody   string
    }{
        {"valid request", "/hello?name=Go", 200, "Hello, Go!"},
        {"missing name", "/hello", 400, "missing name"},
        {"not found", "/invalid", 404, "404 page not found"},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            req := httptest.NewRequest("GET", tt.url, nil)
            w := httptest.NewRecorder()

            router().ServeHTTP(w, req)

            if w.Code != tt.wantStatus {
                t.Errorf("status = %d; want %d", w.Code, tt.wantStatus)
            }
            if !strings.Contains(w.Body.String(), tt.wantBody) {
                t.Errorf("body = %q; want %q", w.Body.String(), tt.wantBody)
            }
        })
    }
}
What is a Test?

At its core, a test consists of three steps:

  1. Arrange – provide known inputs and define the expected outcome.
  2. Act – execute the function or code under test with the known inputs.
  3. Assert – compare the obtained result with the expected result.

A test can:

  • pass: if the obtained result and expected result match.
  • fail: if they don’t, signaling a potential bug or unexpected behavior.

Depending on the context, the “obtained result” of a test might be:

  • A return value (e.g., Add(2,3) should return 5).
  • An error (e.g., dividing by zero should return an error).
  • A side effect (e.g., a file is created, a log message is written).
  • A performance constraint (e.g., execution must complete under 100 ms).
  • A system state (e.g., a flag is set, a resource is locked).
  • A performance metric (e.g., memory usage or throughput).

Commiting

Git commit messages, follows a conventional Commits style:

Prefix Description Example
chore: Maintenance or tooling work, no behavior change chore: update CI workflow
feat: Adds a new feature feat: add user login functionality
fix: Bug fix fix: correct typo in API response
docs: Documentation changes docs: update README with setup instructions
refactor: Code changes that don’t add features or fix bugs refactor: simplify helper functions
test: Adding or updating tests test: add unit tests for file parser

TODO: Local Development vs. Shared Development environment


Release History & Changelog

Track version updates and changes:

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL