| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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. |
| */ |
| |
| /* $Id$ */ |
| |
| package org.apache.fop.fo.pagination; |
| |
| import org.junit.Test; |
| import org.xml.sax.Locator; |
| |
| import static org.junit.Assert.fail; |
| import static org.mockito.ArgumentMatchers.nullable; |
| import static org.mockito.Matchers.anyBoolean; |
| import static org.mockito.Matchers.anyInt; |
| import static org.mockito.Matchers.anyObject; |
| import static org.mockito.Matchers.anyString; |
| import static org.mockito.Matchers.eq; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import org.apache.fop.apps.FOPException; |
| import org.apache.fop.fo.FONode; |
| import org.apache.fop.layoutmgr.BlockLevelEventProducer; |
| |
| /** |
| * Unit Test for PageSequenceMaster |
| * |
| */ |
| public class PageSequenceMasterTestCase { |
| |
| /** |
| * Test that block level events are produced in line with |
| * XSL:FO - 6.4.8 fo:page-sequence-master - |
| * "It is an error if the entire sequence of sub-sequence-specifiers children is exhausted |
| * while some areas returned by an fo:flow are not placed. Implementations may recover, |
| * if possible, by re-using the sub-sequence-specifier that was last used to generate a page." |
| * |
| * @throws Exception exception |
| */ |
| @Test |
| public void testGetNextSimplePageMasterExhausted() throws Exception { |
| |
| //Test when the last sub-sequence specifier is not repeatable |
| testGetNextSimplePageMasterExhausted(true); |
| |
| //Test when the last sub-sequence specifier is repeatable |
| testGetNextSimplePageMasterExhausted(false); |
| |
| } |
| |
| private void testGetNextSimplePageMasterExhausted(boolean canResume) throws Exception { |
| |
| SimplePageMaster spm = mock(SimplePageMaster.class); |
| SubSequenceSpecifier mockSinglePageMasterReference |
| = mock(SubSequenceSpecifier.class); |
| BlockLevelEventProducer mockBlockLevelEventProducer = mock(BlockLevelEventProducer.class); |
| |
| // subject under test |
| PageSequenceMaster pageSequenceMaster = createPageSequenceMaster( |
| mockBlockLevelEventProducer); |
| pageSequenceMaster.addSubsequenceSpecifier(mockSinglePageMasterReference); |
| |
| //Setup to mock the exhaustion of the last sub-sequence specifier |
| when(mockSinglePageMasterReference.getNextPageMaster(anyBoolean(), anyBoolean(), |
| anyBoolean(), anyBoolean())).thenReturn(null, spm); |
| |
| //Need this for the method to return normally |
| when(mockSinglePageMasterReference.canProcess(nullable(String.class))).thenReturn(true); |
| |
| when(mockSinglePageMasterReference.isReusable()).thenReturn(canResume); |
| |
| pageSequenceMaster.getNextSimplePageMaster(false, false, false, false, null); |
| |
| verify(mockBlockLevelEventProducer).pageSequenceMasterExhausted((Locator)anyObject(), |
| nullable(String.class), eq(canResume), (Locator)anyObject()); |
| } |
| |
| /** |
| * Test that PageProductionException is thrown if the final simple-page-master |
| * cannot handle the main-flow of the page sequence |
| * @throws Exception exception |
| */ |
| @Test |
| public void testGetNextSimplePageMasterException() throws Exception { |
| |
| final String mainFlowRegionName = "main"; |
| final String emptyFlowRegionName = "empty"; |
| |
| // This will represent a page master that does not map to the main flow |
| // of the page sequence |
| SimplePageMaster mockEmptySPM = mock(SimplePageMaster.class); |
| Region mockRegion = mock(Region.class); |
| SinglePageMasterReference mockSinglePageMasterReference |
| = mock(SinglePageMasterReference.class); |
| BlockLevelEventProducer mockBlockLevelEventProducer = mock(BlockLevelEventProducer.class); |
| |
| LayoutMasterSet mockLayoutMasterSet = mock(LayoutMasterSet.class); |
| //The layout master set should return the empty page master |
| when(mockLayoutMasterSet.getSimplePageMaster(anyString())).thenReturn(mockEmptySPM); |
| when(mockEmptySPM.getRegion(anyInt())).thenReturn(mockRegion); |
| |
| when(mockRegion.getRegionName()).thenReturn(emptyFlowRegionName); |
| |
| when(mockSinglePageMasterReference.getNextPageMaster(anyBoolean(), anyBoolean(), |
| anyBoolean(), anyBoolean())) |
| .thenReturn(null, mockEmptySPM); |
| |
| PageSequenceMaster pageSequenceMaster = createPageSequenceMaster(mockLayoutMasterSet, |
| mockBlockLevelEventProducer); |
| |
| pageSequenceMaster.startOfNode(); |
| pageSequenceMaster.addSubsequenceSpecifier(mockSinglePageMasterReference); |
| |
| try { |
| pageSequenceMaster.getNextSimplePageMaster(false, false, false, false, |
| mainFlowRegionName); |
| fail("The next simple page master does not refer to the main flow"); |
| } catch (PageProductionException ppe) { |
| //Passed test |
| } |
| } |
| |
| |
| private PageSequenceMaster createPageSequenceMaster( |
| BlockLevelEventProducer blockLevelEventProducer) throws FOPException { |
| |
| return createPageSequenceMaster(mock(LayoutMasterSet.class), blockLevelEventProducer); |
| } |
| |
| private PageSequenceMaster createPageSequenceMaster(LayoutMasterSet layoutMasterSet, |
| BlockLevelEventProducer blockLevelEventProducer) throws FOPException { |
| FONode mockParent = mock(FONode.class); |
| Root mockRoot = mock(Root.class); |
| |
| //Stub generic components |
| when(mockParent.getRoot()).thenReturn(mockRoot); |
| when(mockRoot.getLayoutMasterSet()).thenReturn(layoutMasterSet); |
| |
| PageSequenceMaster psm = new PageSequenceMaster(mockParent, blockLevelEventProducer); |
| psm.startOfNode(); |
| |
| return psm; |
| } |
| |
| } |
| |