/* * Copyright 2013-present Facebook, 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.facebook.buck.android; import static org.junit.Assert.assertEquals; import com.facebook.buck.android.StringResources.Gender; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.EnumMap; import java.util.TreeMap; import org.junit.Test; public class StringResourcesTest { private static final EnumMap<Gender, String> genderStrings1 = Maps.newEnumMap(Gender.class); private static final EnumMap<Gender, String> genderStrings2 = Maps.newEnumMap(Gender.class); private static final EnumMap<Gender, String> genderStrings3 = Maps.newEnumMap(Gender.class); private static final EnumMap<Gender, ImmutableMap<String, String>> genderPluralMap1 = Maps.newEnumMap(Gender.class); private static final EnumMap<Gender, ImmutableMap<String, String>> genderPluralMap2 = Maps.newEnumMap(Gender.class); private static final EnumMap<Gender, ImmutableList<String>> genderArray1 = Maps.newEnumMap(Gender.class); private static final EnumMap<Gender, ImmutableList<String>> genderArray2 = Maps.newEnumMap(Gender.class); static { genderStrings1.put(Gender.unknown, "S_one"); genderStrings1.put(Gender.female, "S_one_female"); genderStrings2.put(Gender.unknown, "S_two"); genderStrings3.put(Gender.unknown, "S_ne"); genderStrings3.put(Gender.female, "\\\"S_three\\\""); // populate first gender plural map genderPluralMap1.put( Gender.unknown, ImmutableMap.of( "one", "P1_one", "few", "P1_few", "many", "P1_many")); genderPluralMap1.put( Gender.female, ImmutableMap.of( "one", "P1_one_f1", "few", "P1_few_f1", "many", "P1_many_f1")); genderPluralMap1.put( Gender.male, ImmutableMap.of( "one", "P1_one_m2", "few", "P1_few_m2", "many", "P1_many_m2")); // populate second gender plural map genderPluralMap2.put( Gender.unknown, ImmutableMap.of( "zero", "P2_zero", "two", "P2_two", "other", "P2_other")); genderPluralMap2.put( Gender.female, ImmutableMap.of( "zero", "P2_zero_f1", "two", "P2_two_f1", "other", "P2_other_f1")); // populate gender arrays genderArray1.put(Gender.unknown, ImmutableList.of("A1_one", "A1_two")); genderArray1.put(Gender.female, ImmutableList.of("A1_one_f1", "A1_two_f1")); genderArray1.put(Gender.male, ImmutableList.of("A1_one_m2", "A1_two_m2")); genderArray2.put(Gender.unknown, ImmutableList.of("A2_one")); genderArray2.put(Gender.male, ImmutableList.of("A2_one_m2")); } private static final ImmutableMap<Integer, EnumMap<Gender, String>> strings = ImmutableMap.of( 12345678, genderStrings1, 12345679, genderStrings2, 12345680, genderStrings3); private static final ImmutableMap<Integer, EnumMap<Gender, ImmutableMap<String, String>>> plurals = ImmutableMap.of( 12345689, genderPluralMap1, 12345692, genderPluralMap2); private static final ImmutableMap<Integer, EnumMap<Gender, ImmutableList<String>>> arrays = ImmutableMap.of( 12345694, genderArray1, 12345699, genderArray2); @Test public void testBinaryStream() throws IOException { TreeMap<Integer, EnumMap<Gender, String>> stringsMap = new TreeMap<>(); stringsMap.putAll(strings); TreeMap<Integer, EnumMap<Gender, ImmutableMap<String, String>>> pluralsMap = new TreeMap<>(); pluralsMap.putAll(plurals); TreeMap<Integer, EnumMap<Gender, ImmutableList<String>>> arraysMap = new TreeMap<>(); arraysMap.putAll(arrays); byte[] binaryOutput = new StringResources(stringsMap, pluralsMap, arraysMap).getBinaryFileContent(); verifyBinaryStream(binaryOutput); } @Test public void testUnescapesQuotesAndApostrophes() { assertEquals("Test", new String(StringResources.getUnescapedStringBytes("Test"))); assertEquals( "\"testing\"", new String(StringResources.getUnescapedStringBytes("\\\"testing\\\""))); assertEquals( "On a friend's timeline", new String(StringResources.getUnescapedStringBytes("On a friend\\'s timeline"))); } private void verifyBinaryStream(byte[] binaryOutput) throws IOException { DataInputStream stream = new DataInputStream(new ByteArrayInputStream(binaryOutput)); // Version assertEquals(2, stream.readInt()); // Strings assertEquals(3, stream.readInt()); // number of strings assertEquals(12345678, stream.readInt()); // res id of first string assertEquals(0, stream.readShort()); // delta of id for first element assertEquals(2, stream.readByte()); // number of genders assertEquals(0, stream.readByte()); // ordinal of the gender enum for first string assertEquals(5, stream.readShort()); // length of first string of first element assertEquals(1, stream.readByte()); // ordinal of the gender enum for the second string assertEquals(12, stream.readShort()); // length of second string of first element assertEquals(1, stream.readShort()); // delta for second element assertEquals(1, stream.readByte()); // number of genders assertEquals(0, stream.readByte()); // ordinal of the gender enum for first string assertEquals(5, stream.readShort()); // length of first string assertEquals(1, stream.readShort()); // delta for third element assertEquals(2, stream.readByte()); // number of genders assertEquals(0, stream.readByte()); // ordinal of the gender enum for first string assertEquals(4, stream.readShort()); // length of first string of first element assertEquals(1, stream.readByte()); // ordinal of the gender enum for the second string assertEquals(9, stream.readShort()); // length of second string of first element // string values assertEquals("S_one", readStringOfLength(stream, 5)); assertEquals("S_one_female", readStringOfLength(stream, 12)); assertEquals("S_two", readStringOfLength(stream, 5)); assertEquals("S_ne", readStringOfLength(stream, 4)); assertEquals("\"S_three\"", readStringOfLength(stream, 9)); // string should be unescaped. // Plurals assertEquals(2, stream.readInt()); // number of plurals assertEquals(12345689, stream.readInt()); // res Id of the first string assertEquals(0, stream.readShort()); // delta of id for first element assertEquals(3, stream.readByte()); // number of genders assertEquals(0, stream.readByte()); // ordinal of the gender enum for first string assertEquals(3, stream.readByte()); // number of categories. assertEquals(1, stream.readByte()); // plural key mapped value of first item assertEquals(6, stream.readShort()); // length of first item assertEquals(3, stream.readByte()); // plural key mapped value of second item assertEquals(6, stream.readShort()); // length of second item assertEquals(4, stream.readByte()); // plural key mapped value of third item assertEquals(7, stream.readShort()); // length of third item assertEquals(1, stream.readByte()); // ordinal of the gender enum for first string assertEquals(3, stream.readByte()); // number of categories. assertEquals(1, stream.readByte()); // plural key mapped value of first item assertEquals(9, stream.readShort()); // length of first item assertEquals(3, stream.readByte()); // plural key mapped value of second item assertEquals(9, stream.readShort()); // length of second item assertEquals(4, stream.readByte()); // plural key mapped value of third item assertEquals(10, stream.readShort()); // length of third item assertEquals(2, stream.readByte()); // ordinal of the gender enum for first plural assertEquals(3, stream.readByte()); // number of categories. assertEquals(1, stream.readByte()); // plural key mapped value of first item assertEquals(9, stream.readShort()); // length of first item assertEquals(3, stream.readByte()); // plural key mapped value of second item assertEquals(9, stream.readShort()); // length of second item assertEquals(4, stream.readByte()); // plural key mapped value of third item assertEquals(10, stream.readShort()); // length of third item assertEquals(3, stream.readShort()); // delta of id for the second plural assertEquals(2, stream.readByte()); // number of genders assertEquals(0, stream.readByte()); // ordinal of the gender enum for first plural assertEquals(3, stream.readByte()); // number of categories. assertEquals(0, stream.readByte()); // plural key mapped value of first item assertEquals(7, stream.readShort()); // length of first item assertEquals(2, stream.readByte()); // plural key mapped value of second item assertEquals(6, stream.readShort()); // length of second item assertEquals(5, stream.readByte()); // plural key mapped value of third item assertEquals(8, stream.readShort()); // length of third item assertEquals(1, stream.readByte()); // ordinal of the gender enum for first plural assertEquals(3, stream.readByte()); // number of categories. assertEquals(0, stream.readByte()); // plural key mapped value of first item assertEquals(10, stream.readShort()); // length of first item assertEquals(2, stream.readByte()); // plural key mapped value of second item assertEquals(9, stream.readShort()); // length of second item assertEquals(5, stream.readByte()); // plural key mapped value of third item assertEquals(11, stream.readShort()); // length of third item // plural strings assertEquals("P1_one", readStringOfLength(stream, 6)); assertEquals("P1_few", readStringOfLength(stream, 6)); assertEquals("P1_many", readStringOfLength(stream, 7)); assertEquals("P1_one_f1", readStringOfLength(stream, 9)); assertEquals("P1_few_f1", readStringOfLength(stream, 9)); assertEquals("P1_many_f1", readStringOfLength(stream, 10)); assertEquals("P1_one_m2", readStringOfLength(stream, 9)); assertEquals("P1_few_m2", readStringOfLength(stream, 9)); assertEquals("P1_many_m2", readStringOfLength(stream, 10)); assertEquals("P2_zero", readStringOfLength(stream, 7)); assertEquals("P2_two", readStringOfLength(stream, 6)); assertEquals("P2_other", readStringOfLength(stream, 8)); assertEquals("P2_zero_f1", readStringOfLength(stream, 10)); assertEquals("P2_two_f1", readStringOfLength(stream, 9)); assertEquals("P2_other_f1", readStringOfLength(stream, 11)); // Arrays assertEquals(2, stream.readInt()); // number of arrays assertEquals(12345694, stream.readInt()); // res Id of the first string assertEquals(0, stream.readShort()); // delta of id for first element assertEquals(3, stream.readByte()); // number of genders assertEquals(0, stream.readByte()); // ordinal of the gender enum for first array assertEquals(2, stream.readByte()); // number of array elements. assertEquals(6, stream.readShort()); // length of first item assertEquals(6, stream.readShort()); // length of second item assertEquals(1, stream.readByte()); // ordinal of the gender enum for second array assertEquals(2, stream.readByte()); // number of array elements. assertEquals(9, stream.readShort()); // length of first item assertEquals(9, stream.readShort()); // length of second item assertEquals(2, stream.readByte()); // ordinal of the gender enum for third array assertEquals(2, stream.readByte()); // number of array elements. assertEquals(9, stream.readShort()); // length of first item assertEquals(9, stream.readShort()); // length of second item assertEquals(5, stream.readShort()); // delta of id for second element assertEquals(2, stream.readByte()); // number of genders assertEquals(0, stream.readByte()); // ordinal of the gender enum for first array assertEquals(1, stream.readByte()); // number of array elements. assertEquals(6, stream.readShort()); // length of first item assertEquals(2, stream.readByte()); // ordinal of the gender enum for second array assertEquals(1, stream.readByte()); // number of array elements. assertEquals(9, stream.readShort()); // length of first item // array strings assertEquals("A1_one", readStringOfLength(stream, 6)); assertEquals("A1_two", readStringOfLength(stream, 6)); assertEquals("A1_one_f1", readStringOfLength(stream, 9)); assertEquals("A1_two_f1", readStringOfLength(stream, 9)); assertEquals("A1_one_m2", readStringOfLength(stream, 9)); assertEquals("A1_two_m2", readStringOfLength(stream, 9)); assertEquals("A2_one", readStringOfLength(stream, 6)); assertEquals("A2_one_m2", readStringOfLength(stream, 9)); } private String readStringOfLength(DataInputStream stream, int length) throws IOException { byte[] data = new byte[length]; assertEquals(length, stream.read(data, 0, length)); return new String(data); } }