blob: 3c7e70796a8c28311105b1d7ac64c84259ee1e61 [file] [log] [blame]
// Copyright 2018 The Feed Authors.
//
// 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.android.libraries.feed.piet;
import static com.google.android.libraries.feed.common.testing.RunnableSubject.assertThatRunnable;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import android.app.Activity;
import android.content.Context;
import android.widget.FrameLayout;
import com.google.android.libraries.feed.common.ui.LayoutUtils;
import com.google.android.libraries.feed.host.config.DebugBehavior;
import com.google.android.libraries.feed.piet.DebugLogger.ErrorCodeAndMessage;
import com.google.android.libraries.feed.piet.DebugLogger.MessageType;
import com.google.android.libraries.feed.piet.PietStylesHelper.PietStylesHelperFactory;
import com.google.android.libraries.feed.piet.host.ActionHandler;
import com.google.android.libraries.feed.piet.host.AssetProvider;
import com.google.android.libraries.feed.piet.host.CustomElementProvider;
import com.google.android.libraries.feed.piet.host.HostBindingProvider;
import com.google.search.now.ui.piet.ActionsProto.Actions;
import com.google.search.now.ui.piet.BindingRefsProto.ActionsBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.ChunkedTextBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.CustomBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.ElementBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.GridCellWidthBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.ImageBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.ParameterizedTextBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.StyleBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.TemplateBindingRef;
import com.google.search.now.ui.piet.BindingRefsProto.VisibilityBindingRef;
import com.google.search.now.ui.piet.ElementsProto.BindingContext;
import com.google.search.now.ui.piet.ElementsProto.BindingValue;
import com.google.search.now.ui.piet.ElementsProto.CustomElementData;
import com.google.search.now.ui.piet.ElementsProto.Element;
import com.google.search.now.ui.piet.ElementsProto.GridCellWidth;
import com.google.search.now.ui.piet.ElementsProto.HostBindingData;
import com.google.search.now.ui.piet.ElementsProto.TemplateInvocation;
import com.google.search.now.ui.piet.ElementsProto.TextElement;
import com.google.search.now.ui.piet.ElementsProto.Visibility;
import com.google.search.now.ui.piet.ErrorsProto.ErrorCode;
import com.google.search.now.ui.piet.GradientsProto.ColorStop;
import com.google.search.now.ui.piet.GradientsProto.Fill;
import com.google.search.now.ui.piet.GradientsProto.LinearGradient;
import com.google.search.now.ui.piet.ImagesProto.Image;
import com.google.search.now.ui.piet.ImagesProto.ImageSource;
import com.google.search.now.ui.piet.MediaQueriesProto.ComparisonCondition;
import com.google.search.now.ui.piet.MediaQueriesProto.DarkLightCondition;
import com.google.search.now.ui.piet.MediaQueriesProto.DarkLightCondition.DarkLightMode;
import com.google.search.now.ui.piet.MediaQueriesProto.FrameWidthCondition;
import com.google.search.now.ui.piet.MediaQueriesProto.MediaQueryCondition;
import com.google.search.now.ui.piet.PietProto.Frame;
import com.google.search.now.ui.piet.PietProto.PietSharedState;
import com.google.search.now.ui.piet.PietProto.Stylesheet;
import com.google.search.now.ui.piet.PietProto.Stylesheets;
import com.google.search.now.ui.piet.PietProto.Template;
import com.google.search.now.ui.piet.StylesProto.BoundStyle;
import com.google.search.now.ui.piet.StylesProto.Font;
import com.google.search.now.ui.piet.StylesProto.Font.FontWeight;
import com.google.search.now.ui.piet.StylesProto.GravityVertical;
import com.google.search.now.ui.piet.StylesProto.Style;
import com.google.search.now.ui.piet.StylesProto.StyleIdsStack;
import com.google.search.now.ui.piet.TextProto.Chunk;
import com.google.search.now.ui.piet.TextProto.ChunkedText;
import com.google.search.now.ui.piet.TextProto.ParameterizedText;
import com.google.search.now.ui.piet.TextProto.StyledTextChunk;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
/** Tests of the {@link FrameContext}. */
@RunWith(RobolectricTestRunner.class)
public class FrameContextTest {
private static final String DEFAULT_TEMPLATE_ID = "TEMPLATE_ID";
private static final Template DEFAULT_TEMPLATE =
Template.newBuilder().setTemplateId(DEFAULT_TEMPLATE_ID).build();
private static final Frame DEFAULT_FRAME =
Frame.newBuilder().addTemplates(DEFAULT_TEMPLATE).build();
private static final String SAMPLE_STYLE_ID = "STYLE_ID";
private static final int BASE_STYLE_COLOR = 111111;
private static final int SAMPLE_STYLE_COLOR = 888888;
private static final Style SAMPLE_STYLE =
Style.newBuilder().setStyleId(SAMPLE_STYLE_ID).setColor(SAMPLE_STYLE_COLOR).build();
private static final String STYLESHEET_ID = "STYLESHEET_ID";
private static final Style BASE_STYLE = Style.newBuilder().setColor(BASE_STYLE_COLOR).build();
private static final StyleIdsStack SAMPLE_STYLE_IDS =
StyleIdsStack.newBuilder().addStyleIds(SAMPLE_STYLE_ID).build();
private static final String BINDING_ID = "BINDING_ID";
private static final String INVALID_BINDING_ID = "NOT_A_REAL_BINDING_ID";
private static final Map<String, Template> DEFAULT_TEMPLATES = new HashMap<>();
private static final int FRAME_WIDTH_PX = 999999;
static {
DEFAULT_TEMPLATES.put(DEFAULT_TEMPLATE_ID, DEFAULT_TEMPLATE);
}
@Mock private ActionHandler actionHandler;
@Mock private AssetProvider assetProvider;
private final Map<String, Style> defaultStylesheet = new HashMap<>();
private final DebugLogger debugLogger = new DebugLogger();
private HostBindingProvider hostBindingProvider;
private HostProviders hostProviders;
private FrameContext frameContext;
private List<PietSharedState> pietSharedStates;
private PietStylesHelper pietStylesHelper;
private StyleProvider defaultStyleProvider;
private Context context;
private FrameLayout frameView;
@Before
public void setUp() throws Exception {
initMocks(this);
context = Robolectric.buildActivity(Activity.class).get();
hostBindingProvider = new HostBindingProvider();
hostProviders =
new HostProviders(assetProvider, mock(CustomElementProvider.class), hostBindingProvider);
defaultStyleProvider = new StyleProvider(assetProvider);
defaultStylesheet.put(SAMPLE_STYLE_ID, SAMPLE_STYLE);
pietSharedStates = new ArrayList<>();
pietStylesHelper = newPietStylesHelper();
frameView = new FrameLayout(context);
}
@Test
public void testSharedStateTemplatesAddedToFrame() {
String sharedStateTemplateId = "SHARED_STATE_TEMPLATE_ID";
Template sharedStateTemplate =
Template.newBuilder().setTemplateId(sharedStateTemplateId).build();
pietSharedStates.add(PietSharedState.newBuilder().addTemplates(sharedStateTemplate).build());
frameContext = defaultFrameContext();
assertThat(frameContext.getTemplate(sharedStateTemplateId))
.isSameInstanceAs(sharedStateTemplate);
assertThat(frameContext.getTemplate(DEFAULT_TEMPLATE_ID)).isSameInstanceAs(DEFAULT_TEMPLATE);
}
@Test
public void testThrowsIfSharedStateTemplatesConflictWithFrameTemplates() {
Template sharedStateTemplate = Template.newBuilder().setTemplateId(DEFAULT_TEMPLATE_ID).build();
pietSharedStates.add(PietSharedState.newBuilder().addTemplates(sharedStateTemplate).build());
assertThatRunnable(this::defaultFrameContext)
.throwsAnExceptionOfType(IllegalArgumentException.class)
.that()
.hasMessageThat()
.contains("Template key 'TEMPLATE_ID' already defined");
}
@Test
public void testThrowsIfDuplicateBindingValueId() {
frameContext = defaultFrameContext();
BindingContext bindingContextWithDuplicateIds =
BindingContext.newBuilder()
.addBindingValues(BindingValue.newBuilder().setBindingId(BINDING_ID))
.addBindingValues(BindingValue.newBuilder().setBindingId(BINDING_ID))
.build();
assertThatRunnable(
() ->
frameContext.createTemplateContext(
DEFAULT_TEMPLATE, bindingContextWithDuplicateIds))
.throwsAnExceptionOfType(IllegalArgumentException.class)
.that()
.hasMessageThat()
.contains("BindingValue key 'BINDING_ID' already defined");
}
@Test
public void testGetters() {
String template2BindingId = "TEMPLATE_2";
Template template2 = Template.newBuilder().setTemplateId(template2BindingId).build();
PietSharedState sharedState = PietSharedState.newBuilder().addTemplates(template2).build();
pietSharedStates.add(sharedState);
frameContext =
new FrameContext(
DEFAULT_FRAME,
defaultStylesheet,
pietSharedStates,
newPietStylesHelper(),
DebugBehavior.VERBOSE,
debugLogger,
actionHandler,
hostProviders,
frameView);
assertThat(frameContext.getFrame()).isEqualTo(DEFAULT_FRAME);
assertThat(frameContext.getActionHandler()).isEqualTo(actionHandler);
assertThat(frameContext.getTemplate(DEFAULT_TEMPLATE_ID)).isEqualTo(DEFAULT_TEMPLATE);
assertThat(frameContext.getTemplate(template2BindingId)).isEqualTo(template2);
}
@Test
public void testThrowsWithNoBindingContext() {
frameContext = makeFrameContextForDefaultFrame();
assertThatRunnable(
() -> frameContext.getActionsFromBinding(ActionsBindingRef.getDefaultInstance()))
.throwsAnExceptionOfType(IllegalArgumentException.class)
.that()
.hasMessageThat()
.contains("no BindingValues defined");
}
@Test
public void testCreateTemplateContext_lotsOfStuff() {
frameContext = defaultFrameContext();
// createTemplateContext should add new BindingValues
ParameterizedText text = ParameterizedText.newBuilder().setText("Calico").build();
BindingValue textBinding =
BindingValue.newBuilder().setBindingId(BINDING_ID).setParameterizedText(text).build();
FrameContext frameContextWithBindings =
frameContext.createTemplateContext(
DEFAULT_TEMPLATE, BindingContext.newBuilder().addBindingValues(textBinding).build());
assertThat(
frameContextWithBindings
.getParameterizedTextBindingValue(
ParameterizedTextBindingRef.newBuilder().setBindingId(BINDING_ID).build())
.getParameterizedText())
.isEqualTo(text);
// and clear out all the previous styles
assertThat(frameContextWithBindings.makeStyleFor(StyleIdsStack.getDefaultInstance()))
.isEqualTo(defaultStyleProvider);
assertThat(frameContextWithBindings.makeStyleFor(SAMPLE_STYLE_IDS).getColor())
.isEqualTo(defaultStyleProvider.getColor());
}
@Test
public void testCreateTemplateContext_stylesheetId() {
String styleId = "cotton";
int width = 343;
Style style = Style.newBuilder().setStyleId(styleId).setWidth(width).build();
String stylesheetId = "linen";
Stylesheet stylesheet =
Stylesheet.newBuilder().setStylesheetId(stylesheetId).addStyles(style).build();
pietSharedStates.add(PietSharedState.newBuilder().addStylesheets(stylesheet).build());
frameContext = defaultFrameContext();
Template template =
Template.newBuilder()
.setTemplateId("kingSize")
.setStylesheets(Stylesheets.newBuilder().addStylesheetIds(stylesheetId))
.build();
FrameContext templateContext =
frameContext.createTemplateContext(template, BindingContext.getDefaultInstance());
StyleIdsStack styleRef = StyleIdsStack.newBuilder().addStyleIds(styleId).build();
assertThat(templateContext.makeStyleFor(styleRef).getWidthSpecPx(context))
.isEqualTo((int) LayoutUtils.dpToPx(width, context));
}
@Test
public void testCreateTemplateContext_multipleStylesheets() {
String styleId = "cotton";
int width = 343;
Style style = Style.newBuilder().setStyleId(styleId).setWidth(width).build();
String stylesheetId = "linen";
Stylesheet stylesheet =
Stylesheet.newBuilder().setStylesheetId(stylesheetId).addStyles(style).build();
pietSharedStates.add(PietSharedState.newBuilder().addStylesheets(stylesheet).build());
frameContext = defaultFrameContext();
int templateStyleColor = 343434;
String templateStyleId = "templateStyle";
Template template =
Template.newBuilder()
.setTemplateId("kingSize")
.setStylesheets(
Stylesheets.newBuilder()
.addStylesheetIds(stylesheetId)
.addStylesheets(
Stylesheet.newBuilder()
.addStyles(
Style.newBuilder()
.setStyleId(templateStyleId)
.setColor(templateStyleColor))))
.build();
FrameContext templateContext =
frameContext.createTemplateContext(template, BindingContext.getDefaultInstance());
StyleIdsStack styleRef = StyleIdsStack.newBuilder().addStyleIds(styleId).build();
assertThat(templateContext.makeStyleFor(styleRef).getWidthSpecPx(context))
.isEqualTo((int) LayoutUtils.dpToPx(width, context));
styleRef = StyleIdsStack.newBuilder().addStyleIds(templateStyleId).build();
assertThat(templateContext.makeStyleFor(styleRef).getColor()).isEqualTo(templateStyleColor);
}
@Test
public void testCreateTemplateContext_transcludingBinding() {
String parentBindingId = "PARENT";
String childBindingId = "CHILD";
ParameterizedText parentBoundText =
ParameterizedText.newBuilder().setText("parent_text").build();
BindingValue parentBindingValue =
BindingValue.newBuilder()
.setBindingId(parentBindingId)
.setParameterizedText(parentBoundText)
.build();
ParameterizedTextBindingRef childTextBindingRef =
ParameterizedTextBindingRef.newBuilder().setBindingId(childBindingId).build();
frameContext = makeFrameContextWithBinding(parentBindingValue);
FrameContext childContext =
frameContext.createTemplateContext(
Template.newBuilder()
.setElement(
Element.newBuilder()
.setTextElement(
TextElement.newBuilder()
.setParameterizedTextBinding(childTextBindingRef)))
.build(),
BindingContext.newBuilder()
.addBindingValues(
BindingValue.newBuilder()
.setBindingId(childBindingId)
.setBindingIdFromTranscludingTemplate(parentBindingId))
.build());
assertThat(childContext.getParameterizedTextBindingValue(childTextBindingRef))
.isEqualTo(
BindingValue.newBuilder()
.setBindingId(childBindingId)
.setParameterizedText(parentBoundText)
.build());
}
@Test
public void testCreateTemplateContext_transcludingBindingNotFound() {
String invalidParentBindingId = "NOT_FOUND";
String childBindingId = "CHILD";
ParameterizedTextBindingRef childTextBindingRef =
ParameterizedTextBindingRef.newBuilder().setBindingId(childBindingId).build();
frameContext = makeFrameContextWithNoBindings();
FrameContext childContext =
frameContext.createTemplateContext(
Template.newBuilder()
.setElement(
Element.newBuilder()
.setTextElement(
TextElement.newBuilder()
.setParameterizedTextBinding(childTextBindingRef)))
.build(),
BindingContext.newBuilder()
.addBindingValues(
BindingValue.newBuilder()
.setBindingId(childBindingId)
.setBindingIdFromTranscludingTemplate(invalidParentBindingId))
.build());
assertThat(debugLogger.getMessages(MessageType.ERROR))
.containsExactly(
new ErrorCodeAndMessage(
ErrorCode.ERR_MISSING_BINDING_VALUE,
"[] Parent binding value 'NOT_FOUND' not found"));
assertThatRunnable(() -> childContext.getParameterizedTextBindingValue(childTextBindingRef))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Parameterized text binding not found for CHILD");
}
@Test
public void testMakeStyleFor() {
frameContext = defaultFrameContext();
// Returns base style provider if there are no styles defined
StyleProvider noStyle = frameContext.makeStyleFor(StyleIdsStack.getDefaultInstance());
assertThat(noStyle).isEqualTo(defaultStyleProvider);
// Successful lookup results in a new style provider
StyleProvider defaultStyle = frameContext.makeStyleFor(SAMPLE_STYLE_IDS);
assertThat(defaultStyle.getColor()).isEqualTo(SAMPLE_STYLE_COLOR);
// Failed lookup returns the current style provider
StyleProvider notFoundStyle =
frameContext.makeStyleFor(
StyleIdsStack.newBuilder().addStyleIds(INVALID_BINDING_ID).build());
assertThat(notFoundStyle).isEqualTo(defaultStyleProvider);
}
@Test
public void testGetText() {
ParameterizedText text = ParameterizedText.newBuilder().setText("tabby").build();
BindingValue textBindingValue = defaultBinding().setParameterizedText(text).build();
ParameterizedTextBindingRef textBindingRef =
ParameterizedTextBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(textBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getParameterizedTextBindingValue(textBindingRef))
.isEqualTo(textBindingValue);
// Can't look up binding
assertThatRunnable(
() ->
frameContext.getParameterizedTextBindingValue(
ParameterizedTextBindingRef.newBuilder()
.setBindingId(INVALID_BINDING_ID)
.build()))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Parameterized text binding not found");
// Binding has no content
assertThatRunnable(
() -> makeFrameContextWithNoBindings().getParameterizedTextBindingValue(textBindingRef))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Parameterized text binding not found");
// Binding is invalid but is optional
ParameterizedTextBindingRef textBindingRefInvalidOptional =
ParameterizedTextBindingRef.newBuilder()
.setBindingId(INVALID_BINDING_ID)
.setIsOptional(true)
.build();
assertThat(
makeFrameContextWithNoBindings()
.getParameterizedTextBindingValue(textBindingRefInvalidOptional))
.isEqualTo(BindingValue.getDefaultInstance());
// Binding has no content but is optional
ParameterizedTextBindingRef textBindingRefOptional =
ParameterizedTextBindingRef.newBuilder()
.setBindingId(BINDING_ID)
.setIsOptional(true)
.build();
assertThat(
makeFrameContextWithNoBindings()
.getParameterizedTextBindingValue(textBindingRefOptional))
.isEqualTo(BindingValue.getDefaultInstance());
}
@Test
public void testGetText_hostBinding() {
ParameterizedText text = ParameterizedText.newBuilder().setText("tabby").build();
BindingValue textBindingValue = defaultBinding().setParameterizedText(text).build();
BindingValue hostTextBindingValue =
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setParameterizedText(text)
.build();
ParameterizedTextBindingRef textBindingRef =
ParameterizedTextBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(hostTextBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getParameterizedTextBindingValue(textBindingRef))
.isEqualTo(textBindingValue);
}
@Test
public void testGetImage() {
Image image = Image.newBuilder().setOverlayColor(12345).build();
BindingValue imageBindingValue = defaultBinding().setImage(image).build();
ImageBindingRef imageBindingRef = ImageBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(imageBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getImageBindingValue(imageBindingRef)).isEqualTo(imageBindingValue);
// Can't look up binding
assertThatRunnable(
() ->
frameContext.getImageBindingValue(
ImageBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Image binding not found");
// Binding has no content
assertThatRunnable(() -> makeFrameContextWithNoBindings().getImageBindingValue(imageBindingRef))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Image binding not found");
// Binding is invalid but is optional
ImageBindingRef imageBindingRefInvalidOptional =
ImageBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).setIsOptional(true).build();
assertThat(
makeFrameContextWithNoBindings().getImageBindingValue(imageBindingRefInvalidOptional))
.isEqualTo(BindingValue.getDefaultInstance());
// Binding has no content but is optional
ImageBindingRef imageBindingRefOptional =
ImageBindingRef.newBuilder().setBindingId(BINDING_ID).setIsOptional(true).build();
assertThat(makeFrameContextWithNoBindings().getImageBindingValue(imageBindingRefOptional))
.isEqualTo(BindingValue.getDefaultInstance());
}
@Test
public void testGetImage_hostBinding() {
Image image = Image.newBuilder().setOverlayColor(12345).build();
BindingValue imageBindingValue = defaultBinding().setImage(image).build();
BindingValue hostImageBindingValue =
defaultBinding().setHostBindingData(HostBindingData.newBuilder()).setImage(image).build();
ImageBindingRef imageBindingRef = ImageBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(hostImageBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getImageBindingValue(imageBindingRef)).isEqualTo(imageBindingValue);
}
@Test
public void testGetElement() {
Element element =
Element.newBuilder().setGravityVertical(GravityVertical.GRAVITY_MIDDLE).build();
BindingValue elementBindingValue = defaultBinding().setElement(element).build();
ElementBindingRef elementBindingRef =
ElementBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(elementBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getElementBindingValue(elementBindingRef))
.isEqualTo(elementBindingValue);
// Can't look up binding
assertThatRunnable(
() ->
frameContext.getElementBindingValue(
ElementBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Element binding not found");
// Binding has no content
assertThatRunnable(
() -> makeFrameContextWithNoBindings().getElementBindingValue(elementBindingRef))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Element binding not found");
// Binding is missing but is optional
ElementBindingRef elementBindingRefInvalidOptional =
ElementBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).setIsOptional(true).build();
assertThat(
makeFrameContextWithNoBindings()
.getElementBindingValue(elementBindingRefInvalidOptional))
.isEqualTo(BindingValue.getDefaultInstance());
// Binding has no content but is optional
ElementBindingRef elementBindingRefOptional =
ElementBindingRef.newBuilder().setBindingId(BINDING_ID).setIsOptional(true).build();
assertThat(makeFrameContextWithNoBindings().getElementBindingValue(elementBindingRefOptional))
.isEqualTo(BindingValue.getDefaultInstance());
}
@Test
public void testGetElement_hostBinding() {
Element element =
Element.newBuilder().setGravityVertical(GravityVertical.GRAVITY_MIDDLE).build();
BindingValue elementBindingValue = defaultBinding().setElement(element).build();
BindingValue hostListBindingValue =
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setElement(element)
.build();
ElementBindingRef elementBindingRef =
ElementBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(hostListBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getElementBindingValue(elementBindingRef))
.isEqualTo(elementBindingValue);
}
@Test
public void testGetVisibility() {
Visibility visibility = Visibility.INVISIBLE;
BindingValue visibilityBindingValue = defaultBinding().setVisibility(visibility).build();
VisibilityBindingRef visibilityBindingRef =
VisibilityBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(visibilityBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getVisibilityFromBinding(visibilityBindingRef)).isEqualTo(visibility);
// Can't look up binding
assertThat(
frameContext.getVisibilityFromBinding(
VisibilityBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.isNull();
// Binding has no content
assertThat(makeFrameContextWithNoBindings().getVisibilityFromBinding(visibilityBindingRef))
.isNull();
}
@Test
public void testGetVisibility_hostBinding() {
Visibility visibility = Visibility.INVISIBLE;
BindingValue hostListBindingValue =
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setVisibility(visibility)
.build();
VisibilityBindingRef visibilityBindingRef =
VisibilityBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(hostListBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getVisibilityFromBinding(visibilityBindingRef)).isEqualTo(visibility);
}
@Test
public void testGetGridCellWidthFromBinding() {
GridCellWidth cellWidth = GridCellWidth.newBuilder().setWeight(123).build();
frameContext = makeFrameContextWithBinding(defaultBinding().setCellWidth(cellWidth).build());
assertThat(
frameContext.getGridCellWidthFromBinding(
GridCellWidthBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isEqualTo(cellWidth);
assertThat(
frameContext.getGridCellWidthFromBinding(
GridCellWidthBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.isNull();
frameContext = makeFrameContextWithNoBindings();
assertThat(
frameContext.getGridCellWidthFromBinding(
GridCellWidthBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isNull();
}
@Test
public void testGetGridCellWidthFromBinding_hostBinding() {
GridCellWidth cellWidth = GridCellWidth.newBuilder().setWeight(123).build();
frameContext =
makeFrameContextWithBinding(
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setCellWidth(cellWidth)
.build());
assertThat(
frameContext.getGridCellWidthFromBinding(
GridCellWidthBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isEqualTo(cellWidth);
}
@Test
public void testGetActionsFromBinding() {
Actions actions = Actions.newBuilder().build();
frameContext = makeFrameContextWithBinding(defaultBinding().setActions(actions).build());
assertThat(
frameContext.getActionsFromBinding(
ActionsBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isSameInstanceAs(actions);
assertThat(
frameContext.getActionsFromBinding(
ActionsBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.isSameInstanceAs(Actions.getDefaultInstance());
frameContext = makeFrameContextWithNoBindings();
assertThat(
frameContext.getActionsFromBinding(
ActionsBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isSameInstanceAs(Actions.getDefaultInstance());
}
@Test
public void testGetActionsFromBinding_hostBinding() {
frameContext =
makeFrameContextWithBinding(
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setActions(Actions.getDefaultInstance())
.build());
assertThat(
frameContext.getActionsFromBinding(
ActionsBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isEqualTo(Actions.getDefaultInstance());
}
@Test
public void testGetStyleFromBinding() {
BoundStyle boundStyle = BoundStyle.newBuilder().setColor(12345).build();
frameContext = makeFrameContextWithBinding(defaultBinding().setBoundStyle(boundStyle).build());
assertThat(
frameContext.getStyleFromBinding(
StyleBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isEqualTo(boundStyle);
assertThat(
frameContext.getStyleFromBinding(
StyleBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.isEqualTo(BoundStyle.getDefaultInstance());
frameContext = makeFrameContextWithNoBindings();
assertThat(
frameContext.getStyleFromBinding(
StyleBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isEqualTo(BoundStyle.getDefaultInstance());
}
@Test
public void testGetStyleFromBinding_hostBinding() {
BoundStyle boundStyle = BoundStyle.newBuilder().setColor(12345).build();
frameContext =
makeFrameContextWithBinding(
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setBoundStyle(boundStyle)
.build());
assertThat(
frameContext.getStyleFromBinding(
StyleBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isEqualTo(boundStyle);
}
@Test
public void testGetTemplateInvocationFromBinding() {
TemplateInvocation templateInvocation =
TemplateInvocation.newBuilder().setTemplateId("carboncopy").build();
BindingValue templateBindingValue =
defaultBinding().setTemplateInvocation(templateInvocation).build();
frameContext = makeFrameContextWithBinding(templateBindingValue);
assertThat(
frameContext.getTemplateInvocationBindingValue(
TemplateBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.isEqualTo(templateBindingValue);
assertThat(
frameContext.getTemplateInvocationBindingValue(
TemplateBindingRef.newBuilder()
.setIsOptional(true)
.setBindingId(INVALID_BINDING_ID)
.build()))
.isEqualTo(BindingValue.getDefaultInstance());
assertThatRunnable(
() ->
frameContext.getTemplateInvocationBindingValue(
TemplateBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Template binding not found for NOT_A_REAL_BINDING_ID");
frameContext = makeFrameContextWithNoBindings();
assertThatRunnable(
() ->
frameContext.getTemplateInvocationBindingValue(
TemplateBindingRef.newBuilder().setBindingId(BINDING_ID).build()))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Template binding not found for BINDING_ID");
}
@Test
public void testGetTemplateInvocationFromBinding_hostBinding() {
TemplateInvocation templateInvocation =
TemplateInvocation.newBuilder().setTemplateId("carboncopy").build();
frameContext =
makeFrameContextWithBinding(
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setTemplateInvocation(templateInvocation)
.build());
}
@Test
public void testGetCustomElementBindingValue() {
CustomElementData customElement = CustomElementData.getDefaultInstance();
BindingValue customElementBindingValue =
defaultBinding().setCustomElementData(customElement).build();
CustomBindingRef customBindingRef =
CustomBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(customElementBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getCustomElementBindingValue(customBindingRef))
.isEqualTo(customElementBindingValue);
// Can't look up binding
assertThatRunnable(
() ->
frameContext.getCustomElementBindingValue(
CustomBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Custom element binding not found");
// Binding has no content
assertThatRunnable(
() -> makeFrameContextWithNoBindings().getCustomElementBindingValue(customBindingRef))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Custom element binding not found");
// Binding is missing but is optional
CustomBindingRef customBindingRefInvalidOptional =
CustomBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).setIsOptional(true).build();
assertThat(
makeFrameContextWithNoBindings()
.getCustomElementBindingValue(customBindingRefInvalidOptional))
.isEqualTo(BindingValue.getDefaultInstance());
// Binding has no content but is optional
CustomBindingRef customBindingRefOptional =
CustomBindingRef.newBuilder().setBindingId(BINDING_ID).setIsOptional(true).build();
assertThat(
makeFrameContextWithNoBindings().getCustomElementBindingValue(customBindingRefOptional))
.isEqualTo(BindingValue.getDefaultInstance());
}
@Test
public void testGetCustomElementBindingValue_hostBinding() {
CustomElementData customElement = CustomElementData.getDefaultInstance();
BindingValue customElementBindingValue =
defaultBinding().setCustomElementData(customElement).build();
BindingValue hostCustomElementBindingValue =
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setCustomElementData(customElement)
.build();
CustomBindingRef customBindingRef =
CustomBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(hostCustomElementBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getCustomElementBindingValue(customBindingRef))
.isEqualTo(customElementBindingValue);
}
@Test
public void testGetChunkedTextBindingValue() {
ChunkedText text =
ChunkedText.newBuilder()
.addChunks(
Chunk.newBuilder()
.setTextChunk(
StyledTextChunk.newBuilder()
.setParameterizedText(ParameterizedText.newBuilder().setText("text"))))
.build();
BindingValue textBindingValue = defaultBinding().setChunkedText(text).build();
ChunkedTextBindingRef textBindingRef =
ChunkedTextBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(textBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getChunkedTextBindingValue(textBindingRef)).isEqualTo(textBindingValue);
// Can't look up binding
assertThatRunnable(
() ->
frameContext.getChunkedTextBindingValue(
ChunkedTextBindingRef.newBuilder().setBindingId(INVALID_BINDING_ID).build()))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Chunked text binding not found");
// Binding has no content
assertThatRunnable(
() -> makeFrameContextWithNoBindings().getChunkedTextBindingValue(textBindingRef))
.throwsAnExceptionOfType(PietFatalException.class)
.that()
.hasMessageThat()
.contains("Chunked text binding not found");
// Binding is missing but is optional
ChunkedTextBindingRef textBindingRefInvalidOptional =
ChunkedTextBindingRef.newBuilder()
.setBindingId(INVALID_BINDING_ID)
.setIsOptional(true)
.build();
assertThat(
makeFrameContextWithNoBindings()
.getChunkedTextBindingValue(textBindingRefInvalidOptional))
.isEqualTo(BindingValue.getDefaultInstance());
// Binding has no content but is optional
ChunkedTextBindingRef textBindingRefOptional =
ChunkedTextBindingRef.newBuilder().setBindingId(BINDING_ID).setIsOptional(true).build();
assertThat(makeFrameContextWithNoBindings().getChunkedTextBindingValue(textBindingRefOptional))
.isEqualTo(BindingValue.getDefaultInstance());
}
@Test
public void testGetChunkedTextBindingValue_hostBinding() {
ChunkedText text =
ChunkedText.newBuilder()
.addChunks(
Chunk.newBuilder()
.setTextChunk(
StyledTextChunk.newBuilder()
.setParameterizedText(ParameterizedText.newBuilder().setText("text"))))
.build();
BindingValue textBindingValue = defaultBinding().setChunkedText(text).build();
BindingValue hostTextBindingValue =
defaultBinding()
.setHostBindingData(HostBindingData.newBuilder())
.setChunkedText(text)
.build();
ChunkedTextBindingRef textBindingRef =
ChunkedTextBindingRef.newBuilder().setBindingId(BINDING_ID).build();
frameContext = makeFrameContextWithBinding(hostTextBindingValue);
// Succeed in looking up binding
assertThat(frameContext.getChunkedTextBindingValue(textBindingRef)).isEqualTo(textBindingValue);
}
// TODO: Remove; this is now reported by PietStylesHelper.
@Deprecated
@Test
public void testError_stylesheetNotFound() {
Frame frame =
Frame.newBuilder()
.setStylesheetId(STYLESHEET_ID)
.setStyleReferences(SAMPLE_STYLE_IDS)
.build();
FrameContext frameContext = makeFrameContextFromFrame(frame);
assertThat(frameContext).isNotNull();
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).hasSize(1);
}
@Test
public void testCreateWithoutError() {
Frame frame = getWorkingFrame();
FrameContext frameContext = makeFrameContextFromFrame(frame);
assertThat(frameContext).isNotNull();
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testBindFrame_withStylesheetId() {
Frame frame =
Frame.newBuilder()
.setStylesheets(Stylesheets.newBuilder().addStylesheetIds(STYLESHEET_ID))
.build();
setUpPietSharedStates();
FrameContext frameContext = makeFrameContextFromFrame(frame);
// The style is not currently bound, but available from the stylesheet.
assertThat(frameContext.makeStyleFor(StyleIdsStack.getDefaultInstance()).getColor())
.isNotEqualTo(SAMPLE_STYLE_COLOR);
assertThat(frameContext.makeStyleFor(SAMPLE_STYLE_IDS).getColor())
.isEqualTo(SAMPLE_STYLE_COLOR);
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testBindFrame_withStylesheet() {
Frame frame =
Frame.newBuilder()
.setStylesheets(
Stylesheets.newBuilder()
.addStylesheets(Stylesheet.newBuilder().addStyles(SAMPLE_STYLE)))
.build();
FrameContext frameContext = makeFrameContextFromFrame(frame);
// The style is not currently bound, but available from the stylesheet.
assertThat(frameContext.makeStyleFor(StyleIdsStack.getDefaultInstance()).getColor())
.isNotEqualTo(SAMPLE_STYLE_COLOR);
assertThat(frameContext.makeStyleFor(SAMPLE_STYLE_IDS).getColor())
.isEqualTo(SAMPLE_STYLE_COLOR);
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testBindFrame_withMultipleStylesheets() {
Frame frame =
Frame.newBuilder()
.setStylesheets(
Stylesheets.newBuilder()
.addStylesheetIds(STYLESHEET_ID)
.addStylesheets(Stylesheet.newBuilder().addStyles(BASE_STYLE).build()))
.build();
setUpPietSharedStates();
FrameContext frameContext = makeFrameContextFromFrame(frame);
assertThat(frameContext.makeStyleFor(StyleIdsStack.getDefaultInstance()).getColor())
.isNotEqualTo(SAMPLE_STYLE_COLOR);
assertThat(frameContext.makeStyleFor(SAMPLE_STYLE_IDS).getColor())
.isEqualTo(SAMPLE_STYLE_COLOR);
assertThat(
frameContext
.makeStyleFor(
StyleIdsStack.newBuilder().addStyleIds(BASE_STYLE.getStyleId()).build())
.getColor())
.isEqualTo(BASE_STYLE_COLOR);
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testBindFrame_withFrameStyle() {
Frame frame =
Frame.newBuilder()
.setStylesheets(
Stylesheets.newBuilder()
.addStylesheets(Stylesheet.newBuilder().addStyles(SAMPLE_STYLE)))
.setStyleReferences(SAMPLE_STYLE_IDS)
.build();
FrameContext frameContext = makeFrameContextFromFrame(frame);
assertThat(frameContext.makeStyleFor(StyleIdsStack.getDefaultInstance()))
.isEqualTo(defaultStyleProvider);
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testBindFrame_withoutFrameStyle() {
Frame frame =
Frame.newBuilder()
.setStylesheets(
Stylesheets.newBuilder()
.addStylesheets(Stylesheet.newBuilder().addStyles(SAMPLE_STYLE)))
.build();
FrameContext frameContext = makeFrameContextFromFrame(frame);
assertThat(frameContext.makeStyleFor(StyleIdsStack.getDefaultInstance()))
.isEqualTo(defaultStyleProvider);
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testBindFrame_baseStyle() {
int styleHeight = 747;
String heightStyleId = "JUMBO";
Frame frame =
Frame.newBuilder()
.setStylesheets(
Stylesheets.newBuilder()
.addStylesheets(
Stylesheet.newBuilder()
.addStyles(SAMPLE_STYLE)
.addStyles(
Style.newBuilder()
.setStyleId(heightStyleId)
.setHeight(styleHeight))))
.setStyleReferences(SAMPLE_STYLE_IDS)
.build();
// Set up a frame with a color applied to the frame.
FrameContext frameContext = makeFrameContextFromFrame(frame);
StyleProvider baseStyleWithHeight =
frameContext.makeStyleFor(StyleIdsStack.newBuilder().addStyleIds(heightStyleId).build());
// Make a style for something that doesn't override color, and check that the base color is a
// default, not the frame color.
assertThat(baseStyleWithHeight.getColor()).isEqualTo(Style.getDefaultInstance().getColor());
assertThat(baseStyleWithHeight.getHeightSpecPx(context))
.isEqualTo((int) LayoutUtils.dpToPx(styleHeight, context));
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testMergeStyleIdsStack() {
String styleId1 = "STYLE1";
Style style1 =
Style.newBuilder()
.setColor(12345) // Not overridden
.setMaxLines(54321) // Overridden
.setFont(Font.newBuilder().setSize(11).setWeight(FontWeight.MEDIUM))
.setBackground(
Fill.newBuilder()
.setLinearGradient(
LinearGradient.newBuilder()
.addStops(ColorStop.newBuilder().setColor(1234))))
.setStyleId(styleId1)
.build();
String styleId2 = "STYLE2";
Style style2 =
Style.newBuilder()
.setMaxLines(22222) // Overrides
.setMinHeight(33333) // Not an override
.setFont(Font.newBuilder().setSize(13))
.setBackground(
Fill.newBuilder()
.setLinearGradient(LinearGradient.newBuilder().setDirectionDeg(321)))
.setStyleId(styleId2)
.build();
StyleIdsStack twoStyles =
StyleIdsStack.newBuilder().addStyleIds(styleId1).addStyleIds(styleId2).build();
Frame frame =
Frame.newBuilder()
.setStylesheets(Stylesheets.newBuilder().addStylesheetIds(STYLESHEET_ID))
.setStyleReferences(twoStyles)
.build();
pietSharedStates.add(
PietSharedState.newBuilder()
.addStylesheets(
Stylesheet.newBuilder()
.setStylesheetId(STYLESHEET_ID)
.addStyles(style1)
.addStyles(style2)
.build())
.build());
FrameContext frameContext = makeFrameContextFromFrame(frame);
StyleProvider defaultFrameStyle = frameContext.makeStyleFor(twoStyles);
assertThat(defaultFrameStyle.getColor()).isEqualTo(12345);
assertThat(defaultFrameStyle.getMaxLines()).isEqualTo(22222);
assertThat(defaultFrameStyle.getMinHeight()).isEqualTo(33333);
assertThat(defaultFrameStyle.getFont())
.isEqualTo(Font.newBuilder().setSize(13).setWeight(FontWeight.MEDIUM).build());
assertThat(defaultFrameStyle.getBackground())
.isEqualTo(
Fill.newBuilder()
.setLinearGradient(
LinearGradient.newBuilder()
.addStops(ColorStop.newBuilder().setColor(1234))
.setDirectionDeg(321))
.build());
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
// Frame's styles don't affect the childrens' styles.
assertThat(frameContext.makeStyleFor(StyleIdsStack.getDefaultInstance()))
.isEqualTo(defaultStyleProvider);
assertThat(frameContext.getDebugLogger().getMessages(MessageType.ERROR)).isEmpty();
}
@Test
public void testGetMediaQueryStylesheets() {
String noMediaQueryStylesheetId = "noMediaQueries";
Stylesheet noMediaQueryStylesheet =
Stylesheet.newBuilder().setStylesheetId(noMediaQueryStylesheetId).build();
String mediaQueryStylesheetId = "mediaQueries";
Stylesheet mediaQueryStylesheet =
Stylesheet.newBuilder()
.setStylesheetId(mediaQueryStylesheetId)
.addConditions(
MediaQueryCondition.newBuilder()
.setFrameWidth(
FrameWidthCondition.newBuilder()
.setWidth(0)
.setCondition(ComparisonCondition.GREATER_THAN)))
.build();
pietSharedStates.add(
PietSharedState.newBuilder()
.addStylesheets(mediaQueryStylesheet)
.addStylesheets(noMediaQueryStylesheet)
.build());
FrameContext frameContext = defaultFrameContext();
Template inlineStylesheetTemplate =
Template.newBuilder()
.setStylesheets(
Stylesheets.newBuilder()
.addStylesheets(Stylesheet.newBuilder().setStylesheetId("inline")))
.build();
assertThat(frameContext.getMediaQueryStylesheets(inlineStylesheetTemplate)).isEmpty();
Template notFoundStylesheetTemplate = Template.newBuilder().setStylesheetId("NotFound").build();
assertThat(frameContext.getMediaQueryStylesheets(notFoundStylesheetTemplate)).isEmpty();
Template noConditionsTemplate =
Template.newBuilder()
.setStylesheets(Stylesheets.newBuilder().addStylesheetIds(noMediaQueryStylesheetId))
.build();
assertThat(frameContext.getMediaQueryStylesheets(noConditionsTemplate)).isEmpty();
Template mediaQueryTemplate =
Template.newBuilder()
.setStylesheets(Stylesheets.newBuilder().addStylesheetIds(mediaQueryStylesheetId))
.build();
assertThat(frameContext.getMediaQueryStylesheets(mediaQueryTemplate))
.containsExactly(mediaQueryStylesheet);
}
@Test
public void testFilterImageSourcesByMediaQueryCondition() {
ImageSource activeSource =
ImageSource.newBuilder()
.addConditions(
MediaQueryCondition.newBuilder()
.setDarkLight(DarkLightCondition.newBuilder().setMode(DarkLightMode.DARK)))
.build();
ImageSource inactiveSource =
ImageSource.newBuilder()
.addConditions(
MediaQueryCondition.newBuilder()
.setDarkLight(DarkLightCondition.newBuilder().setMode(DarkLightMode.LIGHT)))
.build();
ImageSource sourceWithNoConditions = ImageSource.getDefaultInstance();
Image image =
Image.newBuilder()
.addSources(activeSource)
.addSources(inactiveSource)
.addSources(sourceWithNoConditions)
.build();
when(assetProvider.isDarkTheme()).thenReturn(true);
frameContext = defaultFrameContext();
Image resultImage = frameContext.filterImageSourcesByMediaQueryCondition(image);
assertThat(resultImage.getSourcesList()).containsExactly(activeSource, sourceWithNoConditions);
}
private FrameContext defaultFrameContext() {
return makeFrameContextForDefaultFrame();
}
private FrameContext makeFrameContextForDefaultFrame() {
return new FrameContext(
DEFAULT_FRAME,
defaultStylesheet,
pietSharedStates,
newPietStylesHelper(),
DebugBehavior.VERBOSE,
debugLogger,
actionHandler,
hostProviders,
frameView);
}
private FrameContext makeFrameContextWithBinding(BindingValue bindingValue) {
Map<String, BindingValue> bindingValueMap = new HashMap<>();
bindingValueMap.put(bindingValue.getBindingId(), bindingValue);
return new FrameContext(
DEFAULT_FRAME,
defaultStylesheet,
bindingValueMap,
pietSharedStates,
pietStylesHelper,
DebugBehavior.VERBOSE,
debugLogger,
actionHandler,
hostProviders,
DEFAULT_TEMPLATES,
frameView);
}
private FrameContext makeFrameContextWithNoBindings() {
Map<String, BindingValue> bindingValueMap = new HashMap<>();
bindingValueMap.put(BINDING_ID, BindingValue.getDefaultInstance());
return new FrameContext(
DEFAULT_FRAME,
defaultStylesheet,
bindingValueMap,
pietSharedStates,
pietStylesHelper,
DebugBehavior.VERBOSE,
debugLogger,
actionHandler,
hostProviders,
DEFAULT_TEMPLATES,
frameView);
}
private FrameContext makeFrameContextFromFrame(Frame frame) {
return FrameContext.createFrameContext(
frame,
pietSharedStates,
newPietStylesHelper(),
DebugBehavior.VERBOSE,
debugLogger,
actionHandler,
hostProviders,
frameView);
}
private void setUpPietSharedStates() {
pietSharedStates.add(
PietSharedState.newBuilder()
.addStylesheets(
Stylesheet.newBuilder().setStylesheetId(STYLESHEET_ID).addStyles(SAMPLE_STYLE))
.build());
}
private Frame getWorkingFrame() {
setUpPietSharedStates();
return getBaseFrame();
}
private Frame getBaseFrame() {
return Frame.newBuilder()
.setStylesheets(Stylesheets.newBuilder().addStylesheetIds(STYLESHEET_ID))
.setStyleReferences(SAMPLE_STYLE_IDS)
.build();
}
private BindingValue.Builder defaultBinding() {
return BindingValue.newBuilder().setBindingId(BINDING_ID);
}
private PietStylesHelper newPietStylesHelper() {
return new PietStylesHelperFactory()
.get(pietSharedStates, new MediaQueryHelper(FRAME_WIDTH_PX, assetProvider, context));
}
}