1 /* 2 * Copyright (C) 2017 The Libphonenumber Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.i18n.phonenumbers.metadata.table; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import com.google.common.collect.ImmutableList; 21 import com.google.common.collect.ImmutableSet; 22 import com.google.i18n.phonenumbers.metadata.DigitSequence; 23 import com.google.i18n.phonenumbers.metadata.PrefixTree; 24 import com.google.i18n.phonenumbers.metadata.RangeSpecification; 25 import com.google.i18n.phonenumbers.metadata.RangeTree; 26 import java.util.stream.Stream; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.junit.runners.JUnit4; 30 31 @RunWith(JUnit4.class) 32 public class RangeKeyTest { 33 @Test testEmpty()34 public void testEmpty() { 35 ImmutableList<RangeKey> keys = RangeKey.decompose(RangeTree.empty()); 36 assertThat(keys).isEmpty(); 37 } 38 39 @Test testZeroLengthMatch()40 public void testZeroLengthMatch() { 41 ImmutableList<RangeKey> keys = RangeKey.decompose(RangeTree.from(RangeSpecification.empty())); 42 assertThat(keys).containsExactly(key("", 0)); 43 } 44 45 @Test testOnlyAnyPath()46 public void testOnlyAnyPath() { 47 ImmutableList<RangeKey> keys = RangeKey.decompose(ranges("xxx", "xxxx", "xxxxx")); 48 assertThat(keys).containsExactly(key("", 3, 4, 5)); 49 } 50 51 @Test testSimple()52 public void testSimple() { 53 ImmutableList<RangeKey> keys = RangeKey.decompose(ranges("123xxx", "123xxxx", "123xxxxx")); 54 assertThat(keys).containsExactly(key("123", 6, 7, 8)); 55 } 56 57 @Test testEmbeddedRanges()58 public void testEmbeddedRanges() { 59 ImmutableList<RangeKey> keys = 60 RangeKey.decompose(ranges("1x", "1xx", "1xx23", "1xx23x", "1xx23xx")); 61 assertThat(keys).containsExactly(key("1", 2, 3), key("1xx23", 5, 6, 7)).inOrder(); 62 } 63 64 @Test testSplitFactors()65 public void testSplitFactors() { 66 ImmutableList<RangeKey> keys = RangeKey.decompose(ranges("123xxxx", "1234x", "1234xx")); 67 // If the input wasn't "factored" first, this would result in: 68 // key("123[0-35-9]", 7), key("1234", 5, 6, 7) 69 assertThat(keys).containsExactly(key("123", 7), key("1234", 5, 6)).inOrder(); 70 } 71 72 @Test testMergeStrategy()73 public void testMergeStrategy() { 74 ImmutableList<RangeKey> keys = RangeKey.decompose(ranges("12[0-4]xxx", "12xxx", "12xx")); 75 // The merge strategy for factorizing the tree will prefer to keep the longer paths intact 76 // and split shorter paths around it. Using the other strategy we would get: 77 // key("12", 4, 5), key("12[0-4]", 6) 78 assertThat(keys).containsExactly(key("12[0-4]", 4, 5, 6), key("12[5-9]", 4, 5)).inOrder(); 79 } 80 81 @Test testAsRangeSpecifications()82 public void testAsRangeSpecifications() { 83 assertThat(key("", 3, 4, 5).asRangeSpecifications()) 84 .containsExactly(spec("xxx"), spec("xxxx"), spec("xxxxx")).inOrder(); 85 assertThat(key("1[2-4]", 3, 4, 5).asRangeSpecifications()) 86 .containsExactly(spec("1[2-4]x"), spec("1[2-4]xx"), spec("1[2-4]xxx")).inOrder(); 87 assertThat(key("1x[468]", 3, 5, 7).asRangeSpecifications()) 88 .containsExactly(spec("1x[468]"), spec("1x[468]xx"), spec("1x[468]xxxx")).inOrder(); 89 } 90 91 @Test testSimpleRealWorldData()92 public void testSimpleRealWorldData() { 93 // From ITU German numbering plan, first few fixed line ranges. 94 PrefixTree prefixes = 95 PrefixTree.from(ranges("20[1-389]", "204[135]", "205[1-468]", "206[4-6]", "20[89]")); 96 RangeTree ranges = prefixes.retainFrom( 97 ranges("xxxxxx", "xxxxxxx", "xxxxxxxx", "xxxxxxxxx", "xxxxxxxxxx", "xxxxxxxxxxx")); 98 ImmutableList<RangeKey> keys = RangeKey.decompose(ranges); 99 assertThat(keys).containsExactly( 100 key("20[1-389]", 6, 7, 8, 9, 10, 11), 101 key("204[135]", 6, 7, 8, 9, 10, 11), 102 key("205[1-468]", 6, 7, 8, 9, 10, 11), 103 key("206[4-6]", 6, 7, 8, 9, 10, 11)) 104 .inOrder(); 105 } 106 107 @Test testContains()108 public void testContains() { 109 RangeKey key = key("1[23]", 7, 8, 9); 110 assertThat(key.contains(digitSequence("12"), 8)).isTrue(); 111 assertThat(key.contains(digitSequence("12"), 10)).isFalse(); 112 assertThat(key.contains(digitSequence("7"), 8)).isFalse(); 113 } 114 key(String spec, Integer... lengths)115 private static RangeKey key(String spec, Integer... lengths) { 116 RangeSpecification prefix = 117 spec.isEmpty() ? RangeSpecification.empty() : RangeSpecification.parse(spec); 118 return RangeKey.create(prefix, ImmutableSet.copyOf(lengths)); 119 } 120 ranges(String... spec)121 private static RangeTree ranges(String... spec) { 122 return RangeTree.from(Stream.of(spec).map(RangeSpecification::parse)); 123 } 124 spec(String spec)125 private static RangeSpecification spec(String spec) { 126 return RangeSpecification.parse(spec); 127 } 128 digitSequence(String spec)129 private static DigitSequence digitSequence(String spec) { 130 return DigitSequence.of(spec); 131 } 132 } 133