codeforces

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: May 4, 2023 License: MIT Imports: 8 Imported by: 0

README

A package to ease testing of codeforces or any other online judge problems. It allows you to run test on your code using test data located in files, where files with names like 01 contains test input and 01.a contains test output.

Installation

go get github.com/zenwarr/codeforces

Usage

If your solution lives in main.go, you test data files should be located in directory testdata.

main.go should have the following structure:

// this function contains your solution
func solve(in *bufio.Reader, out *bufio.Writer) {
	// your solution code here
}

// this function is going to be called in real codeforces environment
func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	solve(in, out)
}

Now create main_test.go file and write something like this:

package main

import (
    "testing"
    "github.com/zenwarr/codeforces"
)

func TestSolution(t *testing.T) {
	codeforces.New(t, solve).Test()
}

Then you can run tests using go test command. Make sure testdata directory is in current working directory, so it can be accessed by tests.

If running in IDEA, you can see test results and execution time in Run tab like this:

img.png

Test function is going to scan all files in testdata directory and run a test for your solution on each test case. In each test, the entire output of your solve function is going to be compared with a corresponding .a file contents.

Run a single test

You can run a single test case by specifying its file name in TestFile function:

func TestSolution(t *testing.T) {
    codeforces.New(t, solve).TestFile("01") // run only "01" test case
}

Custom line comparator

Some test cases contain only one variant of the correct answer, but the judge is going to accept other variants as well.

For example, in a hypothetical problem you need to check some condition and output a number divisible by 2 if the condition is true and any odd number otherwise. In this case we need to check that all matching lines in your answer and .a file are either even or odd.

You can write something like this:

func TestSolution(t *testing.T) {
    codeforces.New(t, solve).WithLineComparator(func(expected, actual string) bool {
		// check both values are odd or even
		expectedNum, err := strconv.Atoi(expected)
		if err != nil {
		    return false
		}

		actualNum, err := strconv.Atoi(actual)
		if err != nil {
		    return false
		}
		
		return expectedNum%2 == actualNum%2
    }).Test()
}

Each line in your solution output is going to be checked against the corresponding line in .a file using this comparator, and the test is going to fail if the comparator returns false for any line.

The comparator does not know anything about internal structure of the output, so it is only usable for tests which can be compared line-by-line using the same condition.

Output normalization

Some tasks allow you to output answer lines in any order, so you need, for example, to sort them before comparing with .a file. This can be tricky, because sometimes output contains several groups of lines which should be sorted separately. In this case you can provide a custom output normalizer function that is called both on actual and expected output before comparing them.

func TestSolution(t *testing.T) {
    codeforces.New(t, solve).WithOutputNormalizer(func(output string) string {
		lines := strings.Split(output, "\n")
		// can be a more complex sorting algorithm with respect for groups of lines
		strings.Sort(lines)
		return strings.Join(lines, "\n")
    }).Test()
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Tester added in v1.1.0

type Tester struct {
	// contains filtered or unexported fields
}

func New added in v1.1.0

func New(t *testing.T, solver func(in *bufio.Reader, out *bufio.Writer)) *Tester

func (*Tester) Test added in v1.1.0

func (tester *Tester) Test()

func (*Tester) TestFile added in v1.1.0

func (tester *Tester) TestFile(file string)

func (*Tester) WithLineComparator added in v1.1.0

func (tester *Tester) WithLineComparator(lineComparator func(expected, actual string) bool) *Tester

func (*Tester) WithOutputNormalizer added in v1.1.0

func (tester *Tester) WithOutputNormalizer(outputNormalizer func(output string) string) *Tester

Jump to

Keyboard shortcuts

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