proto2.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2012 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Test helpers to compare goog.proto2.Messages.
  16. *
  17. */
  18. goog.setTestOnly('goog.testing.proto2');
  19. goog.provide('goog.testing.proto2');
  20. goog.require('goog.proto2.Message');
  21. goog.require('goog.proto2.ObjectSerializer');
  22. goog.require('goog.testing.asserts');
  23. /**
  24. * Compares two goog.proto2.Message instances of the same type.
  25. * @param {!goog.proto2.Message} expected First message.
  26. * @param {!goog.proto2.Message} actual Second message.
  27. * @param {string} path Path to the messages.
  28. * @return {string} A string describing where they differ. Empty string if they
  29. * are equal.
  30. * @private
  31. */
  32. goog.testing.proto2.findDifferences_ = function(expected, actual, path) {
  33. var fields = expected.getDescriptor().getFields();
  34. for (var i = 0; i < fields.length; i++) {
  35. var field = fields[i];
  36. var newPath = (path ? path + '/' : '') + field.getName();
  37. if (expected.has(field) && !actual.has(field)) {
  38. return newPath + ' should be present';
  39. }
  40. if (!expected.has(field) && actual.has(field)) {
  41. return newPath + ' should not be present';
  42. }
  43. if (expected.has(field)) {
  44. var isComposite = field.isCompositeType();
  45. if (field.isRepeated()) {
  46. var expectedCount = expected.countOf(field);
  47. var actualCount = actual.countOf(field);
  48. if (expectedCount != actualCount) {
  49. return newPath + ' should have ' + expectedCount + ' items, ' +
  50. 'but has ' + actualCount;
  51. }
  52. for (var j = 0; j < expectedCount; j++) {
  53. var expectedItem = expected.get(field, j);
  54. var actualItem = actual.get(field, j);
  55. if (isComposite) {
  56. var itemDiff = goog.testing.proto2.findDifferences_(
  57. /** @type {!goog.proto2.Message} */ (expectedItem),
  58. /** @type {!goog.proto2.Message} */ (actualItem),
  59. newPath + '[' + j + ']');
  60. if (itemDiff) {
  61. return itemDiff;
  62. }
  63. } else {
  64. if (expectedItem != actualItem) {
  65. return newPath + '[' + j + '] should be ' + expectedItem +
  66. ', but was ' + actualItem;
  67. }
  68. }
  69. }
  70. } else {
  71. var expectedValue = expected.get(field);
  72. var actualValue = actual.get(field);
  73. if (isComposite) {
  74. var diff = goog.testing.proto2.findDifferences_(
  75. /** @type {!goog.proto2.Message} */ (expectedValue),
  76. /** @type {!goog.proto2.Message} */ (actualValue), newPath);
  77. if (diff) {
  78. return diff;
  79. }
  80. } else {
  81. if (expectedValue != actualValue) {
  82. return newPath + ' should be ' + expectedValue + ', but was ' +
  83. actualValue;
  84. }
  85. }
  86. }
  87. }
  88. }
  89. return '';
  90. };
  91. /**
  92. * Compares two goog.proto2.Message objects. Gives more readable output than
  93. * assertObjectEquals on mismatch.
  94. * @param {!goog.proto2.Message} expected Expected proto2 message.
  95. * @param {!goog.proto2.Message} actual Actual proto2 message.
  96. * @param {string=} opt_failureMessage Failure message when the values don't
  97. * match.
  98. */
  99. goog.testing.proto2.assertEquals = function(
  100. expected, actual, opt_failureMessage) {
  101. var failureSummary = opt_failureMessage || '';
  102. if (!(expected instanceof goog.proto2.Message) ||
  103. !(actual instanceof goog.proto2.Message)) {
  104. goog.testing.asserts.raiseException(
  105. failureSummary,
  106. 'Bad arguments were passed to goog.testing.proto2.assertEquals');
  107. }
  108. if (expected.constructor != actual.constructor) {
  109. goog.testing.asserts.raiseException(
  110. failureSummary, 'Message type mismatch: ' +
  111. expected.getDescriptor().getFullName() + ' != ' +
  112. actual.getDescriptor().getFullName());
  113. }
  114. var diff = goog.testing.proto2.findDifferences_(expected, actual, '');
  115. if (diff) {
  116. goog.testing.asserts.raiseException(failureSummary, diff);
  117. }
  118. };
  119. /**
  120. * Helper function to quickly build protocol buffer messages from JSON objects.
  121. * @param {function(new:MessageType)} messageCtor A constructor that
  122. * creates a {@code goog.proto2.Message} subclass instance.
  123. * @param {!Object} json JSON object which uses field names as keys.
  124. * @return {MessageType} The deserialized protocol buffer.
  125. * @template MessageType
  126. */
  127. goog.testing.proto2.fromObject = function(messageCtor, json) {
  128. var serializer = new goog.proto2.ObjectSerializer(
  129. goog.proto2.ObjectSerializer.KeyOption.NAME);
  130. var message = new messageCtor;
  131. serializer.deserializeTo(message, json);
  132. return message;
  133. };