/*
* Copyright 2017 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.template.soy.jssrc.internal;
import com.google.common.truth.FailureStrategy;
import com.google.common.truth.Subject;
import com.google.common.truth.SubjectFactory;
import com.google.common.truth.Truth;
import com.google.template.soy.jssrc.dsl.CodeChunk;
import com.google.template.soy.jssrc.internal.NullSafeAccumulator.FieldAccess;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for {@link NullSafeAccumulator}. */
@RunWith(JUnit4.class)
public final class NullSafeAccumulatorTest {
@Test
public void testNullSafeChain() {
NullSafeAccumulator accum = new NullSafeAccumulator(CodeChunk.id("a"));
assertThat(accum).generates("a;");
assertThat(accum.dotAccess(FieldAccess.id("b"), true /* nullSafe */))
.generates("a == null ? null : a.b;");
assertThat(accum.bracketAccess(CodeChunk.id("c"), true /* nullSafe */))
.generates("a == null ? null : a.b == null ? null : a.b[c];");
assertThat(accum.dotAccess(FieldAccess.id("d"), true /* nullSafe */))
.generates("a == null ? null : a.b == null ? null : a.b[c] == null ? null : a.b[c].d;");
assertThat(accum.bracketAccess(CodeChunk.id("e"), true /* nullSafe */))
.generates("a == null ? null : a.b == null ? null : a.b[c] == null ? null : a.b[c].d == null ? null : a.b[c].d[e];");
}
@Test
public void testNonNullSafeChain() {
NullSafeAccumulator accum = new NullSafeAccumulator(CodeChunk.id("a"));
assertThat(accum)
.generates("a;");
assertThat(accum.bracketAccess(CodeChunk.id("b"), false /* nullSafe */))
.generates("a[b];");
assertThat(accum.dotAccess(FieldAccess.id("c"), false /* nullSafe */))
.generates("a[b].c;");
assertThat(accum.bracketAccess(CodeChunk.id("d"), false /* nullSafe */))
.generates("a[b].c[d];");
assertThat(accum.dotAccess(FieldAccess.id("e"), false /* nullSafe */))
.generates("a[b].c[d].e;");
}
@Test
public void testMixedChains() {
NullSafeAccumulator accum = new NullSafeAccumulator(CodeChunk.id("a"));
assertThat(accum).generates("a;");
assertThat(accum.dotAccess(FieldAccess.id("b"), true /* nullSafe */))
.generates("a == null ? null : a.b;");
assertThat(accum.bracketAccess(CodeChunk.id("c"), false /* nullSafe */))
.generates("a == null ? null : a.b[c];");
assertThat(accum.dotAccess(FieldAccess.id("d"), true /* nullSafe */))
.generates("a == null ? null : a.b[c] == null ? null : a.b[c].d;");
assertThat(accum.bracketAccess(CodeChunk.id("e"), false /* nullSafe */))
.generates("a == null ? null : a.b[c] == null ? null : a.b[c].d[e];");
}
@Test
public void testCallPreservesChain() {
NullSafeAccumulator accum = new NullSafeAccumulator(CodeChunk.id("a"));
assertThat(accum.dotAccess(FieldAccess.call("b", CodeChunk.id("c")), false /* nullSafe */))
.generates("a.b(c);");
assertThat(accum.dotAccess(FieldAccess.call("d", CodeChunk.id("e")), true /* nullSafe */))
.generates("a.b(c) == null ? null : a.b(c).d(e);");
}
private static final SubjectFactory<AccumulatorSubject, NullSafeAccumulator> FACTORY =
new SubjectFactory<AccumulatorSubject, NullSafeAccumulator>() {
@Override
public AccumulatorSubject getSubject(FailureStrategy fs, NullSafeAccumulator that) {
return new AccumulatorSubject(fs, that);
}
};
private static AccumulatorSubject assertThat(NullSafeAccumulator accumulator) {
return Truth.assertAbout(FACTORY).that(accumulator);
}
private static final class AccumulatorSubject
extends Subject<AccumulatorSubject, NullSafeAccumulator> {
AccumulatorSubject(FailureStrategy failureStrategy, NullSafeAccumulator actual) {
super(failureStrategy, actual);
}
void generates(String expectedCode) {
String actualCode =
actual()
.result(CodeChunk.Generator.create(JsSrcNameGenerators.forLocalVariables()))
.getCode();
if (!actualCode.equals(expectedCode)) {
failWithBadResults("generates", expectedCode, "generates", actualCode);
}
}
}
}