Skip to content

Commit

Permalink
Fixed merge conflicts.
Browse files Browse the repository at this point in the history
Macro for nodejs examples update to include the new tests. Also small update to ddp generator usage text to make it easier to use out of the box
  • Loading branch information
sarietta committed May 4, 2016
2 parents 1a0b657 + fb3bf44 commit 803e09d
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 160 deletions.
49 changes: 38 additions & 11 deletions dotdashpay/rpcgen/ddp_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,24 @@
Example call:
protoc -I../../ -I/usr/local/include --plugin=protoc-gen-ddprpc=./generator.py --ddprpc_out=../../../ddp.api.node/lib/autogen/ ../../dotdashpay/api/common/protobuf/services.proto
While there is no way to pass an argument to the generator via protoc
(it does not allow this), you can set the following environment
variables to control how this program is executed:
EXAMPLES_DIR=../../examples \
TESTS_DIR=../../tests \
STANDALONE_DIR=../../../ddp.server.developer/views/examples \
protoc \
-I../../ -I/usr/local/include \
--plugin=protoc-gen-ddprpc=./generator.py \
--ddprpc_out=../../../ddp.api.node/lib/autogen/ \
../../dotdashpay/api/common/protobuf/services.proto
Notice the first 3 lines are actually setting environment
variables. This is because protoc doesn't allow command line
arguments. Those first 3 lines control the output of the various
markup regions in the jinja templates when the generator outputs the
examples, tests, and standalone code samples (for the connect
tutorials).
In addition, you can set the following environment variables to
control how this program is executed:
== RPCGEN_DATA_FILE
Expand All @@ -19,7 +32,7 @@
== RPCGEN_DEBUG_MODE
Set the to 1 if you want to run this program in standalone mode. You
Set this to 1 if you want to run this program in standalone mode. You
must first run the program using the above command line and then can
subsequently run the program directly to insert breakpoints.
Expand All @@ -39,8 +52,8 @@
import re
import sys

EXAMPLE_VALUES_FILENAME = os.path.sep.join([os.path.dirname(os.path.realpath(__file__)),
"..", "api", "common", "spec", "example-values.json"])
EXAMPLE_VALUES_FILENAME = os.path.join(os.path.dirname(os.path.realpath(__file__)),
"..", "api", "common", "spec", "example-values.json")
TEMPLATES_DIR = os.path.dirname(os.path.realpath(__file__)) + os.path.sep + "templates"

# Python protobuf module parses the update/completion service options
Expand Down Expand Up @@ -173,6 +186,15 @@ def find_arguments_proto_by_method_name(self, proto):
"""
return self.find_proto_by_name("{}Args".format(proto))

def find_response_args_proto_by_response_name(self, proto):
"""find_response_args_proto_by_response_name
returns a DescriptorProto of the proto field for the given response
This is meant to be 'installed' as a jinja filter.
"""

return self.find_proto_by_name(proto)

def find_proto_by_name(self, proto):
"""find_proto_by_name returns a DescriptorProto of the named proto
Expand Down Expand Up @@ -450,6 +472,7 @@ def generate(self, services, outputs):
lambda content: get_method_options(content)
environment.filters["get_example_value_for_field"] = self.get_example_value_for_field
environment.filters["find_arguments_proto_by_method_name"] = self.find_arguments_proto_by_method_name
environment.filters["find_response_args_proto_by_response_name"] = self.find_response_args_proto_by_response_name
environment.filters["find_proto_by_name"] = self.find_proto_by_name
environment.filters["recase"] = self.recase
environment.filters["service_file"] = self.service_file
Expand Down Expand Up @@ -593,10 +616,14 @@ def _map_raw_example_value_to_language(self, raw_value):

value = "";
if isinstance(raw_value, basestring):
if has_language:
value = "{}{}{}".format(mapping["string_prefix"], raw_value, mapping["string_suffix"])
# differentiate between enums and strings here
if raw_value[:2] == "e:":
value = "\"{}\"".format(raw_value.split(".")[-1])
else:
value = "\"{}\"".format(raw_value)
if has_language:
value = "{}{}{}".format(mapping["string_prefix"], raw_value, mapping["string_suffix"])
else:
value = "\"{}\"".format(raw_value)
elif isinstance(raw_value, bool):
if has_language:
value = mapping["true_value"] if raw_value else mapping["false_value"];
Expand Down
55 changes: 0 additions & 55 deletions dotdashpay/rpcgen/example-values.json

