/* * Copyright 2014 astamuse company,Ltd. * * 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.astamuse.asta4d.render.test; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; import org.jsoup.nodes.Element; import com.astamuse.asta4d.render.AttributeSetter; import com.astamuse.asta4d.render.Renderer; import com.astamuse.asta4d.render.RendererTestHelper; import com.astamuse.asta4d.render.RendererType; import com.astamuse.asta4d.render.transformer.Transformer; import com.astamuse.asta4d.util.collection.ListConvertUtil; import com.astamuse.asta4d.util.collection.RowConvertor; public class RendererTester { private Renderer renderer; private RendererTester(Renderer renderer) { this.renderer = renderer; } public final static RendererTester forRenderer(Renderer renderer) { return new RendererTester(renderer); } public final static List<RendererTester> forRendererList(List<Renderer> rendererList) { return ListConvertUtil.transform(rendererList, new RowConvertor<Renderer, RendererTester>() { @Override public RendererTester convert(int rowIndex, Renderer obj) { return new RendererTester(obj); } }); } private List<List<Transformer<?>>> retrieveNonAttrTransformer(String selector) { List<List<Transformer<?>>> rtnList = new LinkedList<>(); List<Renderer> rendererList = renderer.asUnmodifiableList(); for (Renderer r : rendererList) { if (r.getSelector().equals(selector)) { List<Transformer<?>> list = r.getTransformerList(); if (list.isEmpty()) { rtnList.add(list); } else { Transformer<?> t = list.get(0); if (t.getContent() instanceof AttributeSetter) { continue; } else { rtnList.add(list); } } } } return rtnList; } private List<Transformer<?>> retrieveSingleTransformerListOnSelector(String selector) { List<List<Transformer<?>>> list = retrieveNonAttrTransformer(selector); if (list.isEmpty()) { throw new RendererTestException("There is no value to be rendered for selector:[" + selector + "]"); } else if (list.size() > 1) { throw new RendererTestException( "There are more than one value to be rendered for selector:[" + selector + "], maybe it is rendered multiple times?"); } else { return list.get(0); } } // following are simple render value accessores for simple test cases private Transformer<?> retrieveSingleTransformerOnSelector(String selector) { List<Transformer<?>> list = retrieveSingleTransformerListOnSelector(selector); if (list.isEmpty()) { throw new RendererTestException( "There is no value to be rendered for selector:[" + selector + "], maybe it is rendered as a empty list?"); } else if (list.size() > 1) { throw new RendererTestException( "There are more than one value to be rendered for selector:[" + selector + "], maybe it is rendered as a list?"); } else { return list.get(0); } } /** * * @return true - the current Renderer will do nothing */ public boolean noOp() { return renderer.asUnmodifiableList().size() == 1 && RendererTestHelper.getRendererType(renderer) == RendererType.GO_THROUGH; } /** * * * @param selector * @return true - there is no actual rendering operation on the given selector */ public boolean noOp(String selector) { List<List<Transformer<?>>> list = retrieveNonAttrTransformer(selector); return list.isEmpty(); } /** * * * @param selector * @param attr * @return true - there is no actual rendering operation on the given selector and attribute */ public boolean noOp(String selector, String attr) { List list = (List) getAttrAsObject(selector, attr, true, true); return list.isEmpty(); } /** * * @param selector * @return the rendered operation on given selector * @throws RendererTestException * if there is no operation or more than one operation on given selector, RendererTestException will be thrown */ @SuppressWarnings("rawtypes") public Object get(String selector) throws RendererTestException { Transformer t = retrieveSingleTransformerOnSelector(selector); Object content = retrieveTestContentFromTransformer(t); return content; } /** * * @param selector * @return the rendered operation list on given selector * @throws RendererTestException * if there is no operation on given selector, RendererTestException will be thrown */ public List<Object> getAsList(String selector) throws RendererTestException { return getAsList(selector, Object.class); } public List<RendererTester> getAsRendererTesterList(String selector) throws RendererTestException { return getAsList(selector, Renderer.class).stream().map(r -> RendererTester.forRenderer(r)).collect(Collectors.toList()); } /** * * @param selector * @param targetCls * @return the rendered operation list on given selector * @throws RendererTestException * if there is no operation on given selector, RendererTestException will be thrown */ public <T> List<T> getAsList(String selector, final Class<T> targetCls) throws RendererTestException { List<Transformer<?>> list = retrieveSingleTransformerListOnSelector(selector); return ListConvertUtil.transform(list, new RowConvertor<Transformer<?>, T>() { @SuppressWarnings("unchecked") @Override public T convert(int rowIndex, Transformer<?> transformer) { Object content = retrieveTestContentFromTransformer(transformer); return (T) content; } }); } private Object retrieveTestContentFromTransformer(Transformer<?> transformer) { Object content = null; if (transformer instanceof TestableRendering) { content = ((TestableRendering) transformer).retrieveTestableData(); } if (content != null && content instanceof TestableRendering) { content = ((TestableRendering) content).retrieveTestableData(); } if (content != null && content instanceof Element) { content = new TestableElementWrapper((Element) content); } return content; } /** * * @param selector * @param attr * @return * @throws RendererTestException * if there is no operation or more than one operation on given selector and attr, RendererTestException will be thrown */ public Object getAttr(String selector, String attr) throws RendererTestException { return getAttrAsObject(selector, attr, false, false); } /** * This method is only for retrieving rendered value of "+class" and "-class" attr action * * @param selector * @param attr * @return * @throws RendererTestException * if there is no operation on given selector and attr, RendererTestException will be thrown */ @SuppressWarnings("unchecked") public List<String> getAttrAsList(String selector, String attr) throws RendererTestException { if (attr.equals("+class") || attr.equals("-class")) { return (List<String>) getAttrAsObject(selector, attr, true, false); } else { throw new RendererTestException("This method is only for retrieving rendered value of \"+class\" and \"-class\" attr action"); } } private Object getAttrAsObject(String selector, String attr, boolean allowList, boolean allowEmpty) { List<Renderer> rendererList = renderer.asUnmodifiableList(); List<Object> valueList = new LinkedList<>(); for (Renderer r : rendererList) { if (r.getSelector().equals(selector)) { List<Transformer<?>> list = r.getTransformerList(); if (list.isEmpty()) { continue; } else { Transformer<?> t = list.get(0); if (t.getContent() instanceof AttributeSetter) { AttributeSetter setter = (AttributeSetter) t.getContent(); @SuppressWarnings("unchecked") Pair<String, Object> data = (Pair<String, Object>) setter.retrieveTestableData(); if (data.getKey().equals(attr)) { Object obj = data.getValue(); valueList.add(obj); } } else { continue; } } } } if (!allowEmpty && valueList.isEmpty()) { throw new RendererTestException("There is no value to be rendered for attr:[" + attr + "] of selector:[" + selector + "]"); } else if (valueList.size() > 1) { if (allowList) { return valueList; } else { throw new RendererTestException("There are more than one values(" + valueList.toString() + ") to be rendered for attr:[" + attr + "] of selector:[" + selector + "]"); } } else { if (allowList) { return valueList; } else { return valueList.get(0); } } } }