Skip to content

Commit

Permalink
Merge pull request #165 from oleg-nenashev/code-tabs
Browse files Browse the repository at this point in the history
Add support for rendering code tabs
  • Loading branch information
oleg-nenashev authored Sep 4, 2023
2 parents 050c296 + 5edecae commit 91b7074
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 51 deletions.
51 changes: 25 additions & 26 deletions _docs/request-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ description: WireMock supports matching of requests to stubs and verification qu

WireMock enables flexible definition of a [mock API](/) by supporting rich matching of incoming requests. Stub matching and verification queries can use the following request attributes:

- URL
- HTTP Method
- Query parameters
- Form parameters
- Headers
- Basic authentication (a special case of header matching)
- Cookies
- Request body
- Multipart/form-data
- URL
- HTTP Method
- Query parameters
- Form parameters
- Headers
- Basic authentication (a special case of header matching)
- Cookies
- Request body
- Multipart/form-data

Here's an example showing all attributes being matched using WireMock's in-built match operators. It is also possible to write [custom matching logic](../extending-wiremock#custom-request-matchers) if
you need more precise control:

## Request with XML Body
Java:

Code:

```java
stubFor(any(urlPathEqualTo("/everything"))
Expand All @@ -41,7 +42,7 @@ stubFor(any(urlPathEqualTo("/everything"))
.willReturn(aResponse()));
```

JSON:
Configuration file:

```json
{
Expand Down Expand Up @@ -126,7 +127,6 @@ stubFor(post(urlPathEqualTo("/mock"))
}
```


The following sections describe each type of matching strategy in detail.

## URL matching
Expand Down Expand Up @@ -664,7 +664,7 @@ JSON:

Request body example:

```
```json
// matching
{ "things": { "name": "RequiredThing" } }
{ "things": [ { "name": "Required" }, { "name": "Wiremock" } ] }
Expand Down Expand Up @@ -701,7 +701,7 @@ JSON:

Request body example:

```
```json
// matching
{ "things": [ { "name": "RequiredThing" }, { "name": "Wiremock" } ] }
// not matching
Expand Down Expand Up @@ -1340,14 +1340,14 @@ JSON:
<div id="all-truncations"></div>
The full list of available truncations is:
- `first minute of hour`
- `first hour of day`
- `first day of month`
- `first day of next month`
- `last day of month`
- `first day of year`
- `first day of next year`
- `last day of year`
- `first minute of hour`
- `first hour of day`
- `first day of month`
- `first day of next month`
- `last day of month`
- `first day of year`
- `first day of next year`
- `last day of year`
## Logical AND and OR
Expand Down Expand Up @@ -1487,7 +1487,6 @@ This would match the following JSON request body:
}
```


### Matching Header/Query parameter containing multiple values

You can match multiple values of a query parameter or header with below provided matchers.
Expand All @@ -1501,7 +1500,7 @@ stubFor(get(urlPathEqualTo("/things"))
.willReturn(ok()));
```

