Back to Repositories

Validating Stack Data Structure Operations in williamfiset/Algorithms

This test suite provides comprehensive validation of Stack data structure implementations in Java, covering multiple stack variants including List-based, Array-based, and Integer-specific implementations. The suite ensures robust functionality through parameterized testing of core stack operations.

Test Coverage Overview

The test suite achieves thorough coverage of stack operations including:
  • Empty stack validation
  • Push and pop operations
  • Peek functionality
  • Size tracking
  • Empty state handling
Edge cases are carefully validated through dedicated tests for empty stack operations and exhaustive sequential operations testing.

Implementation Analysis

The testing approach utilizes JUnit 5’s parameterized testing capabilities to validate multiple stack implementations simultaneously. The @MethodSource annotation enables efficient test case generation, while the Truth assertion library provides fluent assertions for precise validation of stack behaviors.

Each test method focuses on a specific aspect of stack functionality, following a clear arrange-act-assert pattern.

Technical Details

Testing Framework: JUnit 5
Assertion Libraries: Google Truth
Test Patterns: Parameterized Tests
  • @ParameterizedTest annotation for multiple implementation testing
  • @MethodSource for test data generation
  • Exception testing using assertThrows

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Separation of concerns with focused test methods
  • Comprehensive edge case coverage
  • Reusable test data generation
  • Consistent assertion patterns
  • Clear test method naming conventions
The code organization promotes maintainability and readability through well-structured test cases and systematic validation approaches.

williamfiset/algorithms

src/test/java/com/williamfiset/algorithms/datastructures/stack/StackTest.java

            
package com.williamfiset.algorithms.datastructures.stack;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

public class StackTest {

  private static List<Stack<Integer>> inputs() {
    List<Stack<Integer>> stacks = new ArrayList<>();
    stacks.add(new ListStack<Integer>());
    stacks.add(new ArrayStack<Integer>());
    stacks.add(new IntStack(2));
    return stacks;
  }

  @ParameterizedTest
  @MethodSource("inputs")
  public void testEmptyStack(Stack<Integer> stack) {
    assertThat(stack.isEmpty()).isTrue();
    assertThat(stack.size()).isEqualTo(0);
  }

  @ParameterizedTest
  @MethodSource("inputs")
  public void testPopOnEmpty(Stack<Integer> stack) {
    assertThrows(Exception.class, () -> stack.pop());
  }

  @ParameterizedTest
  @MethodSource("inputs")
  public void testPeekOnEmpty(Stack<Integer> stack) {
    assertThrows(Exception.class, () -> stack.peek());
  }

  @ParameterizedTest
  @MethodSource("inputs")
  public void testPush(Stack<Integer> stack) {
    stack.push(2);
    assertThat(stack.size()).isEqualTo(1);
  }

  @ParameterizedTest
  @MethodSource("inputs")
  public void testPeek(Stack<Integer> stack) {
    stack.push(2);
    assertThat((int) (Integer) stack.peek()).isEqualTo(2);
    assertThat(stack.size()).isEqualTo(1);
  }

  @ParameterizedTest
  @MethodSource("inputs")
  public void testPop(Stack<Integer> stack) {
    stack.push(2);
    assertThat((int) stack.pop()).isEqualTo(2);
    assertThat(stack.size()).isEqualTo(0);
  }

  @ParameterizedTest
  @MethodSource("inputs")
  public void testExhaustively(Stack<Integer> stack) {
    assertThat(stack.isEmpty()).isTrue();
    stack.push(1);
    assertThat(stack.isEmpty()).isFalse();
    stack.push(2);
    assertThat(stack.size()).isEqualTo(2);
    assertThat((int) stack.peek()).isEqualTo(2);
    assertThat(stack.size()).isEqualTo(2);
    assertThat((int) stack.pop()).isEqualTo(2);
    assertThat(stack.size()).isEqualTo(1);
    assertThat((int) stack.peek()).isEqualTo(1);
    assertThat(stack.size()).isEqualTo(1);
    assertThat((int) stack.pop()).isEqualTo(1);
    assertThat(stack.size()).isEqualTo(0);
    assertThat(stack.isEmpty()).isTrue();
  }
}