| /* |
| * Copyright 2013 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.gwt.dev.jjs.impl.codesplitter; |
| |
| import com.google.gwt.dev.jjs.SourceOrigin; |
| import com.google.gwt.dev.jjs.ast.JNullLiteral; |
| import com.google.gwt.dev.jjs.ast.JRunAsync; |
| import com.google.gwt.thirdparty.guava.common.collect.Lists; |
| |
| import junit.framework.TestCase; |
| |
| import java.util.List; |
| |
| /** |
| * Tests {@link FragmentPartitioningResult#getCommonAncestorFragmentId(int, int)}. |
| */ |
| public class FragmentPartitioningResultTest extends TestCase { |
| |
| private final int NUM_RUNASYNCS = 10; |
| private final JRunAsync[] runAsyncs = new JRunAsync[NUM_RUNASYNCS + 1]; |
| |
| @Override |
| public void setUp() { |
| // Create some runAsyncs. |
| for (int i = 1; i <= NUM_RUNASYNCS; i++) { |
| runAsyncs[i] = new JRunAsync(SourceOrigin.UNKNOWN, i, "runAsync" + i, false, |
| JNullLiteral.INSTANCE, JNullLiteral.INSTANCE); |
| } |
| } |
| |
| public void testBasics() { |
| // TODO(rluble): replace all this setup with mocks once mockito is in. |
| |
| // Begin setup |
| List<JRunAsync> initialSequence = Lists.newArrayList(runAsyncs[4], runAsyncs[3], runAsyncs[2]); |
| |
| List<Fragment> fragments = Lists.newArrayList(); |
| // Create fragment 0 that is not associated with any runAsync and represent the code live |
| // from the entry point. |
| Fragment entryFragment = new Fragment(Fragment.Type.INITIAL); |
| entryFragment.setFragmentId(0); |
| fragments.add(entryFragment); |
| Fragment lastInitialFragment = entryFragment; |
| int nextId = 1; |
| for (JRunAsync runAsync : initialSequence) { |
| Fragment initialFragment = new Fragment(Fragment.Type.INITIAL, lastInitialFragment); |
| initialFragment.addRunAsync(runAsync); |
| initialFragment.setFragmentId(nextId++); |
| lastInitialFragment = initialFragment; |
| fragments.add(initialFragment); |
| } |
| |
| // create leftover fragment |
| final int LEFTOVERS_ID = NUM_RUNASYNCS + 1; |
| Fragment leftoversFragment = new Fragment(Fragment.Type.NOT_EXCLUSIVE, lastInitialFragment); |
| leftoversFragment.setFragmentId(LEFTOVERS_ID); |
| |
| // Create exclusive fragments. |
| for (JRunAsync runAsync : runAsyncs) { |
| if (runAsync == null || initialSequence.contains(runAsync)) { |
| continue; |
| } |
| Fragment exclusiveFragment = new Fragment(Fragment.Type.EXCLUSIVE, leftoversFragment); |
| exclusiveFragment.addRunAsync(runAsync); |
| assert nextId < LEFTOVERS_ID; |
| exclusiveFragment.setFragmentId(nextId++); |
| fragments.add(exclusiveFragment); |
| } |
| |
| // leftover fragment is the last one. |
| // TODO(rluble): make fragment numbering independent to the load partial ordering. |
| fragments.add(leftoversFragment); |
| |
| // End setup. |
| |
| FragmentPartitioningResult fragmentPartitioningResult = |
| new FragmentPartitioningResult(fragments, NUM_RUNASYNCS); |
| |
| // The closest common ancestor is itself. |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(0, 0)); |
| assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(1, 1)); |
| assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 3)); |
| assertEquals(6, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 6)); |
| assertEquals(11, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 11)); |
| |
| // Lowest number in the initial sequence is the closest common ancestor. |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 0)); |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(10, 0)); |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 0)); |
| |
| // Initial sequence fragments load before all others |
| assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 10)); |
| assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(10, 3)); |
| |
| // Earlier initial sequence fragments load before the others |
| assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(1, 2)); |
| assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(2, 1)); |
| assertEquals(2, fragmentPartitioningResult.getCommonAncestorFragmentId(2, 3)); |
| |
| // For non-equal exclusive fragments, leftovers is the common predecessor |
| assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 8)); |
| assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(9, 8)); |
| |
| // Leftovers is before any exclusive |
| assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 8)); |
| |
| // Inintial are before leftover |
| assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 1)); |
| } |
| |
| |
| public void testWithEmptyInitial() { |
| // TODO(rluble): replace all this setup with mocks once mockito is in. |
| |
| // Begin setup |
| List<Fragment> fragments = Lists.newArrayList(); |
| // Create fragment 0 that is not associated with any runAsync and represent the code live |
| // from the entry point. |
| Fragment entryFragment = new Fragment(Fragment.Type.INITIAL); |
| entryFragment.setFragmentId(0); |
| fragments.add(entryFragment); |
| Fragment lastInitialFragment = entryFragment; |
| int nextId = 1; |
| |
| // create leftover fragment |
| final int LEFTOVERS_ID = NUM_RUNASYNCS + 1; |
| Fragment leftoversFragment = new Fragment(Fragment.Type.NOT_EXCLUSIVE, lastInitialFragment); |
| leftoversFragment.setFragmentId(LEFTOVERS_ID); |
| |
| // Create exclusive fragments. |
| for (JRunAsync runAsync : runAsyncs) { |
| if (runAsync == null) { |
| continue; |
| } |
| Fragment exclusiveFragment = new Fragment(Fragment.Type.EXCLUSIVE, leftoversFragment); |
| exclusiveFragment.addRunAsync(runAsync); |
| assert nextId < LEFTOVERS_ID; |
| exclusiveFragment.setFragmentId(nextId++); |
| fragments.add(exclusiveFragment); |
| } |
| |
| // leftover fragment is the last one. |
| // TODO(rluble): make fragment numbering independent to the load partial ordering. |
| fragments.add(leftoversFragment); |
| |
| // End setup. |
| |
| FragmentPartitioningResult fragmentPartitioningResult = |
| new FragmentPartitioningResult(fragments, NUM_RUNASYNCS); |
| |
| // The closest common ancestor is itself. |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(0, 0)); |
| assertEquals(1, fragmentPartitioningResult.getCommonAncestorFragmentId(1, 1)); |
| assertEquals(3, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 3)); |
| assertEquals(6, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 6)); |
| assertEquals(11, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 11)); |
| |
| // Lowest number in the initial sequence is the closest common ancestor. |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(11, 0)); |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(10, 0)); |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(3, 0)); |
| |
| // For non-equal exclusive fragments, leftovers is the common predecessor |
| assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(6, 8)); |
| assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(9, 8)); |
| |
| // Leftovers is before any exclusive |
| assertEquals(LEFTOVERS_ID, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 8)); |
| |
| // Inintial are before leftover |
| assertEquals(0, fragmentPartitioningResult.getCommonAncestorFragmentId(LEFTOVERS_ID, 0)); |
| } |
| } |