Pārlūkot izejas kodu

Added JavaScript conformance tests. All tests pass!

Josh Haberman 9 gadi atpakaļ
vecāks
revīzija
f873d3213c
5 mainītis faili ar 180 papildinājumiem un 1 dzēšanām
  1. 3 0
      conformance/Makefile.am
  2. 171 0
      conformance/conformance_nodejs.js
  3. 4 0
      js/binary/utils.js
  4. 1 1
      js/message.js
  5. 1 0
      tests.sh

+ 3 - 0
conformance/Makefile.am

@@ -335,6 +335,9 @@ test_python: protoc_middleman conformance-test-runner
 test_python_cpp: protoc_middleman conformance-test-runner
 	./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py
 
+test_nodejs: protoc_middleman conformance-test-runner
+	NODE_PATH=../js:. ./conformance-test-runner ./conformance_nodejs.js
+
 if OBJC_CONFORMANCE_TEST
 
 test_objc: protoc_middleman conformance-test-runner conformance-objc

+ 171 - 0
conformance/conformance_nodejs.js

@@ -0,0 +1,171 @@
+#!/usr/bin/env node
+
+/*
+ * Protocol Buffers - Google's data interchange format
+ * Copyright 2008 Google Inc.  All rights reserved.
+ * https://developers.google.com/protocol-buffers/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var conformance = require('conformance_pb');
+var fs = require('fs');
+
+var testCount = 0;
+
+function doTest(request) {
+  var testMessage;
+  var response = new conformance.ConformanceResponse();
+
+  try {
+    switch (request.getPayloadCase()) {
+      case conformance.ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD:
+        try {
+          testMessage = conformance.TestAllTypes.deserializeBinary(
+              request.getProtobufPayload());
+        } catch (err) {
+          response.setParseError(err.toString());
+          return response;
+        }
+
+      case conformance.ConformanceRequest.PayloadCase.JSON_PAYLOAD:
+        response.setSkipped("JSON not supported.");
+        return response;
+
+      case conformance.ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET:
+        response.setRuntimeError("Request didn't have payload");
+        return response;
+    }
+
+    switch (request.getRequestedOutputFormat()) {
+      case conformance.UNSPECIFIED:
+        response.setRuntimeError("Unspecified output format");
+        return response;
+
+      case conformance.PROTOBUF:
+        response.setProtobufPayload(testMessage.serializeBinary());
+
+      case conformance.JSON:
+        response.setSkipped("JSON not supported.");
+        return response;
+
+      default:
+        throw "Request didn't have requested output format";
+    }
+  } catch (err) {
+    response.setRuntimeError(err.toString());
+  }
+
+  return response
+}
+
+function onEof(totalRead) {
+  if (totalRead == 0) {
+    return undefined;
+  } else {
+    throw "conformance_nodejs: premature EOF on stdin.";
+  }
+}
+
+// Utility function to read a buffer of N bytes.
+function readBuffer(bytes) {
+  var buf = new Buffer(bytes);
+  var totalRead = 0;
+  while (totalRead < bytes) {
+    var read;
+    try {
+      read = fs.readSync(process.stdin.fd, buf, totalRead, bytes - totalRead);
+    } catch (e) {
+      if (e.code == 'EOF') {
+        return onEof(totalRead)
+      } else {
+        throw "conformance_nodejs: Error reading from stdin.";
+      }
+    }
+
+    if (read === 0) {
+      return onEof(totalRead);
+    }
+    totalRead += read;
+  }
+
+  return buf;
+}
+
+function writeBuffer(buffer) {
+  var totalWritten = 0;
+  while (totalWritten < buffer.length) {
+    totalWritten += fs.writeSync(
+        process.stdout.fd, buffer, totalWritten, buffer.length - totalWritten);
+  }
+}
+
+function uint8ArrayToBuffer(arr) {
+  var buffer = new Buffer(arr.length);
+  for (var i = 0; i < arr.length; i++) {
+    buffer[i] = arr[i];
+  }
+  return buffer;
+}
+
+// Returns true if the test ran successfully, false on legitimate EOF.
+// If EOF is encountered in an unexpected place, raises IOError.
+function doTestIo() {
+  var lengthBuf = readBuffer(4);
+  if (!lengthBuf) {
+    return false;
+  }
+
+  var length = lengthBuf.readInt32LE(0);
+  var serializedRequest = readBuffer(length);
+  if (!serializedRequest) {
+    throw "conformance_nodejs: Failed to read request.";
+  }
+
+  var request =
+      conformance.ConformanceRequest.deserializeBinary(serializedRequest);
+  var response = doTest(request);
+
+  var serializedResponse = response.serializeBinary();
+
+  lengthBuf = new Buffer(4);
+  lengthBuf.writeInt32LE(serializedResponse.length, 0);
+  writeBuffer(lengthBuf);
+  writeBuffer(uint8ArrayToBuffer(serializedResponse));
+
+  testCount += 1
+
+  return true;
+}
+
+while (true) {
+  if (!doTestIo()) {
+    console.error('conformance_ruby: received EOF from test runner ' +
+                  "after " + testCount + " tests, exiting")
+    break;
+  }
+}

+ 4 - 0
js/binary/utils.js

@@ -970,6 +970,10 @@ jspb.utils.byteSourceToUint8Array = function(data) {
     return /** @type {!Uint8Array} */(new Uint8Array(data));
   }
 
+  if (data.constructor === Buffer) {
+    return /** @type {!Uint8Array} */(new Uint8Array(data));
+  }
+
   if (data.constructor === Array) {
     data = /** @type {!Array.<number>} */(data);
     return /** @type {!Uint8Array} */(new Uint8Array(data));

+ 1 - 1
js/message.js

@@ -202,7 +202,7 @@ goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED);
 
 
 /**
- * Does this browser support Uint8Aray typed arrays?
+ * Does this JavaScript environment support Uint8Aray typed arrays?
  * @type {boolean}
  * @private
  */

+ 1 - 0
tests.sh

@@ -350,6 +350,7 @@ build_ruby_all() {
 build_javascript() {
   internal_build_cpp
   cd js && npm install && npm test && cd ..
+  cd conformance && make test_nodejs && cd ..
 }
 
 generate_php_test_proto() {