
com.google.common.truth.SortedSetSubject Maven / Gradle / Ivy
/*
* Copyright (c) 2011 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.common.truth;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import com.google.common.collect.ForwardingSortedSet;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.SortedSet;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
/**
* Tests for {@link SortedSet} and {@link NavigableSet} objects. This class supports assertions
* based on {@code NavigableSet}'s API even if the subject only implements {@code SortedSet}.
*/
// TODO(diamondm): identify use-cases for assertions on other NavigableSet methods, such as
// ceiling(), and propose an API to support such assertions.
public final class SortedSetSubject extends IterableSubject {
private final NavigableSet> actualAsNavigableSet;
SortedSetSubject(FailureMetadata metadata, SortedSet> set) {
super(metadata, set);
actualAsNavigableSet = set == null ? null : SortedSetAsNavigableSet.wrapIfNecessary(set);
}
@Override
public SortedSetSubject named(String format, Object... args) {
super.named(format, args);
return this;
}
/** Fails if the subject does not have the given first element. */
public void hasFirstElement(@NullableDecl Object element) {
if (actualAsNavigableSet().isEmpty()) {
fail("has first element", element);
return;
}
if (!Objects.equal(actualAsNavigableSet().first(), element)) {
if (actualAsNavigableSet().contains(element)) {
failWithRawMessage(
"Not true that %s has first element <%s>. "
+ "It does contain this element, but the first element is <%s>",
actualAsString(), element, actualAsNavigableSet().first());
return;
}
failWithRawMessage(
"Not true that %s has first element <%s>. "
+ "It does not contain this element, and the first element is <%s>",
actualAsString(), element, actualAsNavigableSet().first());
}
}
/** Fails if the subject does not have the given last element. */
public void hasLastElement(@NullableDecl Object element) {
if (actualAsNavigableSet().isEmpty()) {
fail("has last element", element);
return;
}
if (!Objects.equal(actualAsNavigableSet().last(), element)) {
if (actualAsNavigableSet().contains(element)) {
failWithRawMessage(
"Not true that %s has last element <%s>. "
+ "It does contain this element, but the last element is <%s>",
actualAsString(), element, actualAsNavigableSet().last());
return;
}
failWithRawMessage(
"Not true that %s has last element <%s>. "
+ "It does not contain this element, and the last element is <%s>",
actualAsString(), element, actualAsNavigableSet().last());
}
}
/**
* Provides access to the actual value via {@link NavigableSet}'s API. This may or may be the same
* object as returned by {@link #actual}, therefore you should avoid identity (e.g. {@code ==}) or
* type (e.g. {@code instanceof}) assertions on this object.
*/
private NavigableSet> actualAsNavigableSet() {
return actualAsNavigableSet;
}
/**
* A view into a {@link SortedSet} as a {@link NavigableSet}, enabling Truth to support assertions
* on {@code NavigableSet}'s API even if the user only has a {@code SortedSet}. For now only the
* functionality needed for the existing assertions has been implemented. Reference {@link
* com.google.common.collect.ForwardingNavigableSet}'s behavior when implementing additional
* methods.
*
* TODO(diamondm): consider moving this to com.google.common.collect if it's ever fully
* implemented.
*/
private static class SortedSetAsNavigableSet extends ForwardingSortedSet
implements NavigableSet {
private final SortedSet delegate;
static NavigableSet wrapIfNecessary(SortedSet set) {
if (set instanceof NavigableSet) {
return (NavigableSet) set;
}
return new SortedSetAsNavigableSet(set);
}
SortedSetAsNavigableSet(SortedSet delegate) {
this.delegate = checkNotNull(delegate);
}
@Override
protected SortedSet delegate() {
return delegate;
}
@Override
public E ceiling(E e) {
throw new UnsupportedOperationException();
}
@Override
public Iterator descendingIterator() {
throw new UnsupportedOperationException();
}
@Override
public NavigableSet descendingSet() {
throw new UnsupportedOperationException();
}
@Override
public E floor(E e) {
throw new UnsupportedOperationException();
}
@Override
public NavigableSet headSet(E toElement, boolean inclusive) {
throw new UnsupportedOperationException();
}
@Override
public E higher(E e) {
throw new UnsupportedOperationException();
}
@Override
public E lower(E e) {
throw new UnsupportedOperationException();
}
@Override
public E pollFirst() {
throw new UnsupportedOperationException();
}
@Override
public E pollLast() {
throw new UnsupportedOperationException();
}
@Override
public NavigableSet subSet(
E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
throw new UnsupportedOperationException();
}
@Override
public NavigableSet tailSet(E fromElement, boolean inclusive) {
throw new UnsupportedOperationException();
}
}
}