Skip to content

Commit

Permalink
test: coverage for non-generated code (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
ParanoidUser authored Aug 6, 2024
1 parent 5a2b3de commit a7f5267
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/auto-merge-dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
steps:
- name: Fetch Dependabot metadata
id: dependabot-metadata
uses: dependabot/fetch-metadata@dbb049abf0d677abbd7f7eee0375145b417fdd34
uses: dependabot/fetch-metadata@dbb049abf0d677abbd7f7eee0375145b417fdd34 # v2.2.0
- name: Enable auto-merge for minor updates
if: ${{ steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major' }}
env:
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ jobs:
timeout-minutes: 1
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup Java
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
distribution: temurin
java-version: 17
Expand All @@ -40,15 +40,15 @@ jobs:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup Java
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
distribution: temurin
java-version: 17
cache: maven
- name: Initialize CodeQL
uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a
uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
with:
languages: java
queries: security-and-quality
Expand All @@ -57,4 +57,4 @@ jobs:
- name: Compile project
run: ./mvnw compile
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a
uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ jobs:
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup Java
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
distribution: temurin
java-version: 17
Expand Down
5 changes: 5 additions & 0 deletions codewars-sdk-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import dev.noid.codewars.client.model.CompletedChallenges;
import dev.noid.codewars.client.model.User;
import java.util.List;
import java.util.function.IntFunction;
import java.util.Map;

public final class CodewarsClient {

Expand Down Expand Up @@ -41,9 +41,11 @@ public List<AuthoredChallenge> listAuthoredChallenges(String idOrUsername) throw

public List<CompletedChallenge> listCompletedChallenges(String idOrUsername) throws ApiException {
CompletedChallenges firstPage = usersApi.listCompletedChallenges(idOrUsername, 0);
List<CompletedChallenge> recentChallenges = firstPage.getData();
IntFunction<List<CompletedChallenge>> pageLoader = page -> usersApi.listCompletedChallenges(idOrUsername, page).getData();
return new LazyList<>(pageLoader, recentChallenges, recentChallenges.size(), firstPage.getTotalItems());
return new PaginatedList<>(
page -> usersApi.listCompletedChallenges(idOrUsername, page).getData(),
firstPage.getTotalPages(),
firstPage.getTotalItems(),
Map.of(0, firstPage.getData()));
}

public CodeChallenge getCodeChallenge(String idOrSlag) throws ApiException {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package dev.noid.codewars.client;

import java.util.AbstractList;
import java.util.List;
import java.util.Map;
import java.util.function.IntFunction;

class PaginatedList<E> extends AbstractList<E> {

private final IntFunction<List<E>> pageLoader;
private final List<E>[] cache;
private final int totalItems;
private final int pageSize;

PaginatedList(IntFunction<List<E>> pageLoader, int totalPages, int totalItems, Map<Integer, List<E>> preloaded) {
this.pageLoader = pageLoader;
this.cache = new List[totalPages];
preloaded.forEach((pageNumber, page) -> cache[pageNumber] = page);
this.totalItems = totalItems;
this.pageSize = (int) Math.ceil((double) totalItems / totalPages);
}

@Override
public E get(int i) {
if (i < 0 || i >= size()) {
throw new IndexOutOfBoundsException();
}

int pageNumber = Math.floorDiv(i, pageSize);
List<E> page = cache[pageNumber];
if (page == null) {
page = pageLoader.apply(pageNumber);
cache[pageNumber] = page;
}
return page.get(i % pageSize);
}

@Override
public int size() {
return totalItems;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package dev.noid.codewars.client;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;

import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

class PaginatedListTest {

private final List<List<String>> remotePages = Mockito.spy(List.of(
List.of("a", "b", "c", "d", "e"),
List.of("f", "g", "h", "i", "j"),
List.of("k", "l", "m", "n", "o"),
List.of("p", "q", "r", "s", "t"),
List.of("u", "v", "w", "x", "y"),
List.of("z")
));

@Test
void load_all_remote_pages() {
assertEquals(List.of(
"a", "b", "c", "d", "e",
"f", "g", "h", "i", "j",
"k", "l", "m", "n", "o",
"p", "q", "r", "s", "t",
"u", "v", "w", "x", "y",
"z"
), getList(6, 26, Map.of()));

Mockito.verify(remotePages, Mockito.times(remotePages.size())).get(anyInt());
for (int page = 0; page < remotePages.size(); page++) {
Mockito.verify(remotePages, Mockito.times(1)).get(page);
}
}

@Test
void preload_first_page() {
assertEquals(List.of(
"1", "2", "3", "4", "5",
"f", "g", "h", "i", "j",
"k", "l", "m", "n", "o",
"p", "q", "r", "s", "t",
"u", "v", "w", "x", "y",
"z"
), getList(6, 26, Map.of(0, List.of("1", "2", "3", "4", "5"))));

Mockito.verify(remotePages, Mockito.times(remotePages.size() - 1)).get(anyInt());
for (int page = 1; page < remotePages.size(); page++) {
Mockito.verify(remotePages, Mockito.times(1)).get(page);
}
}

@Test
void preload_last_page() {
assertEquals(List.of(
"a", "b", "c", "d", "e",
"f", "g", "h", "i", "j",
"k", "l", "m", "n", "o",
"p", "q", "r", "s", "t",
"u", "v", "w", "x", "y",
"1"
), getList(6, 26, Map.of(5, List.of("1", "2", "3", "4", "5"))));

Mockito.verify(remotePages, Mockito.times(remotePages.size() - 1)).get(anyInt());
for (int page = 0; page < remotePages.size() - 1; page++) {
Mockito.verify(remotePages, Mockito.times(1)).get(page);
}
}

@Test
void load_no_remote_pages() {
Map<Integer, List<String>> preloaded = Map.of(
0, List.of("1", "2", "3", "4", "5"),
1, List.of("6", "7", "8", "9", "0"),
2, List.of("~", "!", "@", "#", "$"),
3, List.of("%", "^", "&", "*", "("),
4, List.of(")", "_", "+", "`", "-"),
5, List.of("=")
);

assertEquals(List.of(
"1", "2", "3", "4", "5",
"6", "7", "8", "9", "0",
"~", "!", "@", "#", "$",
"%", "^", "&", "*", "(",
")", "_", "+", "`", "-",
"="
), getList(6, 26, preloaded));

Mockito.verify(remotePages, Mockito.times(0)).get(anyInt());
}

@Test
void limit_pages_access() {
assertEquals(List.of(
"a", "b", "c", "d", "e",
"f", "g", "h", "i", "j",
"k", "l", "m"
), getList(3, 13, Map.of()));

Mockito.verify(remotePages, Mockito.times(3)).get(anyInt());
Mockito.verify(remotePages, Mockito.times(1)).get(0);
Mockito.verify(remotePages, Mockito.times(1)).get(1);
Mockito.verify(remotePages, Mockito.times(1)).get(2);
}

@Test
void read_from_empty() {
List<String> list = getList(0, 0, Map.of());
assertTrue(list.isEmpty());
assertEquals(List.of(), list);
}

@Test
void constant_size() {
List<String> list = getList(6, 26, Map.of());
assertEquals(26, list.size());
for (String ignored : list) {
assertEquals(26, list.size());
}
assertEquals(26, list.size());
}

@Test
void immutability() {
List<String> list = getList(1, 1, Map.of());
assertThrows(UnsupportedOperationException.class, () -> list.add(0, "!"));
assertThrows(UnsupportedOperationException.class, () -> list.set(0, "!"));
assertThrows(UnsupportedOperationException.class, () -> list.remove(0));
assertThrows(UnsupportedOperationException.class, () -> list.remove("a"));
}

private List<String> getList(int totalPages, int totalItems, Map<Integer, List<String>> preloaded) {
return new PaginatedList<>(remotePages::get, totalPages, totalItems, preloaded);
}
}
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<jsr305.version>3.0.2</jsr305.version>
<swagger.version>1.6.14</swagger.version>
<junit.version>5.10.3</junit.version>
<mockito.version>5.12.0</mockito.version>
</properties>

<dependencyManagement>
Expand All @@ -63,6 +64,15 @@
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-bom</artifactId>
<version>${mockito.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Expand Down

0 comments on commit a7f5267

Please sign in to comment.