Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parallel mess with process #98

Merged
merged 2 commits into from
Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading