| // Copyright 2012 The Closure Library Authors. All Rights Reserved. |
| // |
| // 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. |
| |
| /** |
| * @fileoverview Unit tests for goog.proto2.TextFormatSerializer. |
| * |
| */ |
| |
| /** @suppress {extraProvide} */ |
| goog.provide('goog.proto2.TextFormatSerializerTest'); |
| |
| goog.require('goog.proto2.ObjectSerializer'); |
| goog.require('goog.proto2.TextFormatSerializer'); |
| goog.require('goog.testing.jsunit'); |
| goog.require('proto2.TestAllTypes'); |
| |
| goog.setTestOnly('goog.proto2.TextFormatSerializerTest'); |
| |
| function testSerialization() { |
| var message = new proto2.TestAllTypes(); |
| |
| // Set the fields. |
| // Singular. |
| message.setOptionalInt32(101); |
| message.setOptionalUint32(103); |
| message.setOptionalSint32(105); |
| message.setOptionalFixed32(107); |
| message.setOptionalSfixed32(109); |
| message.setOptionalInt64('102'); |
| message.setOptionalFloat(111.5); |
| message.setOptionalDouble(112.5); |
| message.setOptionalBool(true); |
| message.setOptionalString('test'); |
| message.setOptionalBytes('abcd'); |
| |
| var group = new proto2.TestAllTypes.OptionalGroup(); |
| group.setA(111); |
| |
| message.setOptionalgroup(group); |
| |
| var nestedMessage = new proto2.TestAllTypes.NestedMessage(); |
| nestedMessage.setB(112); |
| |
| message.setOptionalNestedMessage(nestedMessage); |
| |
| message.setOptionalNestedEnum(proto2.TestAllTypes.NestedEnum.FOO); |
| |
| // Repeated. |
| message.addRepeatedInt32(201); |
| message.addRepeatedInt32(202); |
| |
| // Serialize to a simplified text format. |
| var simplified = new goog.proto2.TextFormatSerializer().serialize(message); |
| var expected = 'optional_int32: 101\n' + |
| 'optional_int64: 102\n' + |
| 'optional_uint32: 103\n' + |
| 'optional_sint32: 105\n' + |
| 'optional_fixed32: 107\n' + |
| 'optional_sfixed32: 109\n' + |
| 'optional_float: 111.5\n' + |
| 'optional_double: 112.5\n' + |
| 'optional_bool: true\n' + |
| 'optional_string: "test"\n' + |
| 'optional_bytes: "abcd"\n' + |
| 'optionalgroup {\n' + |
| ' a: 111\n' + |
| '}\n' + |
| 'optional_nested_message {\n' + |
| ' b: 112\n' + |
| '}\n' + |
| 'optional_nested_enum: FOO\n' + |
| 'repeated_int32: 201\n' + |
| 'repeated_int32: 202\n'; |
| |
| assertEquals(expected, simplified); |
| } |
| |
| function testSerializationOfUnknown() { |
| var nestedUnknown = new proto2.TestAllTypes(); |
| var message = new proto2.TestAllTypes(); |
| |
| // Set the fields. |
| // Known. |
| message.setOptionalInt32(101); |
| message.addRepeatedInt32(201); |
| message.addRepeatedInt32(202); |
| |
| nestedUnknown.addRepeatedInt32(301); |
| nestedUnknown.addRepeatedInt32(302); |
| |
| // Unknown. |
| message.setUnknown(1000, 301); |
| message.setUnknown(1001, 302); |
| message.setUnknown(1002, 'hello world'); |
| message.setUnknown(1002, nestedUnknown); |
| |
| nestedUnknown.setUnknown(2000, 401); |
| |
| // Serialize. |
| var simplified = new goog.proto2.TextFormatSerializer().serialize(message); |
| var expected = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'repeated_int32: 202\n' + |
| '1000: 301\n' + |
| '1001: 302\n' + |
| '1002 {\n' + |
| ' repeated_int32: 301\n' + |
| ' repeated_int32: 302\n' + |
| ' 2000: 401\n' + |
| '}\n'; |
| |
| assertEquals(expected, simplified); |
| } |
| |
| function testSerializationOfUnknownParsedFromObject() { |
| // Construct the object-serialized representation of the message constructed |
| // programmatically in the test above. |
| var serialized = { |
| 1: 101, |
| 31: [201, 202], |
| 1000: 301, |
| 1001: 302, |
| 1002: { |
| 31: [301, 302], |
| 2000: 401 |
| } |
| }; |
| |
| // Deserialize that representation into a TestAllTypes message. |
| var objectSerializer = new goog.proto2.ObjectSerializer(); |
| var message = new proto2.TestAllTypes(); |
| objectSerializer.deserializeTo(message, serialized); |
| |
| // Check that the text format matches what we expect. |
| var simplified = new goog.proto2.TextFormatSerializer().serialize(message); |
| var expected = ( |
| 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'repeated_int32: 202\n' + |
| '1000: 301\n' + |
| '1001: 302\n' + |
| '1002 {\n' + |
| ' 31: 301\n' + |
| ' 31: 302\n' + |
| ' 2000: 401\n' + |
| '}\n' |
| ); |
| assertEquals(expected, simplified); |
| } |
| |
| |
| /** |
| * Asserts that the given string value parses into the given set of tokens. |
| * @param {string} value The string value to parse. |
| * @param {Array<Object> | Object} tokens The tokens to check against. If not |
| * an array, a single token is expected. |
| * @param {boolean=} opt_ignoreWhitespace Whether whitespace tokens should be |
| * skipped by the tokenizer. |
| */ |
| function assertTokens(value, tokens, opt_ignoreWhitespace) { |
| var tokenizer = new goog.proto2.TextFormatSerializer.Tokenizer_( |
| value, opt_ignoreWhitespace); |
| var tokensFound = []; |
| |
| while (tokenizer.next()) { |
| tokensFound.push(tokenizer.getCurrent()); |
| } |
| |
| if (goog.typeOf(tokens) != 'array') { |
| tokens = [tokens]; |
| } |
| |
| assertEquals(tokens.length, tokensFound.length); |
| for (var i = 0; i < tokens.length; ++i) { |
| assertToken(tokens[i], tokensFound[i]); |
| } |
| } |
| |
| function assertToken(expected, found) { |
| assertEquals(expected.type, found.type); |
| if (expected.value) { |
| assertEquals(expected.value, found.value); |
| } |
| } |
| |
| function testTokenizer() { |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens('{ 123 }', [ |
| { type: types.OPEN_BRACE }, |
| { type: types.WHITESPACE, value: ' ' }, |
| { type: types.NUMBER, value: '123' }, |
| { type: types.WHITESPACE, value: ' '}, |
| { type: types.CLOSE_BRACE } |
| ]); |
| // The c++ proto serializer might represent a float in exponential |
| // notation: |
| assertTokens('{ 1.2345e+3 }', [ |
| { type: types.OPEN_BRACE }, |
| { type: types.WHITESPACE, value: ' ' }, |
| { type: types.NUMBER, value: '1.2345e+3' }, |
| { type: types.WHITESPACE, value: ' '}, |
| { type: types.CLOSE_BRACE } |
| ]); |
| } |
| |
| function testTokenizerExponentialFloatProblem() { |
| var input = 'merchant: { # blah blah\n' + |
| ' total_price: 3.2186e+06 # 3_218_600; 3.07Mi\n' + |
| ' taxes : 2.17199e+06\n' + |
| '}'; |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens(input, [ |
| { type: types.IDENTIFIER, value: 'merchant' }, |
| { type: types.COLON, value: ':' }, |
| { type: types.OPEN_BRACE, value: '{' }, |
| { type: types.COMMENT, value: '# blah blah' }, |
| { type: types.IDENTIFIER, value: 'total_price' }, |
| { type: types.COLON, value: ':' }, |
| { type: types.NUMBER, value: '3.2186e+06' }, |
| { type: types.COMMENT, value: '# 3_218_600; 3.07Mi' }, |
| { type: types.IDENTIFIER, value: 'taxes' }, |
| { type: types.COLON, value: ':' }, |
| { type: types.NUMBER, value: '2.17199e+06' }, |
| { type: types.CLOSE_BRACE, value: '}' } |
| ], |
| true); |
| } |
| |
| function testTokenizerNoWhitespace() { |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens('{ "hello world" }', [ |
| { type: types.OPEN_BRACE }, |
| { type: types.STRING, value: '"hello world"' }, |
| { type: types.CLOSE_BRACE } |
| ], true); |
| } |
| |
| |
| function assertIdentifier(identifier) { |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens(identifier, { type: types.IDENTIFIER, value: identifier }); |
| } |
| |
| function assertComment(comment) { |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens(comment, { type: types.COMMENT, value: comment }); |
| } |
| |
| function assertString(str) { |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens(str, { type: types.STRING, value: str }); |
| } |
| |
| function assertNumber(num) { |
| num = num.toString(); |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens(num, { type: types.NUMBER, value: num }); |
| } |
| |
| function testTokenizerSingleTokens() { |
| var types = goog.proto2.TextFormatSerializer.Tokenizer_.TokenTypes; |
| assertTokens('{', { type: types.OPEN_BRACE }); |
| assertTokens('}', { type: types.CLOSE_BRACE }); |
| assertTokens('<', { type: types.OPEN_TAG }); |
| assertTokens('>', { type: types.CLOSE_TAG }); |
| assertTokens(':', { type: types.COLON }); |
| assertTokens(',', { type: types.COMMA }); |
| assertTokens(';', { type: types.SEMI }); |
| |
| assertIdentifier('abcd'); |
| assertIdentifier('Abcd'); |
| assertIdentifier('ABcd'); |
| assertIdentifier('ABcD'); |
| assertIdentifier('a123nc'); |
| assertIdentifier('a45_bC'); |
| assertIdentifier('A45_bC'); |
| |
| assertIdentifier('inf'); |
| assertIdentifier('infinity'); |
| assertIdentifier('nan'); |
| |
| assertNumber(0); |
| assertNumber(10); |
| assertNumber(123); |
| assertNumber(1234); |
| assertNumber(123.56); |
| assertNumber(-124); |
| assertNumber(-1234); |
| assertNumber(-123.56); |
| assertNumber('123f'); |
| assertNumber('123.6f'); |
| assertNumber('-123f'); |
| assertNumber('-123.8f'); |
| assertNumber('0x1234'); |
| assertNumber('0x12ac34'); |
| assertNumber('0x49e281db686fb'); |
| // Floating point numbers might be serialized in exponential |
| // notation: |
| assertNumber('1.2345e+3'); |
| assertNumber('1.2345e3'); |
| assertNumber('1.2345e-2'); |
| |
| assertString('""'); |
| assertString('"hello world"'); |
| assertString('"hello # world"'); |
| assertString('"hello #\\" world"'); |
| assertString('"|"'); |
| assertString('"\\"\\""'); |
| assertString('"\\"foo\\""'); |
| assertString('"\\"foo\\" and \\"bar\\""'); |
| assertString('"foo \\"and\\" bar"'); |
| |
| assertComment('# foo bar baz'); |
| assertComment('# foo ## bar baz'); |
| assertComment('# foo "bar" baz'); |
| } |
| |
| function testSerializationOfStringWithQuotes() { |
| var nestedUnknown = new proto2.TestAllTypes(); |
| var message = new proto2.TestAllTypes(); |
| message.setOptionalString('hello "world"'); |
| |
| // Serialize. |
| var simplified = new goog.proto2.TextFormatSerializer().serialize(message); |
| var expected = 'optional_string: "hello \\"world\\""\n'; |
| assertEquals(expected, simplified); |
| } |
| |
| function testDeserialization() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'repeated_int32: 202\n' + |
| 'optional_float: 123.4'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(202, message.getRepeatedInt32(1)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationOfList() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: [201, 202]\n' + |
| 'optional_float: 123.4'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationOfIntegerAsHexadecimalString() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 0x1\n' + |
| 'optional_sint32: 0xf\n' + |
| 'optional_uint32: 0xffffffff\n' + |
| 'repeated_int32: [0x0, 0xff]\n'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(1, message.getOptionalInt32()); |
| assertEquals(15, message.getOptionalSint32()); |
| assertEquals(4294967295, message.getOptionalUint32()); |
| assertEquals(0, message.getRepeatedInt32(0)); |
| assertEquals(255, message.getRepeatedInt32(1)); |
| } |
| |
| function testDeserializationOfInt64AsHexadecimalString() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int64: 0xf'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals('0xf', message.getOptionalInt64()); |
| } |
| |
| function testDeserializationOfZeroFalseAndEmptyString() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 0\n' + |
| 'optional_bool: false\n' + |
| 'optional_string: ""'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(0, message.getOptionalInt32()); |
| assertEquals(false, message.getOptionalBool()); |
| assertEquals('', message.getOptionalString()); |
| } |
| |
| function testDeserializationOfConcatenatedString() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 123\n' + |
| 'optional_string:\n' + |
| ' "FirstLine"\n' + |
| ' "SecondLine"\n' + |
| 'optional_float: 456.7'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(123, message.getOptionalInt32()); |
| assertEquals('FirstLineSecondLine', message.getOptionalString()); |
| assertEquals(456.7, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationSkipComment() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| '# Some comment.\n' + |
| 'repeated_int32: 202\n' + |
| 'optional_float: 123.4'; |
| |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| assertTrue(parser.parse(message, value)); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(202, message.getRepeatedInt32(1)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationSkipTrailingComment() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'repeated_int32: 202 # Some trailing comment.\n' + |
| 'optional_float: 123.4'; |
| |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| assertTrue(parser.parse(message, value)); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(202, message.getRepeatedInt32(1)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationSkipUnknown() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'some_unknown: true\n' + |
| 'repeated_int32: 202\n' + |
| 'optional_float: 123.4'; |
| |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| assertTrue(parser.parse(message, value, true)); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(202, message.getRepeatedInt32(1)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationSkipUnknownList() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'some_unknown: [true, 1, 201, "hello"]\n' + |
| 'repeated_int32: 202\n' + |
| 'optional_float: 123.4'; |
| |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| assertTrue(parser.parse(message, value, true)); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(202, message.getRepeatedInt32(1)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationSkipUnknownNested() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'some_unknown: <\n' + |
| ' a: 1\n' + |
| ' b: 2\n' + |
| '>\n' + |
| 'repeated_int32: 202\n' + |
| 'optional_float: 123.4'; |
| |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| assertTrue(parser.parse(message, value, true)); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(202, message.getRepeatedInt32(1)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationSkipUnknownNestedInvalid() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'some_unknown: <\n' + |
| ' a: \n' + // Missing value. |
| ' b: 2\n' + |
| '>\n' + |
| 'repeated_int32: 202\n' + |
| 'optional_float: 123.4'; |
| |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| assertFalse(parser.parse(message, value, true)); |
| } |
| |
| function testDeserializationSkipUnknownNestedInvalid2() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'repeated_int32: 201\n' + |
| 'some_unknown: <\n' + |
| ' a: 2\n' + |
| ' b: 2\n' + |
| '}\n' + // Delimiter mismatch |
| 'repeated_int32: 202\n' + |
| 'optional_float: 123.4'; |
| |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| assertFalse(parser.parse(message, value, true)); |
| } |
| |
| |
| function testDeserializationLegacyFormat() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101,\n' + |
| 'repeated_int32: 201,\n' + |
| 'repeated_int32: 202;\n' + |
| 'optional_float: 123.4'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(201, message.getRepeatedInt32(0)); |
| assertEquals(202, message.getRepeatedInt32(1)); |
| assertEquals(123.4, message.getOptionalFloat()); |
| } |
| |
| function testDeserializationVariedNumbers() { |
| var message = new proto2.TestAllTypes(); |
| var value = ( |
| 'repeated_int32: 23\n' + |
| 'repeated_int32: -3\n' + |
| 'repeated_int32: 0xdeadbeef\n' + |
| 'repeated_float: 123.0\n' + |
| 'repeated_float: -3.27\n' + |
| 'repeated_float: -35.5f\n' |
| ); |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(23, message.getRepeatedInt32(0)); |
| assertEquals(-3, message.getRepeatedInt32(1)); |
| assertEquals(3735928559, message.getRepeatedInt32(2)); |
| assertEquals(123.0, message.getRepeatedFloat(0)); |
| assertEquals(-3.27, message.getRepeatedFloat(1)); |
| assertEquals(-35.5, message.getRepeatedFloat(2)); |
| } |
| |
| function testDeserializationScientificNotation() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'repeated_float: 1.1e5\n' + |
| 'repeated_float: 1.1e-5\n' + |
| 'repeated_double: 1.1e5\n' + |
| 'repeated_double: 1.1e-5\n'; |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| assertEquals(1.1e5, message.getRepeatedFloat(0)); |
| assertEquals(1.1e-5, message.getRepeatedFloat(1)); |
| assertEquals(1.1e5, message.getRepeatedDouble(0)); |
| assertEquals(1.1e-5, message.getRepeatedDouble(1)); |
| } |
| |
| function testParseNumericalConstant() { |
| var parseNumericalConstant = |
| goog.proto2.TextFormatSerializer.Parser.parseNumericalConstant_; |
| |
| assertEquals(Infinity, parseNumericalConstant('inf')); |
| assertEquals(Infinity, parseNumericalConstant('inff')); |
| assertEquals(Infinity, parseNumericalConstant('infinity')); |
| assertEquals(Infinity, parseNumericalConstant('infinityf')); |
| assertEquals(Infinity, parseNumericalConstant('Infinityf')); |
| |
| assertEquals(-Infinity, parseNumericalConstant('-inf')); |
| assertEquals(-Infinity, parseNumericalConstant('-inff')); |
| assertEquals(-Infinity, parseNumericalConstant('-infinity')); |
| assertEquals(-Infinity, parseNumericalConstant('-infinityf')); |
| assertEquals(-Infinity, parseNumericalConstant('-Infinity')); |
| |
| assertNull(parseNumericalConstant('-infin')); |
| assertNull(parseNumericalConstant('infin')); |
| assertNull(parseNumericalConstant('-infinite')); |
| |
| assertNull(parseNumericalConstant('-infin')); |
| assertNull(parseNumericalConstant('infin')); |
| assertNull(parseNumericalConstant('-infinite')); |
| |
| assertTrue(isNaN(parseNumericalConstant('Nan'))); |
| assertTrue(isNaN(parseNumericalConstant('NaN'))); |
| assertTrue(isNaN(parseNumericalConstant('NAN'))); |
| assertTrue(isNaN(parseNumericalConstant('nan'))); |
| assertTrue(isNaN(parseNumericalConstant('nanf'))); |
| assertTrue(isNaN(parseNumericalConstant('NaNf'))); |
| |
| assertEquals(Number.POSITIVE_INFINITY, parseNumericalConstant('infinity')); |
| assertEquals(Number.NEGATIVE_INFINITY, parseNumericalConstant('-inf')); |
| assertEquals(Number.NEGATIVE_INFINITY, parseNumericalConstant('-infinity')); |
| |
| assertNull(parseNumericalConstant('na')); |
| assertNull(parseNumericalConstant('-nan')); |
| assertNull(parseNumericalConstant('none')); |
| } |
| |
| function testDeserializationOfNumericalConstants() { |
| |
| var message = new proto2.TestAllTypes(); |
| var value = ( |
| 'repeated_float: inf\n' + |
| 'repeated_float: -inf\n' + |
| 'repeated_float: nan\n' + |
| 'repeated_float: 300.2\n' |
| ); |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(Infinity, message.getRepeatedFloat(0)); |
| assertEquals(-Infinity, message.getRepeatedFloat(1)); |
| assertTrue(isNaN(message.getRepeatedFloat(2))); |
| assertEquals(300.2, message.getRepeatedFloat(3)); |
| } |
| |
| var floatFormatCases = [{given: '1.69e+06', expect: 1.69e+06}, |
| {given: '1.69e6', expect: 1.69e+06}, |
| {given: '2.468e-2', expect: 0.02468} |
| ]; |
| |
| function testGetNumberFromStringExponentialNotation() { |
| for (var i = 0; i < floatFormatCases.length; ++i) { |
| var thistest = floatFormatCases[i]; |
| var result = goog.proto2.TextFormatSerializer.Parser. |
| getNumberFromString_(thistest.given); |
| assertEquals(thistest.expect, result); |
| } |
| } |
| |
| function testDeserializationExponentialFloat() { |
| var parser = new goog.proto2.TextFormatSerializer.Parser(); |
| for (var i = 0; i < floatFormatCases.length; ++i) { |
| var thistest = floatFormatCases[i]; |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_float: ' + thistest.given; |
| assertTrue(parser.parse(message, value, true)); |
| assertEquals(thistest.expect, message.getOptionalFloat()); |
| } |
| } |
| |
| function testGetNumberFromString() { |
| var getNumberFromString = |
| goog.proto2.TextFormatSerializer.Parser.getNumberFromString_; |
| |
| assertEquals(3735928559, getNumberFromString('0xdeadbeef')); |
| assertEquals(4276215469, getNumberFromString('0xFEE1DEAD')); |
| assertEquals(123.1, getNumberFromString('123.1')); |
| assertEquals(123.0, getNumberFromString('123.0')); |
| assertEquals(-29.3, getNumberFromString('-29.3f')); |
| assertEquals(23, getNumberFromString('23')); |
| assertEquals(-3, getNumberFromString('-3')); |
| assertEquals(-3.27, getNumberFromString('-3.27')); |
| |
| assertThrows(goog.partial(getNumberFromString, 'cat')); |
| assertThrows(goog.partial(getNumberFromString, 'NaN')); |
| assertThrows(goog.partial(getNumberFromString, 'inf')); |
| } |
| |
| function testDeserializationError() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int33: 101\n'; |
| var result = |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| assertEquals(result, 'Unknown field: optional_int33'); |
| } |
| |
| function testNestedDeserialization() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'optional_nested_message: {\n' + |
| ' b: 301\n' + |
| '}'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(301, message.getOptionalNestedMessage().getB()); |
| } |
| |
| function testNestedDeserializationLegacyFormat() { |
| var message = new proto2.TestAllTypes(); |
| var value = 'optional_int32: 101\n' + |
| 'optional_nested_message: <\n' + |
| ' b: 301\n' + |
| '>'; |
| |
| new goog.proto2.TextFormatSerializer().deserializeTo(message, value); |
| |
| assertEquals(101, message.getOptionalInt32()); |
| assertEquals(301, message.getOptionalNestedMessage().getB()); |
| } |
| |
| function testBidirectional() { |
| var message = new proto2.TestAllTypes(); |
| |
| // Set the fields. |
| // Singular. |
| message.setOptionalInt32(101); |
| message.setOptionalInt64('102'); |
| message.setOptionalUint32(103); |
| message.setOptionalUint64('104'); |
| message.setOptionalSint32(105); |
| message.setOptionalSint64('106'); |
| message.setOptionalFixed32(107); |
| message.setOptionalFixed64('108'); |
| message.setOptionalSfixed32(109); |
| message.setOptionalSfixed64('110'); |
| message.setOptionalFloat(111.5); |
| message.setOptionalDouble(112.5); |
| message.setOptionalBool(true); |
| message.setOptionalString('test'); |
| message.setOptionalBytes('abcd'); |
| |
| var group = new proto2.TestAllTypes.OptionalGroup(); |
| group.setA(111); |
| |
| message.setOptionalgroup(group); |
| |
| var nestedMessage = new proto2.TestAllTypes.NestedMessage(); |
| nestedMessage.setB(112); |
| |
| message.setOptionalNestedMessage(nestedMessage); |
| |
| message.setOptionalNestedEnum(proto2.TestAllTypes.NestedEnum.FOO); |
| |
| // Repeated. |
| message.addRepeatedInt32(201); |
| message.addRepeatedInt32(202); |
| message.addRepeatedString('hello "world"'); |
| |
| // Serialize the message to text form. |
| var serializer = new goog.proto2.TextFormatSerializer(); |
| var textform = serializer.serialize(message); |
| |
| // Create a copy and deserialize into the copy. |
| var copy = new proto2.TestAllTypes(); |
| serializer.deserializeTo(copy, textform); |
| |
| // Assert that the messages are structurally equivalent. |
| assertTrue(copy.equals(message)); |
| } |
| |
| function testBidirectional64BitNumber() { |
| var message = new proto2.TestAllTypes(); |
| message.setOptionalInt64Number(10000000); |
| message.setOptionalInt64String('200000000000000000'); |
| |
| // Serialize the message to text form. |
| var serializer = new goog.proto2.TextFormatSerializer(); |
| var textform = serializer.serialize(message); |
| |
| // Create a copy and deserialize into the copy. |
| var copy = new proto2.TestAllTypes(); |
| serializer.deserializeTo(copy, textform); |
| |
| // Assert that the messages are structurally equivalent. |
| assertTrue(copy.equals(message)); |
| } |
| |
| function testUseEnumValues() { |
| var message = new proto2.TestAllTypes(); |
| message.setOptionalNestedEnum(proto2.TestAllTypes.NestedEnum.FOO); |
| |
| var serializer = new goog.proto2.TextFormatSerializer(false, true); |
| var textform = serializer.serialize(message); |
| |
| var expected = 'optional_nested_enum: 0\n'; |
| |
| assertEquals(expected, textform); |
| |
| var deserializedMessage = new proto2.TestAllTypes(); |
| serializer.deserializeTo(deserializedMessage, textform); |
| |
| assertEquals( |
| proto2.TestAllTypes.NestedEnum.FOO, |
| deserializedMessage.getOptionalNestedEnum()); |
| } |