diff --git a/package-lock.json b/package-lock.json
index ac49eb5..676784a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2542,6 +2542,240 @@
"jsonschema": "^1.2.4"
}
},
+ "@natlibfi/marc-record-serializers": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@natlibfi/marc-record-serializers/-/marc-record-serializers-5.0.3.tgz",
+ "integrity": "sha512-CiAX1WYFvyrMAA+E/Ui6M2qSGFrqbWZ+OrTlUSZcoaecJKUK9fFRz4cIDcqyi1pfk4cauvtVIYFtf9T0ZmuifQ==",
+ "requires": {
+ "@natlibfi/marc-record": "^4.0.4",
+ "ora": "^4.0.4",
+ "stream-json": "^1.5.0",
+ "text-encoding": ">=0.7.0 <1.0.0",
+ "xmldom": "^0.3.0",
+ "yargs": "^15.3.1"
+ },
+ "dependencies": {
+ "@natlibfi/marc-record": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@natlibfi/marc-record/-/marc-record-4.0.4.tgz",
+ "integrity": "sha512-XykLi0qevkLAVgLmRhATuyaSKgKczlgsk0JYCVUZAfKOHDJpb176uTQaVnQQtWe57CDPg02meAK1fTjlUNNR1Q==",
+ "requires": {
+ "jsonschema": "^1.2.4"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
+ },
+ "ansi-styles": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+ "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+ "requires": {
+ "@types/color-name": "^1.1.1",
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cli-spinners": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz",
+ "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA=="
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "ora": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz",
+ "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==",
+ "requires": {
+ "chalk": "^3.0.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.2.0",
+ "is-interactive": "^1.0.0",
+ "log-symbols": "^3.0.0",
+ "mute-stream": "0.0.8",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
+ "@natlibfi/melinda-commons": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/@natlibfi/melinda-commons/-/melinda-commons-10.0.3.tgz",
+ "integrity": "sha512-OJhzBh4mnqJWo6YB6OnWnm+34zRMKb5phCXl/GOCY4nJ28dieJDu4BoVzM8ONZ2rev44PZMPoeeu3Z9BhKnouQ==",
+ "requires": {
+ "@natlibfi/marc-record": "^6.0.0",
+ "@natlibfi/marc-record-serializers": "^5.0.0",
+ "@natlibfi/sru-client": "^4.0.2",
+ "debug": "^4.1.1",
+ "deep-eql": "^4.0.0",
+ "http-status": "^1.4.2",
+ "moment": "^2.27.0",
+ "nock": "^13.0.3",
+ "node-fetch": "^2.6.0"
+ },
+ "dependencies": {
+ "deep-eql": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.0.0.tgz",
+ "integrity": "sha512-GxJC5MOg2KyQlv6WiUF/VAnMj4MWnYiXo4oLgeptOELVoknyErb4Z8+5F/IM/K4g9/80YzzatxmWcyRwUseH0A==",
+ "requires": {
+ "type-detect": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@natlibfi/sru-client": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@natlibfi/sru-client/-/sru-client-4.0.2.tgz",
+ "integrity": "sha512-De/sf1Nz1eDLImIuGxMvQhz3ZljSrqpF69V68H1kTWjjBwtXUUoAhqTDW9pjlet9r9/57o0Lh/AIkuQUdqsXPQ==",
+ "requires": {
+ "debug": "^4.1.1",
+ "http-status": "^1.4.2",
+ "node-fetch": "^2.6.0",
+ "xml2js": ">=0.4.23 <1.0.0"
+ }
+ },
"@sindresorhus/is": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
@@ -2560,8 +2794,7 @@
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
- "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
- "dev": true
+ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
},
"@types/json-schema": {
"version": "7.0.4",
@@ -2736,7 +2969,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -3310,8 +3542,7 @@
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
- "dev": true
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"camelcase-keys": {
"version": "2.1.0",
@@ -3361,7 +3592,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -3448,7 +3678,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
- "dev": true,
"requires": {
"restore-cursor": "^3.1.0"
}
@@ -3476,6 +3705,11 @@
"wrap-ansi": "^5.1.0"
}
},
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
+ },
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
@@ -3512,7 +3746,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
"requires": {
"color-name": "1.1.3"
}
@@ -3520,8 +3753,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"commander": {
"version": "4.1.1",
@@ -3771,8 +4003,7 @@
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
- "dev": true
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"decode-uri-component": {
"version": "0.2.0",
@@ -3834,6 +4065,14 @@
}
}
},
+ "defaults": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+ "requires": {
+ "clone": "^1.0.2"
+ }
+ },
"defer-to-connect": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
@@ -4043,8 +4282,7 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": {
"version": "7.1.0",
@@ -4695,8 +4933,7 @@
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"get-func-name": {
"version": "2.0.0",
@@ -4906,8 +5143,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-symbols": {
"version": "1.0.1",
@@ -4980,6 +5216,11 @@
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
+ "help": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/help/-/help-3.0.2.tgz",
+ "integrity": "sha1-luGQ1KCkU7icLLSwWrOOOo+f2t0="
+ },
"highlight-es": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/highlight-es/-/highlight-es-1.0.3.tgz",
@@ -5026,6 +5267,11 @@
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
"dev": true
},
+ "http-status": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.4.2.tgz",
+ "integrity": "sha512-mBnIohUwRw9NyXMEMMv8/GANnzEYUj0Y8d3uL01zDWFkxUjYyZ6rgCaAI2zZ1Wb34Oqtbx/nFZolPRDc8Xlm5A=="
+ },
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -5379,6 +5625,11 @@
"is-path-inside": "^1.0.0"
}
},
+ "is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="
+ },
"is-npm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
@@ -5709,6 +5960,11 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
"json5": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
@@ -5840,6 +6096,11 @@
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
"dev": true
},
+ "lodash.set": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
+ "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
+ },
"lodash.toarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
@@ -5850,7 +6111,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
"integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
- "dev": true,
"requires": {
"chalk": "^2.4.2"
}
@@ -5965,8 +6225,7 @@
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
},
"mimic-response": {
"version": "1.0.1",
@@ -6222,6 +6481,11 @@
}
}
},
+ "moment": {
+ "version": "2.27.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
+ "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -6230,8 +6494,7 @@
"mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
- "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
- "dev": true
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"nan": {
"version": "2.14.1",
@@ -6266,6 +6529,17 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
+ "nock": {
+ "version": "13.0.4",
+ "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.4.tgz",
+ "integrity": "sha512-alqTV8Qt7TUbc74x1pKRLSENzfjp4nywovcJgi/1aXDiUxXdt7TkruSTF5MDWPP7UoPVgea4F9ghVdmX0xxnSA==",
+ "requires": {
+ "debug": "^4.1.0",
+ "json-stringify-safe": "^5.0.1",
+ "lodash.set": "^4.3.2",
+ "propagate": "^2.0.0"
+ }
+ },
"node-emoji": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz",
@@ -6285,6 +6559,11 @@
"semver": "^5.7.0"
}
},
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
+ },
"node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -7450,7 +7729,6 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
- "dev": true,
"requires": {
"mimic-fn": "^2.1.0"
}
@@ -7874,6 +8152,11 @@
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
},
+ "propagate": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
+ "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag=="
+ },
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -8185,14 +8468,12 @@
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
- "dev": true
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
- "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
- "dev": true
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"require-package-name": {
"version": "2.0.1",
@@ -8245,7 +8526,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
- "dev": true,
"requires": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
@@ -8310,6 +8590,11 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true
},
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -8333,8 +8618,7 @@
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
- "dev": true
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"set-value": {
"version": "2.0.1",
@@ -8379,8 +8663,7 @@
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
- "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
- "dev": true
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"slash": {
"version": "2.0.0",
@@ -8701,6 +8984,19 @@
}
}
},
+ "stream-chain": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.3.tgz",
+ "integrity": "sha512-w+WgmCZ6BItPAD3/4HD1eDiDHRLhjSSyIV+F0kcmmRyz8Uv9hvQF22KyaiAUmOlmX3pJ6F95h+C191UbS8Oe/g=="
+ },
+ "stream-json": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.7.1.tgz",
+ "integrity": "sha512-I7g0IDqvdJXbJ279/D3ZoTx0VMhmKnEF7u38CffeWdF8bfpMPsLo+5fWnkNjO2GU/JjWaRjdH+zmH03q+XGXFw==",
+ "requires": {
+ "stream-chain": "^2.2.3"
+ }
+ },
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
@@ -8807,7 +9103,6 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@@ -8881,6 +9176,11 @@
"minimatch": "^3.0.4"
}
},
+ "text-encoding": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz",
+ "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA=="
+ },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -9014,8 +9314,7 @@
"type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
},
"type-fest": {
"version": "0.8.1",
@@ -9260,6 +9559,14 @@
"integrity": "sha512-0Twghia4Z5wDGDYWURlhZmI47GvERMCsXIu0QZWVVZyW9ZjpbbZvD9Zy9M6cWiQQRRbAcYajIyKNavaZZDt1Uw==",
"dev": true
},
+ "wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+ "requires": {
+ "defaults": "^1.0.3"
+ }
+ },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -9272,8 +9579,7 @@
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
- "dev": true
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"which-pm": {
"version": "1.1.0",
@@ -9406,6 +9712,25 @@
"integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
"dev": true
},
+ "xml2js": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
+ "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ }
+ },
+ "xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+ },
+ "xmldom": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.3.0.tgz",
+ "integrity": "sha512-z9s6k3wxE+aZHgXYxSTpGDo7BYOUfJsIRyoZiX6HTjwpwfS2wpQBQKa2fD+ShLyPkqDYo5ud7KitmLZ2Cd6r0g=="
+ },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -9415,8 +9740,7 @@
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
- "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
- "dev": true
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
},
"yallist": {
"version": "2.1.2",
diff --git a/src/reducers/select.js b/src/reducers/select.js
new file mode 100644
index 0000000..e71ac53
--- /dev/null
+++ b/src/reducers/select.js
@@ -0,0 +1,117 @@
+/**
+*
+* @licstart The following is the entire license notice for the JavaScript code in this file.
+*
+* Merge MARC records
+*
+* Copyright (C) 2015-2019 University Of Helsinki (The National Library Of Finland)
+*
+* This file is part of marc-record-merge-js
+
+* marc-record-merge-js program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* marc-record-merge-js is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+* @licend The above is the entire license notice
+* for the JavaScript code in this file.
+*
+*/
+import {normalizeSync} from 'normalize-diacritics';
+
+export function strictEquality(subfieldA, subfieldB) {
+ return subfieldA.code === subfieldB.code &&
+ subfieldA.value === subfieldB.value;
+}
+
+export function subsetEquality(subfieldA, subfieldB) {
+ return subfieldA.code === subfieldB.code &&
+ (subfieldA.value.indexOf(subfieldB.value) !== -1 || subfieldB.value.indexOf(subfieldA.value) !== -1);
+}
+
+export default ({pattern, equalityFunction = strictEquality}) => (base, source) => {
+ const baseFields = base.get(pattern);
+ const sourceFields = source.get(pattern);
+
+ checkFieldType(baseFields);
+ checkFieldType(sourceFields);
+
+ if (baseFields.length > 1 || sourceFields.length > 1) {
+ return base;
+ }
+ const [baseField] = baseFields;
+ const [sourceField] = sourceFields;
+
+ if (baseField.tag === sourceField.tag === false) {
+ return base;
+ }
+ const baseSubs = baseField.subfields;
+ const sourceSubs = sourceField.subfields;
+
+ const baseSubsNormalized = baseSubs
+ .map(({code, value}) => ({code, value: normalizeSubfieldValue(value)}));
+
+ const sourceSubsNormalized = sourceSubs
+ .map(({code, value}) => ({code, value: normalizeSubfieldValue(value)}));
+
+ const equalSubfieldsBase = baseSubsNormalized
+ .filter(baseSubfield => sourceSubsNormalized
+ .some(sourceSubfield => equalityFunction(baseSubfield, sourceSubfield)));
+
+ const equalSubfieldsSource = sourceSubsNormalized
+ .filter(sourceSubfield => baseSubsNormalized
+ .some(baseSubfield => equalityFunction(sourceSubfield, baseSubfield)));
+
+ if (baseSubs.length === sourceSubs.length && equalSubfieldsBase.length < baseSubs.length) {
+ return base;
+ }
+
+ if (baseSubs.length === sourceSubs.length && equalSubfieldsBase.length === equalSubfieldsSource.length) {
+ const totalSubfieldLengthBase = baseSubsNormalized
+ .map(({value}) => value.length)
+ .reduce((acc, value) => acc + value);
+ const totalSubfieldLengthSource = sourceSubsNormalized
+ .map(({value}) => value.length)
+ .reduce((acc, value) => acc + value);
+
+ if (totalSubfieldLengthSource > totalSubfieldLengthBase) {
+ return replaceBasefieldWithSourcefield(base);
+ }
+ }
+
+ if (sourceSubs.length > baseSubs.length && equalSubfieldsBase.length === baseSubs.length) {
+ return replaceBasefieldWithSourcefield(base);
+ }
+
+ return base;
+
+ function replaceBasefieldWithSourcefield(base) {
+ const index = base.fields.findIndex(field => field === baseField);
+ base.fields.splice(index, 1, sourceField); // eslint-disable-line functional/immutable-data
+ return base;
+ }
+
+ function checkFieldType(fields) {
+ const checkedFields = fields.map(field => {
+ if ('value' in field) { // eslint-disable-line functional/no-conditional-statement
+ throw new Error('Invalid control field, expected data field');
+ }
+ return field;
+ });
+ return checkedFields;
+ }
+
+ function normalizeSubfieldValue(value) {
+ // Regexp options: g: global search, u: unicode
+ const punctuation = /[.,\-/#!$%^&*;:{}=_`~()[\]]/gu;
+ return normalizeSync(value).toLowerCase().replace(punctuation, '', 'u').replace(/\s+/gu, ' ').trim();
+ }
+};
diff --git a/src/reducers/select.spec.js b/src/reducers/select.spec.js
new file mode 100644
index 0000000..dadf736
--- /dev/null
+++ b/src/reducers/select.spec.js
@@ -0,0 +1,64 @@
+/**
+*
+* @licstart The following is the entire license notice for the JavaScript code in this file.
+*
+* Merge MARC records
+*
+* Copyright (C) 2015-2019 University Of Helsinki (The National Library Of Finland)
+*
+* This file is part of marc-record-merge-js
+
+* marc-record-merge-js program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* marc-record-merge-js is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see .
+*
+* @licend The above is the entire license notice
+* for the JavaScript code in this file.
+*
+*/
+import chai from 'chai';
+import fs from 'fs';
+import path from 'path';
+import {MarcRecord} from '@natlibfi/marc-record';
+import createReducer, {subsetEquality} from './select';
+import fixturesFactory, {READERS} from '@natlibfi/fixura';
+
+MarcRecord.setValidationOptions({subfieldValues: false});
+
+describe('reducers/select', () => {
+ const {expect} = chai;
+ const fixturesPath = path.join(__dirname, '..', '..', 'test-fixtures', 'reducers', 'select');
+
+ fs.readdirSync(fixturesPath).forEach(subDir => {
+ const {getFixture} = fixturesFactory({root: [fixturesPath, subDir], reader: READERS.JSON, failWhenNotFound: false});
+ it(subDir, () => {
+ const baseTest = new MarcRecord(getFixture('base.json'));
+ const sourceTest = new MarcRecord(getFixture('source.json'));
+ const patternTest = new RegExp(getFixture({components: ['pattern.txt'], reader: READERS.TEXT}), 'u');
+ const expectedRecord = getFixture('merged.json');
+ const expectedError = getFixture({components: ['expected-error.txt'], reader: READERS.TEXT});
+ const equalityFunction = getEqualityFunction();
+
+ if (expectedError) {
+ expect(() => createReducer.to.throw(Error, 'control field'));
+ return;
+ }
+ const mergedRecord = createReducer({pattern: patternTest, equalityFunction})(baseTest, sourceTest);
+ expect(mergedRecord.toObject()).to.eql(expectedRecord);
+
+ function getEqualityFunction() {
+ const functionName = getFixture({components: ['equalityFunction.txt'], reader: READERS.TEXT});
+ return functionName === 'subsetEquality' ? subsetEquality : undefined;
+ }
+ });
+ });
+});
diff --git a/test-fixtures/reducers/select/01/base.json b/test-fixtures/reducers/select/01/base.json
new file mode 100644
index 0000000..11156dc
--- /dev/null
+++ b/test-fixtures/reducers/select/01/base.json
@@ -0,0 +1,21 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "value": "this is wrong",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/01/expected-error.txt b/test-fixtures/reducers/select/01/expected-error.txt
new file mode 100644
index 0000000..ce46aee
--- /dev/null
+++ b/test-fixtures/reducers/select/01/expected-error.txt
@@ -0,0 +1 @@
+Invalid control field, expected data field
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/01/merged.json b/test-fixtures/reducers/select/01/merged.json
new file mode 100644
index 0000000..51f3ea0
--- /dev/null
+++ b/test-fixtures/reducers/select/01/merged.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/01/pattern.txt b/test-fixtures/reducers/select/01/pattern.txt
new file mode 100644
index 0000000..ca77554
--- /dev/null
+++ b/test-fixtures/reducers/select/01/pattern.txt
@@ -0,0 +1 @@
+^010$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/01/source.json b/test-fixtures/reducers/select/01/source.json
new file mode 100644
index 0000000..51f3ea0
--- /dev/null
+++ b/test-fixtures/reducers/select/01/source.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/02/base.json b/test-fixtures/reducers/select/02/base.json
new file mode 100644
index 0000000..1e0d580
--- /dev/null
+++ b/test-fixtures/reducers/select/02/base.json
@@ -0,0 +1,31 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Hello world"
+ }
+ ]
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "b",
+ "value": "goodbye world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/02/merged.json b/test-fixtures/reducers/select/02/merged.json
new file mode 100644
index 0000000..1e0d580
--- /dev/null
+++ b/test-fixtures/reducers/select/02/merged.json
@@ -0,0 +1,31 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Hello world"
+ }
+ ]
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "b",
+ "value": "goodbye world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/02/pattern.txt b/test-fixtures/reducers/select/02/pattern.txt
new file mode 100644
index 0000000..ca77554
--- /dev/null
+++ b/test-fixtures/reducers/select/02/pattern.txt
@@ -0,0 +1 @@
+^010$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/02/source.json b/test-fixtures/reducers/select/02/source.json
new file mode 100644
index 0000000..dab3bec
--- /dev/null
+++ b/test-fixtures/reducers/select/02/source.json
@@ -0,0 +1,42 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "hello world"
+ }
+ ]
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "b",
+ "value": "goodbye world"
+ }
+ ]
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "c",
+ "value": "have a nice day"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/03/base.json b/test-fixtures/reducers/select/03/base.json
new file mode 100644
index 0000000..01bd9af
--- /dev/null
+++ b/test-fixtures/reducers/select/03/base.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/03/merged.json b/test-fixtures/reducers/select/03/merged.json
new file mode 100644
index 0000000..01bd9af
--- /dev/null
+++ b/test-fixtures/reducers/select/03/merged.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/03/pattern.txt b/test-fixtures/reducers/select/03/pattern.txt
new file mode 100644
index 0000000..ca77554
--- /dev/null
+++ b/test-fixtures/reducers/select/03/pattern.txt
@@ -0,0 +1 @@
+^010$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/03/source.json b/test-fixtures/reducers/select/03/source.json
new file mode 100644
index 0000000..01bd9af
--- /dev/null
+++ b/test-fixtures/reducers/select/03/source.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/04/base.json b/test-fixtures/reducers/select/04/base.json
new file mode 100644
index 0000000..01bd9af
--- /dev/null
+++ b/test-fixtures/reducers/select/04/base.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/04/merged.json b/test-fixtures/reducers/select/04/merged.json
new file mode 100644
index 0000000..01bd9af
--- /dev/null
+++ b/test-fixtures/reducers/select/04/merged.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/04/pattern.txt b/test-fixtures/reducers/select/04/pattern.txt
new file mode 100644
index 0000000..edc20ea
--- /dev/null
+++ b/test-fixtures/reducers/select/04/pattern.txt
@@ -0,0 +1 @@
+^(010|020)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/04/source.json b/test-fixtures/reducers/select/04/source.json
new file mode 100644
index 0000000..70096b3
--- /dev/null
+++ b/test-fixtures/reducers/select/04/source.json
@@ -0,0 +1,20 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "020",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "hello world"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/05/base.json b/test-fixtures/reducers/select/05/base.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/05/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/05/merged.json b/test-fixtures/reducers/select/05/merged.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/05/merged.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/05/pattern.txt b/test-fixtures/reducers/select/05/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/05/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/05/source.json b/test-fixtures/reducers/select/05/source.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/05/source.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/06/base.json b/test-fixtures/reducers/select/06/base.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/06/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/06/merged.json b/test-fixtures/reducers/select/06/merged.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/06/merged.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/06/pattern.txt b/test-fixtures/reducers/select/06/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/06/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/06/source.json b/test-fixtures/reducers/select/06/source.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/06/source.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/07/base.json b/test-fixtures/reducers/select/07/base.json
new file mode 100644
index 0000000..116e53c
--- /dev/null
+++ b/test-fixtures/reducers/select/07/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ "
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/07/equalityFunction.txt b/test-fixtures/reducers/select/07/equalityFunction.txt
new file mode 100644
index 0000000..dbeac21
--- /dev/null
+++ b/test-fixtures/reducers/select/07/equalityFunction.txt
@@ -0,0 +1 @@
+subsetEquality
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/07/merged.json b/test-fixtures/reducers/select/07/merged.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/07/merged.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/07/pattern.txt b/test-fixtures/reducers/select/07/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/07/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/07/source.json b/test-fixtures/reducers/select/07/source.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/07/source.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/08/base.json b/test-fixtures/reducers/select/08/base.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/08/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/08/merged.json b/test-fixtures/reducers/select/08/merged.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/08/merged.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/08/pattern.txt b/test-fixtures/reducers/select/08/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/08/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/08/source.json b/test-fixtures/reducers/select/08/source.json
new file mode 100644
index 0000000..2c1f2fe
--- /dev/null
+++ b/test-fixtures/reducers/select/08/source.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/09/base.json b/test-fixtures/reducers/select/09/base.json
new file mode 100644
index 0000000..f173ff2
--- /dev/null
+++ b/test-fixtures/reducers/select/09/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": "Boo"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/09/merged.json b/test-fixtures/reducers/select/09/merged.json
new file mode 100644
index 0000000..f173ff2
--- /dev/null
+++ b/test-fixtures/reducers/select/09/merged.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": "Boo"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/09/pattern.txt b/test-fixtures/reducers/select/09/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/09/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/09/source.json b/test-fixtures/reducers/select/09/source.json
new file mode 100644
index 0000000..25e4c25
--- /dev/null
+++ b/test-fixtures/reducers/select/09/source.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Höwdy Êárth"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/10/base.json b/test-fixtures/reducers/select/10/base.json
new file mode 100644
index 0000000..38a8713
--- /dev/null
+++ b/test-fixtures/reducers/select/10/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/10/equalityFunction.txt b/test-fixtures/reducers/select/10/equalityFunction.txt
new file mode 100644
index 0000000..dbeac21
--- /dev/null
+++ b/test-fixtures/reducers/select/10/equalityFunction.txt
@@ -0,0 +1 @@
+subsetEquality
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/10/merged.json b/test-fixtures/reducers/select/10/merged.json
new file mode 100644
index 0000000..790826f
--- /dev/null
+++ b/test-fixtures/reducers/select/10/merged.json
@@ -0,0 +1,28 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ },
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/10/pattern.txt b/test-fixtures/reducers/select/10/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/10/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/10/source.json b/test-fixtures/reducers/select/10/source.json
new file mode 100644
index 0000000..790826f
--- /dev/null
+++ b/test-fixtures/reducers/select/10/source.json
@@ -0,0 +1,28 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ },
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/11/base.json b/test-fixtures/reducers/select/11/base.json
new file mode 100644
index 0000000..f173ff2
--- /dev/null
+++ b/test-fixtures/reducers/select/11/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": "Boo"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/11/merged.json b/test-fixtures/reducers/select/11/merged.json
new file mode 100644
index 0000000..f173ff2
--- /dev/null
+++ b/test-fixtures/reducers/select/11/merged.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": "Boo"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/11/pattern.txt b/test-fixtures/reducers/select/11/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/11/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/11/source.json b/test-fixtures/reducers/select/11/source.json
new file mode 100644
index 0000000..857e6ac
--- /dev/null
+++ b/test-fixtures/reducers/select/11/source.json
@@ -0,0 +1,28 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Höwdy Êárth"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ },
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/12/base.json b/test-fixtures/reducers/select/12/base.json
new file mode 100644
index 0000000..8448a2a
--- /dev/null
+++ b/test-fixtures/reducers/select/12/base.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ "
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/12/equalityFunction.txt b/test-fixtures/reducers/select/12/equalityFunction.txt
new file mode 100644
index 0000000..dbeac21
--- /dev/null
+++ b/test-fixtures/reducers/select/12/equalityFunction.txt
@@ -0,0 +1 @@
+subsetEquality
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/12/merged.json b/test-fixtures/reducers/select/12/merged.json
new file mode 100644
index 0000000..790826f
--- /dev/null
+++ b/test-fixtures/reducers/select/12/merged.json
@@ -0,0 +1,28 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ },
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/12/pattern.txt b/test-fixtures/reducers/select/12/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/12/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/12/source.json b/test-fixtures/reducers/select/12/source.json
new file mode 100644
index 0000000..790826f
--- /dev/null
+++ b/test-fixtures/reducers/select/12/source.json
@@ -0,0 +1,28 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ },
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/13/base.json b/test-fixtures/reducers/select/13/base.json
new file mode 100644
index 0000000..790826f
--- /dev/null
+++ b/test-fixtures/reducers/select/13/base.json
@@ -0,0 +1,28 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ },
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/13/merged.json b/test-fixtures/reducers/select/13/merged.json
new file mode 100644
index 0000000..790826f
--- /dev/null
+++ b/test-fixtures/reducers/select/13/merged.json
@@ -0,0 +1,28 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ .,-/ Wörld .,-/#!$%^&*;:{}=_`~()[]"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ #!$%ËÑĶãýğĝŧŵ"
+ },
+ {
+ "code": "c",
+ "value": "And now for something completely different"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/13/pattern.txt b/test-fixtures/reducers/select/13/pattern.txt
new file mode 100644
index 0000000..f91ea72
--- /dev/null
+++ b/test-fixtures/reducers/select/13/pattern.txt
@@ -0,0 +1 @@
+^(010)$
\ No newline at end of file
diff --git a/test-fixtures/reducers/select/13/source.json b/test-fixtures/reducers/select/13/source.json
new file mode 100644
index 0000000..8448a2a
--- /dev/null
+++ b/test-fixtures/reducers/select/13/source.json
@@ -0,0 +1,24 @@
+{
+ "leader": "01331cam a22003494i 4500",
+ "fields": [
+ {
+ "tag": "001",
+ "value": "007346734"
+ },
+ {
+ "tag": "010",
+ "ind1": " ",
+ "ind2": " ",
+ "subfields": [
+ {
+ "code": "a",
+ "value": "Héllõ"
+ },
+ {
+ "code": "b",
+ "value": " çšŕ#!$%ňŭųœ "
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file