Skip to content

Commit

Permalink
Merge pull request #98 from tuananh/fix-parallel-mess-with-process
Browse files Browse the repository at this point in the history
Fix parallel mess with process
  • Loading branch information
tuananh committed Apr 24, 2020
2 parents cb4d343 + f8e394f commit 5e7b499
Show file tree
Hide file tree
Showing 18 changed files with 98 additions and 39 deletions.
6 changes: 6 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

## camaro

### `ready()`

Initialize module. Needed to be called once before calling other methods.

### `transform(xml, template)`

Transform xml string to JSON using the given template powered by XPath where:
Expand Down Expand Up @@ -44,6 +48,8 @@ const template = {

### `toJson(xml)`

**Not yet implemented**

Transform xml string to JSON where:
- `xml` - the input xml string

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ The rest are pretty much vanilla XPath 1.0.
For complete API documentation, please see [API.md](API.md)

```js
const { transform, prettyPrint } = require('camaro')
const { ready, transform, prettyPrint } = require('camaro')
const fs = require('fs')

const xml = fs.readFileSync('examples/ean.xml', 'utf-8')
Expand All @@ -99,6 +99,7 @@ const template = {
}

;(async function () {
await ready()
const result = await transform(xml, template)
console.log(result)

Expand Down
22 changes: 11 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ function isEmptyObject(obj) {
}

let cachedInstance
const instance = Module()
instance.onRuntimeInitialized = () => {
cachedInstance = instance
}

function callWasmBinding(methodName, ...args) {
return new Promise((resolve) => {
if (!cachedInstance) throw new Error('camaro is not yet initialized. You need to call `ready()` first.')
return cachedInstance[methodName](...args)
}

const ready = () => {
return new Promise((resolve, reject) => {
if (!cachedInstance) {
const instance = Module()
instance.onRuntimeInitialized = () => {
cachedInstance = instance
const result = instance[methodName](...args)
resolve(result)
resolve()
}
} else {
const result = cachedInstance[methodName](...args)
resolve(result)
} else {
resolve()
}
})
}
Expand Down Expand Up @@ -76,4 +76,4 @@ async function prettyPrint(xml, opts={indentSize: 2}) {
return callWasmBinding('prettyPrint', xml, opts)
}

module.exports = { transform, toJson, prettyPrint }
module.exports = { ready, transform, toJson, prettyPrint }
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "camaro",
"version": "4.2.0",
"version": "5.0.0",
"description": "Transforming XML to JSON using Node.js binding to native pugixml parser library",
"homepage": "https://github.com/tuananh/camaro",
"bugs": "https://github.com/tuananh/camaro/issues",
Expand Down
4 changes: 2 additions & 2 deletions test/array-in-array.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')

const xml = `
<element>
Expand Down Expand Up @@ -30,7 +30,7 @@ t.test('array-in-array test .// should only match nodes inside current node', as
items: ['.//item', '.']
}]
}

await ready()
const result = await transform(xml, template)

t.equal(result.elements[0].items.length, 3, 'elements[0].items should have only 3 elements')
Expand Down
4 changes: 2 additions & 2 deletions test/array.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('fs')
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')

