...

/

Solution 2: Code Testing and Profiling

Solution 2: Code Testing and Profiling

Let’s solve the challenge set in the previous lesson.

We'll cover the following...

Solution

Here is the code for the test functions:

package main

import (
	"os"
	"testing"
	"strings"
)

func TestReadCSVFile(t *testing.T) {
	// Create a temporary test CSV file
	tmpFile := "/tmp/test.csv"
	f, err := os.Create(tmpFile)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	// Write test data to the temporary file
	testData := "John,Doe,1234567890,123456789\nJane,Smith,9876543210,987654321\n"
	_, err = f.WriteString(testData)
	if err != nil {
		t.Fatal(err)
	}

	// Call readCSVFile to read the temporary file
	err = readCSVFile(tmpFile)
	if err != nil {
		t.Fatal(err)
	}

	// Check if data is loaded correctly
	if len(data) != 2 {
		t.Fatalf("Expected 2 entries, got %d", len(data))
	}

	// Clean up the temporary file
	err = os.Remove(tmpFile)
	if err != nil {
		t.Fatal(err)
	}
}

// A setup function to clear data before tests
func setup() {
    data = []Entry{}
    index = make(map[string]int)
}

func TestInsert(t *testing.T) {
    // Set up the test environment
    setup()
	// Initialize test data
	testEntry := initS("Test", "User", "5551234567")
	if testEntry == nil {
		t.Fatal("Failed to initialize test entry")
	}

	// Call insert to insert the test entry
	err := insert(testEntry)
	if err != nil {
		t.Fatal(err)
	}

	// Check if the test entry was inserted
	if len(data) != 1 {
		t.Fatalf("Expected 1 entry after insert, got %d", len(data))
	}

	// Clean up by deleting the test entry
	err = deleteEntry("5551234567")
	if err != nil {
		t.Fatal(err)
	}
}

func TestDeleteEntry(t *testing.T) {
	// Initialize test data
	testEntry := initS("Test", "User", "5551234567")
	if testEntry == nil {
		t.Fatal("Failed to initialize test entry")
	}

	// Insert the test entry
	err := insert(testEntry)
	if err != nil {
		t.Fatal(err)
	}

	// Call deleteEntry to delete the test entry
	err = deleteEntry("5551234567")
	if err != nil {
		t.Fatal(err)
	}

	// Check if the test entry was deleted
	if len(data) != 0 {
		t.Fatalf("Expected 0 entries after delete, got %d", len(data))
	}
}

func TestSearch(t *testing.T) {
	// Initialize test data
	testEntry := initS("Test", "User", "5551234567")
	if testEntry == nil {
		t.Fatal("Failed to initialize test entry")
	}

	// Insert the test entry
	err := insert(testEntry)
	if err != nil {
		t.Fatal(err)
	}

	// Call search to find the test entry
	result := search("5551234567")
	if result == nil {
		t.Fatal("Failed to find test entry")
	}

	// Clean up by deleting the test entry
	err = deleteEntry("5551234567")
	if err != nil {
		t.Fatal(err)
	}
}

func TestList(t *testing.T) {
	// Set up test data
	setup()
	testData := []Entry{
		{Name: "John", Surname: "Doe", Tel: "1234567890", LastAccess: "123456789"},
		{Name: "Jane", Surname: "Smith", Tel: "9876543210", LastAccess: "987654321"},
	}
	data = append(data, testData...)

	// Redirect standard output to capture printed output
	oldStdout := os.Stdout
	r, w, _ := os.Pipe()
	os.Stdout = w

	// Call the list function
	list()

	// Close the pipe and restore stdout
	w.Close()
	os.Stdout = oldStdout

	// Read the captured output from the pipe
	outputBytes := make([]byte, 4096)
	n, _ := r.Read(outputBytes)

	// Convert the captured output to a string and split it into lines
	output := string(outputBytes[:n])
	lines := strings.Split(output, "\n")

	// Check if the number of lines matches the number of entries in the test data
	if len(lines)-1 != len(testData) { // Subtract 1 to account for the final newline
		t.Fatalf("Expected %d lines in output, got %d", len(testData), len(lines)-1)
	}
}

func TestMatchTel(t *testing.T) {
	// Test cases for matchTel
	testCases := []struct {
		input    string
		expected bool
	}{
		{"1234567890", true},   // Valid telephone number
		{"9876543210", true},   // Valid telephone number
		{"abcd", false},         // Non-digit characters
		{"", false},             // Empty string
	}

	// Run test cases
	for _, tc := range testCases {
		result := matchTel(tc.input)
		if result != tc.expected {
			t.Errorf("For input %s, expected %v, but got %v", tc.input, tc.expected, result)
		}
	}
}
phoneBook.go and phoneBook_test.go

Code explanation

Let’s look at the code explanation for phoneBook_test.go.

  • Lines 8–40: The TestReadCSVFile function tests the readCSVFile function from phoneBook.go. It starts by creating a temporary test CSV file (tmpFile) and writing some test data to it. It then calls the readCSVFile ...