```json
```json
{
"mapping": {
"request" : {
Expand Down Expand Up @@ -1607,7 +1606,6 @@ stubFor(get(urlPathEqualTo("/things"))
}
```


```java
//values of id must conform to the match expressions
stubFor(get(urlPathEqualTo("/things"))
Expand All @@ -1617,6 +1615,7 @@ stubFor(get(urlPathEqualTo("/things"))
notContaining("3")
)).willReturn(ok()));
```

```json
{
"mapping": {
Expand Down Expand Up @@ -1644,4 +1643,4 @@ stubFor(get(urlPathEqualTo("/things"))
}
}
}
```
```
90 changes: 65 additions & 25 deletions _docs/stubbing.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,44 @@ responses for requests matching criteria. These are described in detail in [Requ

## Basic stubbing

The following code will configure a response with a status of 200 to be
returned when the relative URL exactly matches `/some/thing` (including
query parameters). The body of the response will be "Hello world!" and a
You can configure stubs using JSON configuration files or code:

1. Via a `.json` file under the `mappings` directory
2. Via a POST request to
`http://<host>:<port>/__admin/mappings` with the JSON as a body
3. From code using one of the SDKs

**Example.**
To configure a response with a status of 200 to be returned
when the relative URL exactly matches `/some/thing` (including query parameters).
The body of the response will be "Hello world!" and a
`Content-Type` header will be sent with a value of `text-plain`.

{% codetabs %}

{% codetab JSON %}

```json
{
"request": {
"method": "GET",
"url": "/some/thing"
},

"response": {
"status": 200,
"body": "Hello, world!",
"headers": {
"Content-Type": "text/plain"
}
}
}
```

{% endcodetab %}

{% codetab Java %}

```java
@Test
public void exactUrlOnly() {
Expand All @@ -30,32 +63,39 @@ public void exactUrlOnly() {
}
```

> **note**
>
> If you'd prefer to use slightly more BDDish language in your tests you
> can replace `stubFor` with `givenThat`.
{% endcodetab %}

To create the stub described above via the JSON API, the following
document can either be posted to
`http://<host>:<port>/__admin/mappings` or placed in a file with a
`.json` extension under the `mappings` directory:
{% codetab Python %}

```json
{
"request": {
"method": "GET",
"url": "/some/thing"
},
"response": {
"status": 200,
"body": "Hello world!",
"headers": {
"Content-Type": "text/plain"
}
}
}
```python
Mappings.create_mapping(
Mapping(
request=MappingRequest(method=HttpMethods.GET, url="/some/thing"),
response=MappingResponse(status=200, body="Hello, world!", headers=("Content-Type", "text/plain")),
)
)
```

{% endcodetab %}

{% codetab Golang %}

```go
wiremockClient.StubFor(wiremock.Get(wiremock.URLPathEqualTo("/some/thing")).
WillReturnResponse(
wiremock.NewResponse().
WithStatus(http.StatusOK).
WithBody("Hello, world!").
WithHeader("Content-Type", "text/plain")))
```

{% endcodetab %}

{% endcodetabs %}

In Java, if you'd prefer to use slightly more BDDish language in your tests,
you can replace `stubFor` with `givenThat`.

### Java Shortcuts

Some common request and response patterns can be expressed in Java in abbreviated forms.
Expand Down
96 changes: 96 additions & 0 deletions _layouts/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,103 @@
visibility: visible;
}


/* Code tabs inspired by https://github.com/clustergarage/jekyll-code-tabs/pull/5 */
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}

.tab button {
background-color: inherit;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
}

.codeblock-option-selector {
float: left;
}

.codeblock-copybutton {
float: right;
}

.tab button:hover {
background-color: #ddd;
}

.tab button.active {
background-color: #ccc;
}

.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}

.tabcontent {
animation: fadeEffect 0.5s; /* Fading effect takes 1 second */
}

@keyframes fadeEffect {
from {opacity: 0.5;}
to {opacity: 1;}
}

</style>

<!-- For rendering code tabs without UIKit in the original Code Tabs plugin, also with grouping -->
<script>
document.addEventListener("DOMContentLoaded", function(){
var defaultTabs = document.querySelectorAll("#codeblock-default-selection")
for (i = 0; i < defaultTabs.length; i++) {
defaultTabs[i].click();
}
});

function showTab(evt, tabId) {
// Declare all variables
var i, tabcontent, tablinks;
var currentTab = evt.currentTarget
var codeblock = currentTab.parentElement.parentElement

// Get all elements with class="tabcontent" and hide them
tabcontent = codeblock.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}

// Get all elements with class="tablinks" and remove the class "active"
tablinks = codeblock.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}

// Show the current tab, and add an "active" class to the button that opened the tab
codeblock.querySelector("#"+tabId).style.display = "block";
evt.currentTarget.className += " active";
}

function copyCodeTabToClipboard(evt) {
var range = document.createRange();
var currentTab = evt.currentTarget
var activeTab = currentTab.parentElement.querySelector("button.active")
var tabId = activeTab.textContent

var codeblock = currentTab.parentElement.parentElement.querySelector("#"+tabId)
range.selectNode(codeblock);
window.getSelection().removeAllRanges(); // clear current selection
window.getSelection().addRange(range); // to select text
document.execCommand("copy");
window.getSelection().removeAllRanges();// to deselect
}
</script>


<article class="page" itemscope itemtype="http://schema.org/CreativeWork">
Expand Down
1 change: 1 addition & 0 deletions _plugins/jekyll-code-tabs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require_relative "../lib/jekyll-code-tabs"
Loading

0 comments on commit 91b7074

Please sign in to comment.