t.test('array test', async t => {
const xml = fs.readFileSync('examples/recipe.xml', 'utf-8')
Expand All @@ -15,7 +15,7 @@ t.test('array test', async t => {
}
]
}

await ready()
const result = await transform(xml, recipeTemplate)
t.equal(typeof result, 'object', 'result is expected to be object')
t.equal(result.id, 'moco09596c01s001r002')
Expand Down
4 changes: 2 additions & 2 deletions test/basic.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('fs')
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')

t.test('basic test', async (t) => {
const xml = fs.readFileSync('examples/ean.xml', 'utf-8')
Expand All @@ -23,7 +23,7 @@ t.test('basic test', async (t) => {
path_not_exist: '/HotelListResponse/nonExistenPath',
empty_array: []
}

await ready()
const result = await transform(xml, template)
t.equal(typeof result, 'object', 'result is expected to be object')
t.equal(result.cache_key, '-48a4e19f:15bec159775:50eb', 'parse cache_key ok')
Expand Down
5 changes: 2 additions & 3 deletions test/empty-path.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
const fs = require('fs')
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')

t.test('empty path test', async t => {
const xml = '<hello>world</hello>'
const template = {
empty: ''
}

await ready()
const result = await transform(xml, template)
t.equal(result.empty,'','empty path => empty string')
t.end()
Expand Down
16 changes: 15 additions & 1 deletion test/function.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')
const isWin = process.platform === 'win32'

const xml = `
Expand Down Expand Up @@ -28,6 +28,7 @@ const xml = `
`

t.test('test function upper-case()', async (t) => {
await ready()
const result = await transform(xml, {
upperCase: ['//items/item', 'upper-case(.)']
})
Expand All @@ -38,6 +39,7 @@ t.test('test function upper-case()', async (t) => {
})

t.test('test function lower-case()', async (t) => {
await ready()
const result = await transform(xml, {
lowerCase: ['//items/item', 'lower-case(.)']
})
Expand All @@ -48,6 +50,7 @@ t.test('test function lower-case()', async (t) => {
})

t.test('test function title-case()', async (t) => {
await ready()
const result = await transform(xml, {
titleCase: ['//items/item', 'title-case(.)']
})
Expand All @@ -58,6 +61,7 @@ t.test('test function title-case()', async (t) => {
})

t.test('test function title-case() unicode', async (t) => {
await ready()
const result = await transform(xml, {
titleCase: ['//unicode/item', 'title-case(.)']
})
Expand All @@ -68,6 +72,7 @@ t.test('test function title-case() unicode', async (t) => {
})

t.test('test function title-case() upper after symbols', async (t) => {
await ready()
const result = await transform(xml, {
titleCase: ['//special/item', 'title-case(.)']
})
Expand All @@ -78,6 +83,7 @@ t.test('test function title-case() upper after symbols', async (t) => {
})

t.test('test function camel-case()', async (t) => {
await ready()
const result = await transform(xml, {
camelCase: ['//items/item', 'camel-case(.)']
})
Expand All @@ -88,6 +94,7 @@ t.test('test function camel-case()', async (t) => {
})

t.test('test function snake-case()', async (t) => {
await ready()
const result = await transform(xml, {
snakeCase: ['//items/item', 'snake-case(.)']
})
Expand All @@ -98,6 +105,7 @@ t.test('test function snake-case()', async (t) => {
})

t.test('test nested function calls', async (t) => {
await ready()
const result = await transform(xml, {
snakeCase: ['//items/item', 'snake-case(lower-case(.))']
})
Expand All @@ -108,36 +116,42 @@ t.test('test nested function calls', async (t) => {
})

t.test('test function round()', async (t) => {
await ready()
const result = await transform(xml, { round: 'round(root/single)' })
t.equal(result.round, 20)
t.end()
})

t.test('test function floor()', async (t) => {
await ready()
const result = await transform(xml, { floor: 'floor(root/single)' })
t.equal(result.floor, 20)
t.end()
})

t.test('test function ceiling()', async (t) => {
await ready()
const result = await transform(xml, { ceiling: 'ceiling(root/single)' })
t.equal(result.ceiling, 21)
t.end()
})

t.test('test function sum()', async (t) => {
await ready()
const result = await transform(xml, { sum: 'sum(root/number)' })
t.equal(result.sum, 30.5)
t.end()
})

t.test('test function count()', async (t) => {
await ready()
const result = await transform(xml, { count: 'count(root/number)' })
t.equal(result.count, 2)
t.end()
})

t.test('test function boolean()', async (t) => {
await ready()
const result = await transform(xml, {
boolean: 'boolean(root/boolean = "TrUe")',
boolean_false: 'boolean(root/boolean = "true")'
Expand Down
11 changes: 7 additions & 4 deletions test/input.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')

t.test('test invalid xml string',async (t) => {
try {
const result = await transform('', {})
await ready()
await transform('', {})
} catch (err) {
t.equal(err instanceof TypeError, true, 'should throw TypeError invalid xml string')
}
Expand All @@ -13,13 +14,15 @@ t.test('test invalid xml string',async (t) => {

t.test('test invalid template argument',async (t) => {
try {
const result = await transform('<xml/>', null)
await ready()
await transform('<xml/>', null)
} catch (err) {
t.equal(err instanceof TypeError, true, 'should throw TypeError invalid template')
}

try {
const result = await transform('<xml/>', {})
await ready()
await transform('<xml/>', {})
} catch (err) {
t.equal(err instanceof TypeError, true, 'should throw TypeError invalid template')
}
Expand Down
4 changes: 2 additions & 2 deletions test/invalid-xpath.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
const fs = require('fs')
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')

t.test('invalid xpath test', async t => {
const xml = fs.readFileSync('examples/ean.xml', 'utf-8')
const template = {
invalidXPath: 'concat()'
}

await ready()
const result = await transform(xml, template)
t.equal(result.invalidXPath, '')
t.end()
Expand Down
8 changes: 5 additions & 3 deletions test/output.test.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
const t = require('tape')
const { transform } = require('../')
const { ready, transform } = require('../')

t.test('test output is empty', async (t) => {
try {
const result = await transform('Too Many Requests', { check: 'valid_xml' })
await ready()
await transform('Too Many Requests', { check: 'valid_xml' })
} catch (err) {
t.equal(err instanceof TypeError, true, 'should throw TypeError malformed xml')
}

try {
const result = await transform('<tag>invalid xml<ta/>', { check: 'valid_xml' })
await ready()
await transform('<tag>invalid xml<ta/>', { check: 'valid_xml' })
} catch (err) {
t.equal(err instanceof TypeError, true, 'should throw TypeError malformed xml')
}
Expand Down
13 changes: 13 additions & 0 deletions test/parallel.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const t = require('tape')
const { ready, transform } = require('../')

t.test('parallel test', async t => {
await ready()
const doit = () => transform('<foo>bar</foo>', { foo: 'foo' })
let called = 0
await doit().then(_ => { called += 1 })
await doit().then(_ => { called += 1 })

t.equal(called, 2, '`called` should equal to 2')
t.end()
})
8 changes: 5 additions & 3 deletions test/pretty-print.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const fs = require('fs')
const t = require('tape')
const { prettyPrint } = require('../')
const { ready, prettyPrint } = require('../')

const xml = fs.readFileSync('examples/simple.xml', 'utf-8')

t.test('pretty print default indentSize', async (t) => {
const xml = fs.readFileSync('examples/simple.xml', 'utf-8')
await ready()
const prettyStr = await prettyPrint(xml)
t.equal(prettyStr, `<root text="im root">
<items>
Expand All @@ -17,7 +19,7 @@ t.test('pretty print default indentSize', async (t) => {
})

t.test('pretty print indentSize=4', async (t) => {
const xml = fs.readFileSync('examples/simple.xml', 'utf-8')
await ready()
const prettyStr = await prettyPrint(xml, { indentSize: 4})
t.equal(prettyStr, `<root text="im root">
<items>
Expand Down
3 changes: 2 additions & 1 deletion test/raw.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('fs')
const t = require('tape')
const { transform } = require('..')
const { ready, transform } = require('..')

t.test('raw() test', async t => {
const xml = fs.readFileSync('examples/simple.xml', 'utf-8')
Expand All @@ -10,6 +10,7 @@ t.test('raw() test', async t => {
raw1: 'raw(root/items)',
raw1NodeSet: 'raw(//item)'
}
await ready()
const result = await transform(xml, template)

const rawXml = '<items>\n\t<item>1</item>\n\t<item>2</item>\n</items>\n'
Expand Down

0 comments on commit 5e7b499

Please sign in to comment.