blob: 40d4db2cddab1212d13cf1115ced9c1c9fca2ee8 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.collect;
15
Ulf Adams795895a2015-03-06 15:58:35 +000016import static com.google.common.truth.Truth.assertThat;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010017import static org.junit.Assert.fail;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableSet;
21import com.google.common.collect.Iterables;
22import com.google.common.collect.Lists;
23import com.google.common.collect.Sets;
24import com.google.devtools.build.lib.collect.nestedset.NestedSet;
25import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010026import java.util.EnumSet;
27import java.util.HashSet;
28import java.util.List;
29import java.util.Set;
lberkiaea56b32017-05-30 12:35:33 +020030import org.junit.Test;
31import org.junit.runner.RunWith;
32import org.junit.runners.JUnit4;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010033
34/**
35 * Tests for {@link CollectionUtils}.
36 */
37
38@RunWith(JUnit4.class)
39public class CollectionUtilsTest {
40
41 @Test
42 public void testDuplicatedElementsOf() {
43 assertDups(ImmutableList.<Integer>of(), ImmutableSet.<Integer>of());
44 assertDups(ImmutableList.of(0), ImmutableSet.<Integer>of());
45 assertDups(ImmutableList.of(0, 0, 0), ImmutableSet.of(0));
46 assertDups(ImmutableList.of(1, 2, 3, 1, 2, 3), ImmutableSet.of(1, 2, 3));
47 assertDups(ImmutableList.of(1, 2, 3, 1, 2, 3, 4), ImmutableSet.of(1, 2, 3));
48 assertDups(ImmutableList.of(1, 2, 3, 4), ImmutableSet.<Integer>of());
49 }
50
51 private static void assertDups(List<Integer> collection, Set<Integer> dups) {
lberkiaea56b32017-05-30 12:35:33 +020052 assertThat(CollectionUtils.duplicatedElementsOf(collection)).isEqualTo(dups);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010053 }
54
55 @Test
56 public void testIsImmutable() throws Exception {
lberkiaea56b32017-05-30 12:35:33 +020057 assertThat(CollectionUtils.isImmutable(ImmutableList.of(1, 2, 3))).isTrue();
58 assertThat(CollectionUtils.isImmutable(ImmutableSet.of(1, 2, 3))).isTrue();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010059
60 NestedSet<Integer> ns = NestedSetBuilder.<Integer>compileOrder()
61 .add(1).add(2).add(3).build();
lberkiaea56b32017-05-30 12:35:33 +020062 assertThat(CollectionUtils.isImmutable(ns)).isTrue();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010063
64 NestedSet<Integer> ns2 = NestedSetBuilder.<Integer>linkOrder().add(1).add(2).add(3).build();
lberkiaea56b32017-05-30 12:35:33 +020065 assertThat(CollectionUtils.isImmutable(ns2)).isTrue();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010066
tomlu641569a2018-04-18 08:41:55 -070067 Iterable<Integer> chain = IterablesChain.<Integer>builder().addElement(1).build();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010068
lberkiaea56b32017-05-30 12:35:33 +020069 assertThat(CollectionUtils.isImmutable(chain)).isTrue();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010070
lberkiaea56b32017-05-30 12:35:33 +020071 assertThat(CollectionUtils.isImmutable(Lists.newArrayList())).isFalse();
72 assertThat(CollectionUtils.isImmutable(Lists.newLinkedList())).isFalse();
73 assertThat(CollectionUtils.isImmutable(Sets.newHashSet())).isFalse();
74 assertThat(CollectionUtils.isImmutable(Sets.newLinkedHashSet())).isFalse();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010075
76 // The result of Iterables.concat() actually is immutable, but we have no way of checking if
77 // a given Iterable comes from concat().
lberkiaea56b32017-05-30 12:35:33 +020078 assertThat(CollectionUtils.isImmutable(Iterables.concat(ns, ns2))).isFalse();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010079
80 // We can override the check by using the ImmutableIterable wrapper.
lberkiaea56b32017-05-30 12:35:33 +020081 assertThat(CollectionUtils.isImmutable(ImmutableIterable.from(Iterables.concat(ns, ns2))))
82 .isTrue();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083 }
84
85 @Test
86 public void testCheckImmutable() throws Exception {
87 CollectionUtils.checkImmutable(ImmutableList.of(1, 2, 3));
88 CollectionUtils.checkImmutable(ImmutableSet.of(1, 2, 3));
89
90 try {
91 CollectionUtils.checkImmutable(Lists.newArrayList(1, 2, 3));
92 } catch (IllegalStateException e) {
93 return;
94 }
95 fail();
96 }
97
98 @Test
99 public void testMakeImmutable() throws Exception {
100 Iterable<Integer> immutableList = ImmutableList.of(1, 2, 3);
lberkiaea56b32017-05-30 12:35:33 +0200101 assertThat(CollectionUtils.makeImmutable(immutableList)).isSameAs(immutableList);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100102
103 Iterable<Integer> mutableList = Lists.newArrayList(1, 2, 3);
104 Iterable<Integer> converted = CollectionUtils.makeImmutable(mutableList);
lberkiaea56b32017-05-30 12:35:33 +0200105 assertThat(converted).isNotSameAs(mutableList);
106 assertThat(ImmutableList.copyOf(converted)).isEqualTo(mutableList);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100107 }
108
109 private static enum Small { ALPHA, BRAVO }
110 private static enum Large {
111 L0, L1, L2, L3, L4, L5, L6, L7, L8, L9,
112 L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
113 L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
114 L30, L31,
115 }
116
117 private static enum TooLarge {
118 T0, T1, T2, T3, T4, T5, T6, T7, T8, T9,
119 T10, T11, T12, T13, T14, T15, T16, T17, T18, T19,
120 T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
121 T30, T31, T32,
122 }
123
124 private static enum Medium {
125 ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT,
126 }
127
128 private <T extends Enum<T>> void assertAllDifferent(Class<T> clazz) throws Exception {
129 Set<EnumSet<T>> allSets = new HashSet<>();
130
131 int maxBits = 1 << clazz.getEnumConstants().length;
132 for (int i = 0; i < maxBits; i++) {
133 EnumSet<T> set = CollectionUtils.fromBits(i, clazz);
134 int back = CollectionUtils.toBits(set);
lberkiaea56b32017-05-30 12:35:33 +0200135 assertThat(i).isEqualTo(back); // Assert that a roundtrip is idempotent
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100136 allSets.add(set);
137 }
138
Ulf Adams795895a2015-03-06 15:58:35 +0000139 assertThat(allSets).hasSize(maxBits); // Assert that every decoded value is different
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100140 }
141
142 @Test
143 public void testEnumBitfields() throws Exception {
lberkiaea56b32017-05-30 12:35:33 +0200144 assertThat(CollectionUtils.<Small>toBits()).isEqualTo(0);
145 assertThat(CollectionUtils.fromBits(0, Small.class)).isEqualTo(EnumSet.noneOf(Small.class));
146 assertThat(CollectionUtils.toBits(Small.ALPHA, Small.BRAVO)).isEqualTo(3);
147 assertThat(CollectionUtils.toBits(Medium.TWO, Medium.FOUR)).isEqualTo(10);
148 assertThat(CollectionUtils.fromBits(192, Medium.class))
149 .isEqualTo(EnumSet.of(Medium.SEVEN, Medium.EIGHT));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100150
151 assertAllDifferent(Small.class);
152 assertAllDifferent(Medium.class);
153 assertAllDifferent(Large.class);
154
155 try {
156 CollectionUtils.toBits(TooLarge.T32);
157 fail();
158 } catch (IllegalArgumentException e) {
159 // good
160 }
161
162 try {
163 CollectionUtils.fromBits(0, TooLarge.class);
164 fail();
165 } catch (IllegalArgumentException e) {
166 // good
167 }
168 }
169}