Skip to content

Commit

Permalink
Merge pull request #18 from mbland/handlebars-and-test-touch-ups
Browse files Browse the repository at this point in the history
Handlebars and test touch ups
  • Loading branch information
mbland committed Nov 29, 2023
2 parents 9bb9bad + cdfbe90 commit c79b691
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 24 deletions.
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -739,18 +739,6 @@ plugin:
- Configure the selected plugin to process the downloaded
`jacocoXmlTestReport.xml` file.

## Adding large tests

Coming soon...

TODO(mbland): Document how the following are configured:

- [Gradle WAR Plugin][] - now writes to/includes files from `strcalc/build/webapp`
- [Selenium WebDriver][]
- [TestTomcat](./strcalc/src/test/java/com/mike_bland/training/testing/utils/TestTomcat.java)
(for medium tests)
- [node-gradle/gradle-node-plugin][]

## Setup frontend JavaScript environment

[Node.js][] is a JavaScript runtime environment. [pnpm][] is a Node.js package
Expand Down Expand Up @@ -785,6 +773,20 @@ Code support:
- [Vite IntelliJ plugin][]
- [Vite extension for Visual Studio Code][]

## Adding large tests

Coming soon...

TODO(mbland): Document how the following are configured:

- [Gradle WAR Plugin][] - now writes to/includes files from `strcalc/build/webapp`
- [Selenium WebDriver][] - include references to:
- [Selenium: Design patterns and development strategies][]
- [TestTomcat](./strcalc/src/test/java/com/mike_bland/training/testing/utils/TestTomcat.java)
(for medium tests)
- [node-gradle/gradle-node-plugin][]


## Implementing core logic using Test Driven Development and unit tests

Coming soon...
Expand Down Expand Up @@ -890,3 +892,4 @@ Coming soon...
[ESLint extension for Visual Studio Code]: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
[Vite IntelliJ plugin]: https://plugins.jetbrains.com/plugin/20011-vite
[Vite extension for Visual Studio Code]: https://marketplace.visualstudio.com/items?itemName=antfu.vite
[Selenium: Design patterns and development strategies]: https://www.selenium.dev/documentation/test_practices/design_strategies/
3 changes: 2 additions & 1 deletion strcalc/src/main/frontend/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ describe('String Calculator UI', () => {
test('contains the "Hello, World!" placeholder', async () => {
let { document } = await loader.load('index.html')

let e = document.querySelector('#app .placeholder')
let e = document.querySelector('#app .placeholder a')

expect(e.textContent).toContain('Hello, World!')
expect(e.href).toContain('%22Hello,_World!%22')
})
})
})
20 changes: 12 additions & 8 deletions strcalc/src/main/frontend/rollup-plugin-handlebars-precompile.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@ const IMPORT_HANDLEBARS = `import Handlebars from '${HANDLEBARS_PATH}'`
function helpersModule(helpers) {
return [
IMPORT_HANDLEBARS,
...helpers.map((h, i) => `import helpers${i} from './${h}'`),
...helpers.map((_, i) => `helpers${i}(Handlebars)`)
...helpers.map((h, i) => `import registerHelpers${i} from './${h}'`),
...helpers.map((_, i) => `registerHelpers${i}(Handlebars)`)
].join('\n')
}

function compiledModule(compiled, imports) {
function compiledModule(code, options, helpers) {
const compiled = Handlebars.precompile(code, options)
let imports = helpers.length ? [`import '${PLUGIN_ID}'`] : []

return [
IMPORT_HANDLEBARS,
...imports,
Expand All @@ -66,19 +69,20 @@ export default function (options = {}) {
options.exclude || DEFAULT_EXCLUDE
)
const helpers = options.helpers || []
const isThisPlugin = id => id === PLUGIN_ID && helpers.length
const imports = helpers.length ? [`import '${PLUGIN_ID}'`] : []
const shouldEmitHelpersModule = id => id === PLUGIN_ID && helpers.length

return {
name: PLUGIN_NAME,

resolveId(id) { if (isThisPlugin(id)) return id },
resolveId(id) { if (shouldEmitHelpersModule(id)) return id },

load(id) { if (isThisPlugin(id)) return helpersModule(helpers) },
load(id) {
if (shouldEmitHelpersModule(id)) return helpersModule(helpers)
},

transform(code, id) {
if (isTemplate(id)) return {
code: compiledModule(Handlebars.precompile(code, options), imports)
code: compiledModule(code, options, helpers)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ void servesLandingPage() throws Exception {
@MediumCoverageTest
void getAddEndpointReturnsPlaceholderString() throws Exception {
var req = newRequestBuilder("/add").GET().build();
tomcat.start();
// We're covering the zero argument Servlet constructor while injecting
// a Servlet directly into the TestTomcat, which will leave the
// Servlet's calculator member uninitialized. In this case it's OK,
// since we aren't exercising a code path that uses it.
tomcat.start(new Servlet());

var resp = sendRequest(req);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.net.URI;
import java.time.Duration;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class WebApplicationTest {
Expand Down Expand Up @@ -78,8 +80,12 @@ String endpoint(String relPath) {
void testPlaceholder() {
driver.get(endpoint("/"));

WebElement body = driver.findElement(By.cssSelector("p.placeholder"));
WebElement elem = driver.findElement(By.cssSelector("p.placeholder a"));

assertEquals("Hello, World!", body.getText());
assertEquals("Hello, World!", elem.getText());
assertThat(
elem.getAttribute("href"),
containsString("%22Hello,_World!%22")
);
}
}

0 comments on commit c79b691

Please sign in to comment.