This file was deleted.

2 changes: 1 addition & 1 deletion dotdashpay/rpcgen/objc_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def beautify(self, code):
if not os.path.isfile(UNCRUSTIFY_PATH):
raise "Cannot beautify Objective-C code without uncrustify, which can be built via setup.sh"

pipe = Popen([UNCRUSTIFY_PATH, "-c", "{}".format(UNCRUSTIFY_CFG)],
pipe = Popen([UNCRUSTIFY_PATH, "-q", "-c", "{}".format(UNCRUSTIFY_CFG)],
stdout=PIPE, stdin=PIPE, stderr=STDOUT)
output = pipe.communicate(input="{}\n".format(code))[0]
return output.decode()
Expand Down
2 changes: 1 addition & 1 deletion dotdashpay/rpcgen/templates/nodejs.api.source.j2
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports.{{method.name | lowercase_first_letter}} = function {{method.name
var request = new {{method.name}}Request({{method.input_type | remove_package | lowercase_first_letter}});
server.sendRequest(request);
return request;
}
};

{% endfor %}

Expand Down
165 changes: 109 additions & 56 deletions dotdashpay/rpcgen/templates/nodejs.examples.source.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,115 @@
// @example-args({{service.name}}.{{method.name}})
{% endif %}
var args = {
{% for field in (method.name | find_arguments_proto_by_method_name).field %}
{% if field.name != "META" %}
{{field.name | recase}}: {{field.name | get_example_value_for_field}},
{% endif %}
{% endfor %}
{% for field in (method.name | find_arguments_proto_by_method_name).field %}
{% if field.name != "META" %}
{{field.name | recase}}: {{field.name | get_example_value_for_field}},
{% endif %}
{% endfor %}
};
{% if is_example %}
// @example-args-end()
{% endif %}

// @test()
describe("{{service.name}}", function() {
describe("{{method.name|lowercase_first_letter}}", function () {
it("should have no undefined fields", function (done) {
this.timeout(10000);
var callbacksVisited = 0;
// @test-end()
{% if is_example %}
// @example-request({{service.name}}.{{method.name}})
{% endif %}
dotdashpay.{{service.name|lowercase_first_letter}}.{{method.name|lowercase_first_letter}}(args)
{% for resp in method | get_method_options %}
.on{{resp.name}}(function (response) {
{% for field in (resp.name | find_proto_by_name).field %}
{% if field.name != "META" %}
var {{field.name | recase}} = response.{{field.name | recase}}; // {{field.name | recase}} = {{field.name | get_example_value_for_field}}
// @test()
assert.isDefined({{field.name | recase}});
// @test-end()
{% endif %}
{% endfor%}
// @test()
callbacksVisited++;
{% if resp.type == "COMPLETION" %}
assert.equal(callbacksVisited, {{method | get_method_options | length}}, "Not all callbacks were called")
setTimeout(done, 500); // let the logging complete
{% endif %}
// @test-end()
})
{% endfor %}
.onError(function (errorData) {
if (errorData.errorCode == "") {
console.log("Error: " + errorData.errorMessage);
}
// @test()
fail(null, null, "This example should never return an error");
// @test-end()
});
{% if is_example %}
// @example-request-end()
{% endif %}
// @test()
describe("{{method.name|lowercase_first_letter}}", function () {
beforeEach(function () {
dotdashpay._reset();
dotdashpay.setup({simulate: true});
});

it("should have no undefined fields", function (done) {
this.timeout(10000);
var callbacksVisited = 0;
// @test-end()
{% if is_example %}
// @example-request({{service.name}}.{{method.name}})
{% endif %}
dotdashpay.{{service.name|lowercase_first_letter}}.{{method.name|lowercase_first_letter}}(args)
{% for resp in method | get_method_options %}
.on{{resp.name}}(function (response) {
{% for field in (resp.name | find_proto_by_name).field %}
{% if field.name != "META" %}
var {{field.name | recase}} = response.{{field.name | recase}}; // {{field.name | recase}} = {{field.name | get_example_value_for_field}}
// @test()
assert.isDefined({{field.name | recase}});
// @test-end()
{% endif %}
{% endfor%}
// @test()
callbacksVisited++;
{% if resp.type == "COMPLETION" %}
assert.equal(callbacksVisited, {{method | get_method_options | length}}, "Not all callbacks were called")
done();
{% endif %}
// @test-end()
})
{% endfor %}
.onError(function (errorData) {
if (errorData.errorCode == "") {
console.log("Error: " + errorData.errorMessage);
}
// @test()
fail(null, null, "This example should never return an error");
// @test-end()
});
{% if is_example %}
// @example-request-end()
{% endif %}

// @test()
});

it("should be able to specify an error response with the simulator", function (done) {
this.timeout(10000);
var testErrorMessage = "Test error message";
var testErrorCode = 1;
dotdashpay.simulator.setResponse("{{(method | get_method_options | first).name}}",
{errorMessage: testErrorMessage,
errorCode: testErrorCode},
true);
dotdashpay.{{service.name|lowercase_first_letter}}.{{method.name|lowercase_first_letter}}(args)
{% for resp in method | get_method_options %}
.on{{resp.name}}(function (response) {
fail(null, null, "This example should only have an onError callback event, not {{resp.name}}");
})
{% endfor %}
.onError(function (errorData) {
assert.equal(testErrorMessage, errorData.errorMessage,
"Simulator error message was not returned correctly");
assert.equal(testErrorCode, errorData.errorCode,
"Simulator error code was not returned correctly");
dotdashpay.simulator.resetAllResponses();
done();
});
});

it("should be able to specify a particular response from the simulator", function(done) {
this.timeout(10000);
// need a string value that we can overwrite
{% set final_cb_name = (method | get_method_options | last).name %}
var newVals = {
{% for field in ( final_cb_name | find_response_args_proto_by_response_name).field %}
{# 9 is the protobuf string type #}
{# 3 is the label type for arrays #}
{% if field.type == 9 and field.label != 3 %}
{{field.name | recase}}: {{field.name | get_example_value_for_field}} + "-changed",
{% endif %}
{% endfor %}
};

dotdashpay.simulator.setResponse("{{ (method | get_method_options | last).name }}", newVals);

dotdashpay.{{service.name|lowercase_first_letter}}.{{method.name|lowercase_first_letter}}(args)
.on{{final_cb_name}}(function(response) {
_.each(newVals, function(val, key) {
assert.deepEqual(response[key], val);
});
done();
});
});
});
});
// @test-end()
{%- endmacro %}
Expand All @@ -74,28 +129,26 @@ describe("{{service.name}}", function() {
// @test()
var _ = require("lodash");
var assert = require('chai').assert;
var dotdashpay = require("../lib");
var fail = require('chai').fail;

dotdashpay.init({simulate: true});
var dotdashpay = require("..");
var fail = assert.fail;
// @test-end()

// @example()
// @single(lib-setup())
var dotdashpay = require("dotdashpay");
dotdashpay.init({simulate: true});
dotdashpay.setup({simulate: true});
// @single-end()
// @example-end()

// @reference()
// @single(standalone(try_api_short))
dotdashpay.payment.receivePaymentDataThenSettle({cents: 100})
.onError(function (errorData) {
console.error("Unexpected error while processing receivePaymentDataThenSettle: " + errorData);
})
.onSettled(function (response) {
console.log("Settlement finished! Transaction id: " + response.settle_id);
});
.onError(function (errorData) {
console.error("Unexpected error while processing receivePaymentDataThenSettle: " + errorData);
})
.onSettled(function (response) {
console.log("Settlement finished! Transaction id: " + response.settle_id);
});
// @single-end()
// @reference-end()

Expand Down
Loading

0 comments on commit 803e09d

Please sign in to comment.