@pact-foundation/pact-core 13.10.0 → 13.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +56 -55
- package/build/Makefile +1 -1
- package/ffi/libpact_ffi.dylib +0 -0
- package/ffi/libpact_ffi.so +0 -0
- package/ffi/libpact_ffi.so.gz +0 -0
- package/ffi/linuxaarch64/libpact_ffi.so +0 -0
- package/ffi/osxaarch64/libpact_ffi.dylib +0 -0
- package/ffi/pact-cpp.h +20 -0
- package/ffi/pact.h +20 -0
- package/ffi/pact_ffi.dll +0 -0
- package/ffi/pact_ffi.dll.lib +0 -0
- package/native/addon.cc +5 -0
- package/native/consumer.cc +380 -1
- package/native/consumer.h +2 -0
- package/native/provider.cc +99 -1
- package/native/provider.h +2 -0
- package/package.json +4 -1
- package/src/consumer/index.d.ts +1 -0
- package/src/consumer/index.js +86 -15
- package/src/consumer/index.js.map +1 -1
- package/src/consumer/types.d.ts +26 -6
- package/src/ffi/index.d.ts +1 -1
- package/src/ffi/index.js +1 -1
- package/src/ffi/types.d.ts +4 -0
- package/src/publisher.d.ts +2 -0
- package/src/publisher.js +8 -0
- package/src/publisher.js.map +1 -1
- package/src/verifier/argumentMapper/arguments.d.ts +8 -7
- package/src/verifier/argumentMapper/arguments.js +60 -10
- package/src/verifier/argumentMapper/arguments.js.map +1 -1
- package/src/verifier/argumentMapper/index.js +2 -2
- package/src/verifier/argumentMapper/index.js.map +1 -1
- package/src/verifier/argumentMapper/types.d.ts +18 -9
- package/src/verifier/argumentMapper/types.js.map +1 -1
- package/src/verifier/types.d.ts +7 -0
- package/src/verifier/validateOptions.d.ts +7 -7
- package/src/verifier/validateOptions.js +33 -34
- package/src/verifier/validateOptions.js.map +1 -1
package/native/consumer.cc
CHANGED
|
@@ -237,6 +237,83 @@ Napi::Value PactffiCreateMockServerForPact(const Napi::CallbackInfo& info) {
|
|
|
237
237
|
return Number::New(env, result);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Create a mock server for the provided Pact handle and transport. If the transport is not
|
|
242
|
+
* provided (it is a NULL pointer or an empty string), will default to an HTTP transport. The
|
|
243
|
+
* address is the interface bind to, and will default to the loopback adapter if not specified.
|
|
244
|
+
* Specifying a value of zero for the port will result in the operating system allocating the port.
|
|
245
|
+
*
|
|
246
|
+
* Parameters:
|
|
247
|
+
* * `pact` - Handle to a Pact model created with created with `pactffi_new_pact`.
|
|
248
|
+
* * `addr` - Address to bind to (i.e. `127.0.0.1` or `[::1]`). Must be a valid UTF-8 NULL-terminated string, or NULL or empty, in which case the loopback adapter is used.
|
|
249
|
+
* * `port` - Port number to bind to. A value of zero will result in the operating system allocating an available port.
|
|
250
|
+
* * `transport` - The transport to use (i.e. http, https, grpc). Must be a valid UTF-8 NULL-terminated string, or NULL or empty, in which case http will be used.
|
|
251
|
+
* * `transport_config` - (OPTIONAL) Configuration for the transport as a valid JSON string. Set to NULL or empty if not required.
|
|
252
|
+
*
|
|
253
|
+
* The port of the mock server is returned.
|
|
254
|
+
*
|
|
255
|
+
* # Safety
|
|
256
|
+
* NULL pointers or empty strings can be passed in for the address, transport and transport_config,
|
|
257
|
+
* in which case a default value will be used. Passing in an invalid pointer will result in undefined behaviour.
|
|
258
|
+
*
|
|
259
|
+
* # Errors
|
|
260
|
+
*
|
|
261
|
+
* Errors are returned as negative values.
|
|
262
|
+
*
|
|
263
|
+
* | Error | Description |
|
|
264
|
+
* |-------|-------------|
|
|
265
|
+
* | -1 | An invalid handle was received. Handles should be created with `pactffi_new_pact` |
|
|
266
|
+
* | -2 | transport_config is not valid JSON |
|
|
267
|
+
* | -3 | The mock server could not be started |
|
|
268
|
+
* | -4 | The method panicked |
|
|
269
|
+
* | -5 | The address is not valid |
|
|
270
|
+
*
|
|
271
|
+
* C interface:
|
|
272
|
+
*
|
|
273
|
+
* int32_t pactffi_create_mock_server_for_transport(PactHandle pact,
|
|
274
|
+
* const char *addr,
|
|
275
|
+
* uint16_t port,
|
|
276
|
+
* const char *transport,
|
|
277
|
+
* const char *transport_config);
|
|
278
|
+
*/
|
|
279
|
+
Napi::Value PactffiCreateMockServerForTransport(const Napi::CallbackInfo& info) {
|
|
280
|
+
Napi::Env env = info.Env();
|
|
281
|
+
|
|
282
|
+
if (info.Length() < 5) {
|
|
283
|
+
throw Napi::Error::New(env, "PactffiCreateMockServerForTransport received < 5 arguments");
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (!info[0].IsNumber()) {
|
|
287
|
+
throw Napi::Error::New(env, "PactffiCreateMockServerForTransport(arg 0) expected a PactHandle (uint16_t)");
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (!info[1].IsString()) {
|
|
291
|
+
throw Napi::Error::New(env, "PactffiCreateMockServerForTransport(arg 1) expected a string");
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!info[2].IsNumber()) {
|
|
295
|
+
throw Napi::Error::New(env, "PactffiCleanupMockServer(arg 2) expected a number");
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (!info[3].IsString()) {
|
|
299
|
+
throw Napi::Error::New(env, "PactffiCreateMockServerForTransport(arg 3) expected a string");
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (!info[4].IsString()) {
|
|
303
|
+
throw Napi::Error::New(env, "PactffiCreateMockServerForTransport(arg 4) expected a string");
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
PactHandle pact = info[0].As<Napi::Number>().Int32Value();
|
|
307
|
+
std::string addr = info[1].As<Napi::String>().Utf8Value();
|
|
308
|
+
uint32_t port = info[2].As<Napi::Number>().Int32Value();
|
|
309
|
+
std::string transport = info[3].As<Napi::String>().Utf8Value();
|
|
310
|
+
std::string config = info[4].As<Napi::String>().Utf8Value();
|
|
311
|
+
|
|
312
|
+
uint16_t result = pactffi_create_mock_server_for_transport(pact, addr.c_str(), port, transport.c_str(), config.c_str());
|
|
313
|
+
|
|
314
|
+
return Number::New(env, result);
|
|
315
|
+
}
|
|
316
|
+
|
|
240
317
|
/**
|
|
241
318
|
* External interface to cleanup a mock server. This function will try terminate the mock server
|
|
242
319
|
* with the given port number and cleanup any memory allocated for it. Returns true, unless a
|
|
@@ -321,6 +398,59 @@ Napi::Value PactffiWritePactFile(const Napi::CallbackInfo& info) {
|
|
|
321
398
|
return Number::New(env, res);
|
|
322
399
|
}
|
|
323
400
|
|
|
401
|
+
/**
|
|
402
|
+
* External interface to trigger a mock server to write out its pact file. This function should
|
|
403
|
+
* be called if all the consumer tests have passed. The directory to write the file to is passed
|
|
404
|
+
* as the second parameter. If a NULL pointer is passed, the current working directory is used.
|
|
405
|
+
*
|
|
406
|
+
* If overwrite is true, the file will be overwritten with the contents of the current pact.
|
|
407
|
+
* Otherwise, it will be merged with any existing pact file.
|
|
408
|
+
*
|
|
409
|
+
* Returns 0 if the pact file was successfully written. Returns a positive code if the file can
|
|
410
|
+
* not be written, or there is no mock server running on that port or the function panics.
|
|
411
|
+
*
|
|
412
|
+
* # Errors
|
|
413
|
+
*
|
|
414
|
+
* Errors are returned as positive values.
|
|
415
|
+
*
|
|
416
|
+
* | Error | Description |
|
|
417
|
+
* |-------|-------------|
|
|
418
|
+
* | 1 | A general panic was caught |
|
|
419
|
+
* | 2 | The pact file was not able to be written |
|
|
420
|
+
* | 3 | A mock server with the provided port was not found |
|
|
421
|
+
*
|
|
422
|
+
* C Interface:
|
|
423
|
+
*
|
|
424
|
+
* int32_t pactffi_write_pact_file(int32_t mock_server_port, const char *directory, bool overwrite);
|
|
425
|
+
*/
|
|
426
|
+
Napi::Value PactffiWritePactFileByPort(const Napi::CallbackInfo& info) {
|
|
427
|
+
Napi::Env env = info.Env();
|
|
428
|
+
|
|
429
|
+
if (info.Length() < 3) {
|
|
430
|
+
throw Napi::Error::New(env, "PactffiWritePactFileByPort received < 3 arguments");
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (!info[0].IsNumber()) {
|
|
434
|
+
throw Napi::Error::New(env, "PactffiWritePactFileByPort(arg 0) expected a number");
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (!info[1].IsString()) {
|
|
438
|
+
throw Napi::Error::New(env, "PactffiWritePactFileByPort(arg 1) expected a string");
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (!info[2].IsBoolean()) {
|
|
442
|
+
throw Napi::Error::New(env, "PactffiWritePactFileByPort(arg 2) expected a boolean");
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
int32_t port = info[0].As<Napi::Number>().Int32Value();
|
|
446
|
+
std::string dir = info[1].As<Napi::String>().Utf8Value();
|
|
447
|
+
bool overwrite = info[2].As<Napi::Boolean>().Value();
|
|
448
|
+
|
|
449
|
+
int32_t res = pactffi_write_pact_file(port, dir.c_str(), overwrite);
|
|
450
|
+
|
|
451
|
+
return Number::New(env, res);
|
|
452
|
+
}
|
|
453
|
+
|
|
324
454
|
/**
|
|
325
455
|
* Creates a new Pact model and returns a handle to it.
|
|
326
456
|
*
|
|
@@ -457,6 +587,49 @@ Napi::Value PactffiGiven(const Napi::CallbackInfo& info) {
|
|
|
457
587
|
return Napi::Boolean::New(env, res);
|
|
458
588
|
}
|
|
459
589
|
|
|
590
|
+
/**
|
|
591
|
+
* Write the `description` field on the `SynchronousMessage`.
|
|
592
|
+
*
|
|
593
|
+
* # Safety
|
|
594
|
+
*
|
|
595
|
+
* `description` must contain valid UTF-8. Invalid UTF-8
|
|
596
|
+
* will be replaced with U+FFFD REPLACEMENT CHARACTER.
|
|
597
|
+
*
|
|
598
|
+
* This function will only reallocate if the new string
|
|
599
|
+
* does not fit in the existing buffer.
|
|
600
|
+
*
|
|
601
|
+
* # Error Handling
|
|
602
|
+
*
|
|
603
|
+
* Errors will be reported with a non-zero return value.
|
|
604
|
+
*
|
|
605
|
+
* C interface:
|
|
606
|
+
*
|
|
607
|
+
* int pactffi_sync_message_set_description(struct SynchronousMessage *message,
|
|
608
|
+
* const char *description);
|
|
609
|
+
*/
|
|
610
|
+
// Napi::Value PactffiSyncMessageSetDescription(const Napi::CallbackInfo& info) {
|
|
611
|
+
// Napi::Env env = info.Env();
|
|
612
|
+
|
|
613
|
+
// if (info.Length() < 2) {
|
|
614
|
+
// throw Napi::Error::New(env, "PactffiSyncMessageSetDescription received < 2 arguments");
|
|
615
|
+
// }
|
|
616
|
+
|
|
617
|
+
// if (!info[0].IsNumber()) {
|
|
618
|
+
// throw Napi::Error::New(env, "PactffiSyncMessageSetDescription(arg 0) expected a InteractionHandle (uint32_t)");
|
|
619
|
+
// }
|
|
620
|
+
|
|
621
|
+
// if (!info[1].IsString()) {
|
|
622
|
+
// throw Napi::Error::New(env, "PactffiSyncMessageSetDescription(arg 1) expected a string");
|
|
623
|
+
// }
|
|
624
|
+
|
|
625
|
+
// SynchronousMessage interaction = info[0].As<Napi::Number>().Uint32Value();
|
|
626
|
+
// std::string description = info[1].As<Napi::String>().Utf8Value();
|
|
627
|
+
|
|
628
|
+
// int res = pactffi_sync_message_set_description(interaction, description.c_str());
|
|
629
|
+
|
|
630
|
+
// return Number::New(env, res);
|
|
631
|
+
// }
|
|
632
|
+
|
|
460
633
|
/**
|
|
461
634
|
* Adds a provider state to the Interaction with a parameter key and value. Returns false if the interaction or Pact can't be
|
|
462
635
|
* modified (i.e. the mock server for it has already started)
|
|
@@ -1612,4 +1785,210 @@ Napi::Value PactffiPluginInteractionContents(const Napi::CallbackInfo& info) {
|
|
|
1612
1785
|
bool res = pactffi_interaction_contents(interaction, part, contentType.c_str(), contents.c_str());
|
|
1613
1786
|
|
|
1614
1787
|
return Napi::Boolean::New(env, res);
|
|
1615
|
-
}
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
/*
|
|
1791
|
+
// GetMessageContents retreives the binary contents of the request for a given message
|
|
1792
|
+
// any matchers are stripped away if given
|
|
1793
|
+
// if the contents is from a plugin, the byte[] representation of the parsed
|
|
1794
|
+
// plugin data is returned, again, with any matchers etc. removed
|
|
1795
|
+
func (m *Message) GetMessageRequestContents() ([]byte, error) {
|
|
1796
|
+
log.Println("[DEBUG] GetMessageRequestContents")
|
|
1797
|
+
if m.messageType == MESSAGE_TYPE_ASYNC {
|
|
1798
|
+
iter := C.pactffi_pact_handle_get_message_iter(m.pact.handle)
|
|
1799
|
+
log.Println("[DEBUG] pactffi_pact_handle_get_message_iter")
|
|
1800
|
+
if iter == nil {
|
|
1801
|
+
return nil, errors.New("unable to get a message iterator")
|
|
1802
|
+
}
|
|
1803
|
+
log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - OK")
|
|
1804
|
+
|
|
1805
|
+
///////
|
|
1806
|
+
// TODO: some debugging in here to see what's exploding.......
|
|
1807
|
+
///////
|
|
1808
|
+
|
|
1809
|
+
log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - len", len(m.server.messages))
|
|
1810
|
+
|
|
1811
|
+
for i := 0; i < len(m.server.messages); i++ {
|
|
1812
|
+
log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - index", i)
|
|
1813
|
+
message := C.pactffi_pact_message_iter_next(iter)
|
|
1814
|
+
log.Println("[DEBUG] pactffi_pact_message_iter_next - message", message)
|
|
1815
|
+
|
|
1816
|
+
if i == m.index {
|
|
1817
|
+
log.Println("[DEBUG] pactffi_pact_message_iter_next - index match", message)
|
|
1818
|
+
|
|
1819
|
+
if message == nil {
|
|
1820
|
+
return nil, errors.New("retreived a null message pointer")
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
len := C.pactffi_message_get_contents_length(message)
|
|
1824
|
+
log.Println("[DEBUG] pactffi_message_get_contents_length - len", len)
|
|
1825
|
+
if len == 0 {
|
|
1826
|
+
return nil, errors.New("retreived an empty message")
|
|
1827
|
+
}
|
|
1828
|
+
data := C.pactffi_message_get_contents_bin(message)
|
|
1829
|
+
log.Println("[DEBUG] pactffi_message_get_contents_bin - data", data)
|
|
1830
|
+
if data == nil {
|
|
1831
|
+
return nil, errors.New("retreived an empty pointer to the message contents")
|
|
1832
|
+
}
|
|
1833
|
+
ptr := unsafe.Pointer(data)
|
|
1834
|
+
bytes := C.GoBytes(ptr, C.int(len))
|
|
1835
|
+
|
|
1836
|
+
return bytes, nil
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
} else {
|
|
1841
|
+
iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
|
|
1842
|
+
if iter == nil {
|
|
1843
|
+
return nil, errors.New("unable to get a message iterator")
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
for i := 0; i < len(m.server.messages); i++ {
|
|
1847
|
+
message := C.pactffi_pact_sync_message_iter_next(iter)
|
|
1848
|
+
|
|
1849
|
+
if i == m.index {
|
|
1850
|
+
if message == nil {
|
|
1851
|
+
return nil, errors.New("retreived a null message pointer")
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
len := C.pactffi_sync_message_get_request_contents_length(message)
|
|
1855
|
+
if len == 0 {
|
|
1856
|
+
return nil, errors.New("retreived an empty message")
|
|
1857
|
+
}
|
|
1858
|
+
data := C.pactffi_sync_message_get_request_contents_bin(message)
|
|
1859
|
+
if data == nil {
|
|
1860
|
+
return nil, errors.New("retreived an empty pointer to the message contents")
|
|
1861
|
+
}
|
|
1862
|
+
ptr := unsafe.Pointer(data)
|
|
1863
|
+
bytes := C.GoBytes(ptr, C.int(len))
|
|
1864
|
+
|
|
1865
|
+
return bytes, nil
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
return nil, errors.New("unable to find the message")
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
// GetMessageResponseContents retreives the binary contents of the response for a given message
|
|
1874
|
+
// any matchers are stripped away if given
|
|
1875
|
+
// if the contents is from a plugin, the byte[] representation of the parsed
|
|
1876
|
+
// plugin data is returned, again, with any matchers etc. removed
|
|
1877
|
+
func (m *Message) GetMessageResponseContents() ([][]byte, error) {
|
|
1878
|
+
|
|
1879
|
+
responses := make([][]byte, len(m.server.messages))
|
|
1880
|
+
if m.messageType == MESSAGE_TYPE_ASYNC {
|
|
1881
|
+
return nil, errors.New("invalid request: asynchronous messages do not have response")
|
|
1882
|
+
}
|
|
1883
|
+
iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle)
|
|
1884
|
+
if iter == nil {
|
|
1885
|
+
return nil, errors.New("unable to get a message iterator")
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
for i := 0; i < len(m.server.messages); i++ {
|
|
1889
|
+
message := C.pactffi_pact_sync_message_iter_next(iter)
|
|
1890
|
+
|
|
1891
|
+
if message == nil {
|
|
1892
|
+
return nil, errors.New("retreived a null message pointer")
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
// Get Response body
|
|
1896
|
+
len := C.pactffi_sync_message_get_response_contents_length(message, C.ulong(i))
|
|
1897
|
+
if len == 0 {
|
|
1898
|
+
return nil, errors.New("retreived an empty message")
|
|
1899
|
+
}
|
|
1900
|
+
data := C.pactffi_sync_message_get_response_contents_bin(message, C.ulong(i))
|
|
1901
|
+
if data == nil {
|
|
1902
|
+
return nil, errors.New("retreived an empty pointer to the message contents")
|
|
1903
|
+
}
|
|
1904
|
+
ptr := unsafe.Pointer(data)
|
|
1905
|
+
bytes := C.GoBytes(ptr, C.int(len))
|
|
1906
|
+
|
|
1907
|
+
responses[i] = bytes
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
return responses, nil
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
// StartTransport starts up a mock server on the given address:port for the given transport
|
|
1914
|
+
// https://docs.rs/pact_ffi/latest/pact_ffi/mock_server/fn.pactffi_create_mock_server_for_transport.html
|
|
1915
|
+
func (m *MessageServer) StartTransport(transport string, address string, port int, config map[string][]interface{}) (int, error) {
|
|
1916
|
+
if len(m.messages) == 0 {
|
|
1917
|
+
return 0, ErrNoInteractions
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
log.Println("[DEBUG] mock server starting on address:", address, port)
|
|
1921
|
+
cAddress := C.CString(address)
|
|
1922
|
+
defer free(cAddress)
|
|
1923
|
+
|
|
1924
|
+
cTransport := C.CString(transport)
|
|
1925
|
+
defer free(cTransport)
|
|
1926
|
+
|
|
1927
|
+
configJson := stringFromInterface(config)
|
|
1928
|
+
cConfig := C.CString(configJson)
|
|
1929
|
+
defer free(cConfig)
|
|
1930
|
+
|
|
1931
|
+
p := C.pactffi_create_mock_server_for_transport(m.messagePact.handle, cAddress, C.int(port), cTransport, cConfig)
|
|
1932
|
+
|
|
1933
|
+
// | Error | Description
|
|
1934
|
+
// |-------|-------------
|
|
1935
|
+
// | -1 | An invalid handle was received. Handles should be created with pactffi_new_pact
|
|
1936
|
+
// | -2 | transport_config is not valid JSON
|
|
1937
|
+
// | -3 | The mock server could not be started
|
|
1938
|
+
// | -4 | The method panicked
|
|
1939
|
+
// | -5 | The address is not valid
|
|
1940
|
+
msPort := int(p)
|
|
1941
|
+
switch msPort {
|
|
1942
|
+
case -1:
|
|
1943
|
+
return 0, ErrInvalidMockServerConfig
|
|
1944
|
+
case -2:
|
|
1945
|
+
return 0, ErrInvalidMockServerConfig
|
|
1946
|
+
case -3:
|
|
1947
|
+
return 0, ErrMockServerUnableToStart
|
|
1948
|
+
case -4:
|
|
1949
|
+
return 0, ErrMockServerPanic
|
|
1950
|
+
case -5:
|
|
1951
|
+
return 0, ErrInvalidAddress
|
|
1952
|
+
default:
|
|
1953
|
+
if msPort > 0 {
|
|
1954
|
+
log.Println("[DEBUG] mock server running on port:", msPort)
|
|
1955
|
+
return msPort, nil
|
|
1956
|
+
}
|
|
1957
|
+
return msPort, fmt.Errorf("an unknown error (code: %v) occurred when starting a mock server for the test", msPort)
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
// Get the length of the request contents of a `SynchronousMessage`.
|
|
1962
|
+
size_t pactffi_sync_message_get_request_contents_length(SynchronousMessage *message);
|
|
1963
|
+
struct PactSyncMessageIterator *pactffi_pact_handle_get_sync_message_iter(PactHandle pact);
|
|
1964
|
+
struct SynchronousMessage *pactffi_pact_sync_message_iter_next(struct PactSyncMessageIterator *iter);
|
|
1965
|
+
|
|
1966
|
+
// Async
|
|
1967
|
+
// Get the length of the contents of a `Message`.
|
|
1968
|
+
size_t pactffi_message_get_contents_length(Message *message);
|
|
1969
|
+
|
|
1970
|
+
// Get the contents of a `Message` as a pointer to an array of bytes.
|
|
1971
|
+
const unsigned char *pactffi_message_get_contents_bin(const Message *message);
|
|
1972
|
+
struct PactMessageIterator *pactffi_pact_handle_get_message_iter(PactHandle pact);
|
|
1973
|
+
struct Message *pactffi_pact_message_iter_next(struct PactMessageIterator *iter);
|
|
1974
|
+
|
|
1975
|
+
// Need the index of the body to get
|
|
1976
|
+
const unsigned char *pactffi_sync_message_get_response_contents_bin(const struct SynchronousMessage *message, size_t index);
|
|
1977
|
+
size_t pactffi_sync_message_get_response_contents_length(const struct SynchronousMessage *message, size_t index);
|
|
1978
|
+
|
|
1979
|
+
// Sync
|
|
1980
|
+
// Get the request contents of a `SynchronousMessage` as a pointer to an array of bytes.
|
|
1981
|
+
// The number of bytes in the buffer will be returned by `pactffi_sync_message_get_request_contents_length`.
|
|
1982
|
+
const unsigned char *pactffi_sync_message_get_request_contents_bin(SynchronousMessage *message);
|
|
1983
|
+
// Set Sync message request body - non binary
|
|
1984
|
+
void pactffi_sync_message_set_request_contents(InteractionHandle *message, const char *contents, const char *content_type);
|
|
1985
|
+
|
|
1986
|
+
// Set Sync message request body - binary
|
|
1987
|
+
void pactffi_sync_message_set_request_contents_bin(InteractionHandle *message, const unsigned char *contents, size_t len, const char *content_type);
|
|
1988
|
+
|
|
1989
|
+
// Set sync message response contents - non binary
|
|
1990
|
+
void pactffi_sync_message_set_response_contents(InteractionHandle *message, size_t index, const char *contents, const char *content_type);
|
|
1991
|
+
|
|
1992
|
+
// Set sync message response contents - binary
|
|
1993
|
+
void pactffi_sync_message_set_response_contents_bin(InteractionHandle *message, size_t index, const unsigned char *contents, size_t len, const char *content_type);
|
|
1994
|
+
*/
|
package/native/consumer.h
CHANGED
|
@@ -11,6 +11,7 @@ Napi::Value PactffiWithQueryParameter(const Napi::CallbackInfo& info);
|
|
|
11
11
|
Napi::Value PactffiWithRequest(const Napi::CallbackInfo& info);
|
|
12
12
|
Napi::Value PactffiWithSpecification(const Napi::CallbackInfo& info);
|
|
13
13
|
Napi::Value PactffiWritePactFile(const Napi::CallbackInfo& info);
|
|
14
|
+
Napi::Value PactffiWritePactFileByPort(const Napi::CallbackInfo& info);
|
|
14
15
|
Napi::Value PactffiCleanupMockServer(const Napi::CallbackInfo& info);
|
|
15
16
|
Napi::Value PactffiCreateMockServerForPact(const Napi::CallbackInfo& info);
|
|
16
17
|
Napi::Value PactffiCreateMockServer(const Napi::CallbackInfo& info);
|
|
@@ -123,3 +124,4 @@ Napi::Value PactffiSyncMessageGetResponseContents(const Napi::CallbackInfo& info
|
|
|
123
124
|
Napi::Value PactffiSyncMessageGetResponseContentsBin(const Napi::CallbackInfo& info);
|
|
124
125
|
Napi::Value PactffiSyncMessageGetResponseContentsLength(const Napi::CallbackInfo& info);
|
|
125
126
|
Napi::Value PactffiSyncMessageSetDescription(const Napi::CallbackInfo& info);
|
|
127
|
+
Napi::Value PactffiCreateMockServerForTransport(const Napi::CallbackInfo& info);
|
package/native/provider.cc
CHANGED
|
@@ -152,7 +152,6 @@ Napi::Value PactffiVerifierShutdown(const Napi::CallbackInfo& info) {
|
|
|
152
152
|
return info.Env().Undefined();
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
|
|
156
155
|
/**
|
|
157
156
|
* Set the provider details for the Pact verifier. Passing a NULL for any field will
|
|
158
157
|
* use the default value for that field.
|
|
@@ -214,6 +213,105 @@ Napi::Value PactffiVerifierSetProviderInfo(const Napi::CallbackInfo& info) {
|
|
|
214
213
|
return info.Env().Undefined();
|
|
215
214
|
}
|
|
216
215
|
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Adds a new transport for the given provider. Passing a NULL for any field will
|
|
219
|
+
* use the default value for that field.
|
|
220
|
+
*
|
|
221
|
+
* For non-plugin based message interactions, set protocol to "message" and set scheme
|
|
222
|
+
* to an empty string or "https" if secure HTTP is required. Communication to the calling
|
|
223
|
+
* application will be over HTTP to the default provider hostname.
|
|
224
|
+
*
|
|
225
|
+
* # Safety
|
|
226
|
+
*
|
|
227
|
+
* All string fields must contain valid UTF-8. Invalid UTF-8
|
|
228
|
+
* will be replaced with U+FFFD REPLACEMENT CHARACTER.
|
|
229
|
+
*
|
|
230
|
+
* C interface:
|
|
231
|
+
*
|
|
232
|
+
*
|
|
233
|
+
* void pactffi_verifier_add_provider_transport(VerifierHandle *handle,
|
|
234
|
+
* const char *protocol,
|
|
235
|
+
* unsigned short port,
|
|
236
|
+
* const char *path
|
|
237
|
+
* const char *scheme);
|
|
238
|
+
*
|
|
239
|
+
* */
|
|
240
|
+
Napi::Value PactffiVerifierAddProviderTransport(const Napi::CallbackInfo& info) {
|
|
241
|
+
Napi::Env env = info.Env();
|
|
242
|
+
if (info.Length() < 5) {
|
|
243
|
+
throw Napi::Error::New(env, "PactffiVerifierAddProviderTransport received < 6 arguments");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (!info[0].IsNumber()) {
|
|
247
|
+
throw Napi::Error::New(env, "PactffiVerifierAddProviderTransport(arg 0) expected a VerifierHandle");
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!info[1].IsString()) {
|
|
251
|
+
throw Napi::Error::New(env, "PactffiVerifierAddProviderTransport(arg 1) expected a string");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (!info[2].IsNumber()) {
|
|
255
|
+
throw Napi::Error::New(env, "PactffiVerifierAddProviderTransport(arg 2) expected a number");
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (!info[3].IsString()) {
|
|
259
|
+
throw Napi::Error::New(env, "PactffiVerifierAddProviderTransport(arg 3) expected a string");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!info[4].IsString()) {
|
|
263
|
+
throw Napi::Error::New(env, "PactffiVerifierAddProviderTransport(arg 4) expected a string");
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
uint32_t handleId = info[0].As<Napi::Number>().Uint32Value();
|
|
267
|
+
std::string protocol = info[1].As<Napi::String>().Utf8Value();
|
|
268
|
+
uint32_t port = info[2].As<Napi::Number>().Uint32Value();
|
|
269
|
+
std::string path = info[3].As<Napi::String>().Utf8Value();
|
|
270
|
+
std::string scheme = info[4].As<Napi::String>().Utf8Value();
|
|
271
|
+
|
|
272
|
+
pactffi_verifier_add_provider_transport(handles[handleId], protocol.c_str(), port, path.c_str(), scheme.c_str());
|
|
273
|
+
|
|
274
|
+
return info.Env().Undefined();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Enables or disables if no pacts are found to verify results in an error.
|
|
279
|
+
*
|
|
280
|
+
* `is_error` is a boolean value. Set it to greater than zero to enable an error when no pacts
|
|
281
|
+
* are found to verify, and set it to zero to disable this.
|
|
282
|
+
*
|
|
283
|
+
* # Safety
|
|
284
|
+
*
|
|
285
|
+
* This function is safe as long as the handle pointer points to a valid handle.
|
|
286
|
+
*
|
|
287
|
+
* C interface:
|
|
288
|
+
*
|
|
289
|
+
*
|
|
290
|
+
* int pactffi_verifier_set_no_pacts_is_error(struct VerifierHandle *handle, unsigned char is_error);
|
|
291
|
+
*
|
|
292
|
+
* */
|
|
293
|
+
Napi::Value PactffiVerifierSetNoPactsIsError(const Napi::CallbackInfo& info) {
|
|
294
|
+
Napi::Env env = info.Env();
|
|
295
|
+
if (info.Length() < 2) {
|
|
296
|
+
throw Napi::Error::New(env, "PactffiVerifierSetProviderInfo received < 2 arguments");
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (!info[0].IsNumber()) {
|
|
300
|
+
throw Napi::Error::New(env, "pactffiVerifierSetProviderInfo(arg 0) expected a VerifierHandle");
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!info[1].IsBoolean()) {
|
|
304
|
+
throw Napi::Error::New(env, "pactffiVerifierSetProviderInfo(arg 1 expected a boolean");
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
uint32_t handleId = info[0].As<Napi::Number>().Uint32Value();
|
|
308
|
+
bool isError = info[1].As<Napi::Boolean>().Value();
|
|
309
|
+
|
|
310
|
+
pactffi_verifier_set_no_pacts_is_error(handles[handleId], isError);
|
|
311
|
+
|
|
312
|
+
return info.Env().Undefined();
|
|
313
|
+
}
|
|
314
|
+
|
|
217
315
|
/**
|
|
218
316
|
* Set the filters for the Pact verifier.
|
|
219
317
|
*
|
package/native/provider.h
CHANGED
|
@@ -13,6 +13,8 @@ Napi::Value PactffiVerifierAddCustomHeader(const Napi::CallbackInfo& info);
|
|
|
13
13
|
Napi::Value PactffiVerifierAddFileSource(const Napi::CallbackInfo& info);
|
|
14
14
|
Napi::Value PactffiVerifierAddDirectorySource(const Napi::CallbackInfo& info);
|
|
15
15
|
Napi::Value PactffiVerifierUrlSource(const Napi::CallbackInfo& info);
|
|
16
|
+
Napi::Value PactffiVerifierAddProviderTransport(const Napi::CallbackInfo& info);
|
|
17
|
+
Napi::Value PactffiVerifierSetNoPactsIsError(const Napi::CallbackInfo& info);
|
|
16
18
|
// Napi::Value PactffiVerifierBrokerSource(const Napi::CallbackInfo& info);
|
|
17
19
|
Napi::Value PactffiVerifierBrokerSourceWithSelectors(const Napi::CallbackInfo& info);
|
|
18
20
|
Napi::Value PactffiVerifierSetFailIfNoPactsFound(const Napi::CallbackInfo& info);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pact-foundation/pact-core",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.11.1",
|
|
4
4
|
"description": "Core of @pact-foundation/pact. You almost certainly don't want to depend on this directly.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"homepage": "https://github.com/pact-foundation/pact-js-core#readme",
|
|
@@ -69,6 +69,8 @@
|
|
|
69
69
|
"unixify": "1.0.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
+
"@grpc/grpc-js": "^1.7.1",
|
|
73
|
+
"@grpc/proto-loader": "^0.7.3",
|
|
72
74
|
"@pact-foundation/pact-js-prettier-config": "^1.0.0",
|
|
73
75
|
"@tsconfig/node14": "^1.0.3",
|
|
74
76
|
"@types/basic-auth": "^1.1.2",
|
|
@@ -104,6 +106,7 @@
|
|
|
104
106
|
"eslint-config-prettier": "^8.3.0",
|
|
105
107
|
"express": "4.16.2",
|
|
106
108
|
"form-data": "^4.0.0",
|
|
109
|
+
"grpc-promise": "^1.4.0",
|
|
107
110
|
"mocha": "^9.1.3",
|
|
108
111
|
"nodemon": "^2.0.4",
|
|
109
112
|
"prettier": "^2.3.0",
|
package/src/consumer/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FfiSpecificationVersion } from '../ffi/types';
|
|
2
2
|
import { ConsumerMessagePact, ConsumerPact } from './types';
|
|
3
3
|
export declare const makeConsumerPact: (consumer: string, provider: string, version?: FfiSpecificationVersion, logLevel?: import("..").LogLevel) => ConsumerPact;
|
|
4
|
+
export declare const makeConsumerMessagePact: (consumer: string, provider: string, version?: FfiSpecificationVersion, logLevel?: import("..").LogLevel) => ConsumerMessagePact;
|
|
4
5
|
export declare const makeConsumerAsyncMessagePact: (consumer: string, provider: string, version?: FfiSpecificationVersion, logLevel?: import("..").LogLevel) => ConsumerMessagePact;
|
|
5
6
|
export * from './types';
|