@natlibfi/marc-record-merge 6.0.0-beta.9 → 7.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.github/CODEOWNERS +2 -9
  2. package/.github/dependabot.yml +2 -3
  3. package/.github/workflows/melinda-node-tests.yml +2 -2
  4. package/dist/index.js +49 -4
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.spec.js +59 -0
  7. package/dist/index.spec.js.map +1 -0
  8. package/dist/reducers/copy.js +52 -62
  9. package/dist/reducers/copy.js.map +1 -1
  10. package/dist/reducers/copy.spec.js +6 -8
  11. package/dist/reducers/copy.spec.js.map +1 -1
  12. package/dist/reducers/copy2.spec.js +66 -0
  13. package/dist/reducers/copy2.spec.js.map +1 -0
  14. package/dist/reducers/index.js +0 -6
  15. package/dist/reducers/index.js.map +1 -1
  16. package/dist/reducers/select.js +43 -40
  17. package/dist/reducers/select.js.map +1 -1
  18. package/dist/reducers/select.spec.js +4 -15
  19. package/dist/reducers/select.spec.js.map +1 -1
  20. package/dist/reducers/select2.spec.js +58 -0
  21. package/dist/reducers/select2.spec.js.map +1 -0
  22. package/package.json +18 -18
  23. package/src/index.js +51 -1
  24. package/src/index.spec.js +45 -0
  25. package/src/reducers/copy.js +34 -8
  26. package/src/reducers/copy.spec.js +3 -1
  27. package/src/reducers/copy2.spec.js +55 -0
  28. package/src/reducers/select.js +31 -10
  29. package/src/reducers/select2.spec.js +49 -0
  30. package/test-fixtures/index/01/base.json +24 -0
  31. package/test-fixtures/index/01/merged.json +24 -0
  32. package/test-fixtures/index/01/metadata.json +8 -0
  33. package/test-fixtures/index/01/source.json +40 -0
  34. package/test-fixtures/index/02/base.json +24 -0
  35. package/test-fixtures/index/02/merged.json +24 -0
  36. package/test-fixtures/index/02/metadata.json +7 -0
  37. package/test-fixtures/index/02/source.json +40 -0
  38. package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/03/metadata.json +6 -0
  39. package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/base.json +20 -0
  40. package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/merged.json +31 -0
  41. package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/metadata.json +5 -0
  42. package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/source.json +20 -0
  43. package/test-fixtures/reducers/copy/11 - compareWithoutTag/01/base.json +11 -0
  44. package/test-fixtures/reducers/copy/11 - compareWithoutTag/01/metadata.json +1 -2
  45. package/test-fixtures/reducers/copy/11 - compareWithoutTag/01/source.json +0 -11
  46. package/test-fixtures/reducers/copy/11 - compareWithoutTag/02/merged.json +11 -0
  47. package/test-fixtures/reducers/copy/11 - compareWithoutTag/02/metadata.json +1 -2
  48. package/test-fixtures/reducers/copy/11 - compareWithoutTag/02/source.json +6 -3
  49. package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/base.json +17 -0
  50. package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/merged.json +28 -0
  51. package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/metadata.json +7 -0
  52. package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/source.json +31 -0
  53. package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/base.json +28 -0
  54. package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/merged.json +28 -0
  55. package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/metadata.json +7 -0
  56. package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/source.json +28 -0
package/package.json CHANGED
@@ -14,10 +14,10 @@
14
14
  "url": "git@github.com:natlibfi/marc-record-merge-js.git"
15
15
  },
16
16
  "license": "MIT",
17
- "version": "6.0.0-beta.9",
17
+ "version": "7.0.0-alpha.1",
18
18
  "main": "./dist/index.js",
19
19
  "engines": {
20
- "node": ">=14"
20
+ "node": ">=18"
21
21
  },
22
22
  "type": "commonjs",
23
23
  "scripts": {
@@ -25,8 +25,8 @@
25
25
  "prepublishOnly": "npm run build:transpile",
26
26
  "lint": "eslint ./src",
27
27
  "lint:dev": "eslint ./src --fix",
28
- "test:base": "cross-env NODE_ENV=test mocha --require @babel/register --reporter-option maxDiffSize=15000 src/reducers/*.spec.js",
29
- "test": "npm run lint && npm run test:base",
28
+ "test:base": "cross-env NODE_ENV=test mocha --require @babel/register --reporter-option maxDiffSize=15000",
29
+ "test": "npm run lint && npm run test:base -- --recursive src",
30
30
  "test:dev": "npm run lint:dev && npm run coverage",
31
31
  "coverage": "npm run coverage:unit && npm run coverage:report",
32
32
  "coverage:unit": "nyc --silent npm run test:base",
@@ -37,26 +37,26 @@
37
37
  "dev:test:debug": "cross-env DEBUG=@natlibfi/* NODE_ENV=test nodemon -w src -w test-fixtures --exec 'clear && npm run test:dev'"
38
38
  },
39
39
  "dependencies": {
40
- "@natlibfi/fixugen": "1.1.0",
41
- "@natlibfi/fixura": "^2.2.1",
42
- "@natlibfi/marc-record": "^7.1.0-alpha.2",
40
+ "@natlibfi/marc-record": "^7.2.2",
43
41
  "debug": "^4.3.4",
44
- "normalize-diacritics": "2.14.0"
42
+ "normalize-diacritics": "^2.13.2"
45
43
  },
46
44
  "devDependencies": {
47
- "@babel/cli": "^7.17.10",
48
- "@babel/core": "^7.18.5",
49
- "@babel/eslint-parser": "^7.18.2",
50
- "@babel/preset-env": "^7.18.2",
51
- "@babel/register": "^7.17.7",
52
- "@natlibfi/eslint-config-melinda-backend": "^2.0.0",
45
+ "@babel/cli": "^7.21.0",
46
+ "@babel/core": "^7.21.4",
47
+ "@babel/eslint-parser": "^7.21.3",
48
+ "@babel/preset-env": "^7.21.4",
49
+ "@babel/register": "^7.21.0",
50
+ "@natlibfi/eslint-config-melinda-backend": "^3.0.0",
53
51
  "babel-plugin-istanbul": "^6.1.1",
54
52
  "babel-plugin-rewire": "^1.2.0",
55
- "chai": "^4.3.6",
53
+ "chai": "^4.3.7",
56
54
  "cross-env": "^7.0.3",
57
- "eslint": "^8.17.0",
58
- "mocha": "^10.0.0",
59
- "nodemon": "^2.0.16",
55
+ "eslint": "^8.38.0",
56
+ "mocha": "^10.2.0",
57
+ "@natlibfi/fixugen": "2.0.0",
58
+ "@natlibfi/fixura": "^3.0.0",
59
+ "nodemon": "^2.0.22",
60
60
  "nyc": "^15.1.0"
61
61
  },
62
62
  "eslintConfig": {
package/src/index.js CHANGED
@@ -1,4 +1,54 @@
1
1
  import Reducers from './reducers';
2
+ import createDebugLogger from 'debug';
3
+
4
+ const debug = createDebugLogger('@natlibfi/melinda-marc-record-merge:index');
5
+ const debugData = debug.extend('data');
2
6
 
3
7
  export {Reducers};
4
- export default ({base, source, reducers}) => reducers.reduce((base, reducer) => reducer(base, source), base);
8
+ // export default ({base, source, reducers}) => reducers.reduce((base, reducer) => reducer(base, source), base);
9
+
10
+ // NV: Modified the reducer loop so, that not only base, but also is carried back.
11
+ // However, we try to be backward-compatible: normally after the reducers, only base is returned.
12
+
13
+ export default ({base, source, reducers}) => {
14
+
15
+ const combo = {base, source};
16
+ const resultCombo = reducers.reduce((combo, reducer) => {
17
+ const returnCombo = singleRound(reducer, combo.base, combo.source);
18
+ //debugData(`returnCombo after current reducer: ${JSON.stringify(returnCombo)}`);
19
+ return returnCombo;
20
+ }, combo);
21
+
22
+ debugData(`ResultCombo after reducers: ${JSON.stringify(resultCombo)}`);
23
+
24
+ // Hack to make my melinda-marc-record-merge-reducers single tests that expect both
25
+ // base and source to return them both:
26
+ if (reducers.length === 1 && resultCombo.base && resultCombo.source) {
27
+ debug('Single reducer, returning resultCombo');
28
+ debugData(JSON.stringify(resultCombo));
29
+
30
+ return resultCombo;
31
+ }
32
+ // All other tests return just base... Backward (compability) it is!
33
+ debug('Multiple reducers, returning just base');
34
+ debugData(JSON.stringify(resultCombo.base));
35
+ return resultCombo.base;
36
+
37
+ function singleRound(reducer, base, source) {
38
+ //debug(`SINGLE ROUND INPUT (base, source)`);
39
+ //debugData(base);
40
+ //debugData(base);
41
+ const reducerResult = reducer(base, source);
42
+ //debug(`reducerResult:`);
43
+ //debugData(reducerResult);
44
+ if (reducerResult.base !== undefined && reducerResult.source !== undefined) {
45
+ debug('NEW STYLE REDUCER RESULT v2');
46
+ const combo = reducerResult;
47
+ //debugData(combo);
48
+ return combo;
49
+ }
50
+ debug('OLD SCHOOL REDUCER RESULT v2');
51
+ //debugData({base: reducerResult, source});
52
+ return {base: reducerResult, source};
53
+ }
54
+ };
@@ -0,0 +1,45 @@
1
+ import merger, {Reducers} from './index';
2
+ import {inspect} from 'util';
3
+ import createDebugLogger from 'debug';
4
+ import {expect} from 'chai';
5
+ import {MarcRecord} from '@natlibfi/marc-record';
6
+ import {READERS} from '@natlibfi/fixura';
7
+ import generateTests from '@natlibfi/fixugen';
8
+
9
+ generateTests({
10
+ callback,
11
+ path: [__dirname, '..', 'test-fixtures', 'index'],
12
+ recurse: false,
13
+ useMetadataFile: true,
14
+ fixura: {
15
+ failWhenNotFound: false,
16
+ reader: READERS.JSON
17
+ }
18
+ });
19
+
20
+ function callback({getFixture, reducerConfigs = []}) {
21
+ const base = new MarcRecord(getFixture('base.json'), {subfieldValues: false});
22
+ const source = new MarcRecord(getFixture('source.json'), {subfieldValues: false});
23
+ const expectedRecord = getFixture('merged.json');
24
+
25
+ const debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:index:test');
26
+ const debugData = debug.extend('data');
27
+
28
+ const testReducerConfigs = reducerConfigs;
29
+ const reducers = [...testReducerConfigs.map(conf => Reducers.copy(conf))];
30
+
31
+ debugData(`Reducers: ${inspect(reducers, {colors: true, maxArrayLength: 10, depth: 8})})}`);
32
+
33
+ const result = merger({base, source, reducers});
34
+
35
+ debug(`Merge result is: ${result.constructor.name}`);
36
+ debugData(`${JSON.stringify(result)}`);
37
+
38
+ // Use either result.base or a plain result as resultRecord
39
+ // It can also be a MarcRecord or a plain object
40
+ const resultRecord = result.base || result;
41
+ const resultRecordToRecord = new MarcRecord(resultRecord, {subfieldValues: false});
42
+ expect(resultRecordToRecord.toObject()).to.eql(expectedRecord);
43
+
44
+
45
+ }
@@ -9,6 +9,8 @@ export default ({
9
9
  compareTagsOnly = false,
10
10
  compareWithoutTag = false,
11
11
  compareWithoutIndicators = false,
12
+ compareWithoutIndicator1 = false,
13
+ compareWithoutIndicator2 = false,
12
14
  subfieldsMustBeIdentical = true,
13
15
  excludeSubfields = [],
14
16
  dropSubfields = [],
@@ -19,15 +21,37 @@ export default ({
19
21
  swapSubfieldCode = [],
20
22
  doNotCopyIfFieldPresent = false
21
23
  }) => (base, source) => {
22
- const baseRecord = new MarcRecord(base, baseValidators);
23
- const sourceRecord = new MarcRecord(source, sourceValidators);
24
24
 
25
- const debug = createDebugLogger('@natlibfi/marc-record-merge');
25
+ const debug = createDebugLogger('@natlibfi/marc-record-merge:copy');
26
+ const debugData = debug.extend('data');
26
27
  const debugOptions = createDebugLogger('@natlibfi/marc-record-merge:compare-options');
27
28
  const debugCompare = createDebugLogger('@natlibfi/marc-record-merge:compare');
29
+
30
+ debugData(`base: ${JSON.stringify(base)}`);
31
+ debugData(`source: ${JSON.stringify(source)}`);
32
+
33
+ const {baseRecord, sourceRecord} = getRecordsFromParameters(base, source, baseValidators, sourceValidators);
34
+
35
+ function getRecordsFromParameters(base, source, baseValidators, sourceValidators) {
36
+ // records if we got an object ({base, source}) as a parameter
37
+ if (source === undefined && base.base !== undefined && base.source !== undefined) {
38
+ const baseRecord = new MarcRecord(base.base, baseValidators);
39
+ const sourceRecord = new MarcRecord(base.source, sourceValidators);
40
+ return {baseRecord, sourceRecord};
41
+ }
42
+ // records if we got an non-object (base, source) as a parameter
43
+ const baseRecord = new MarcRecord(base, baseValidators);
44
+ const sourceRecord = new MarcRecord(source, sourceValidators);
45
+ return {baseRecord, sourceRecord};
46
+ }
47
+
48
+ const ignoreInd1 = compareWithoutIndicators || compareWithoutIndicator1;
49
+ const ignoreInd2 = compareWithoutIndicators || compareWithoutIndicator2;
50
+
28
51
  debugOptions(`Tag Pattern: ${tagPattern}`);
29
52
  debugOptions(`Compare tags only: ${compareTagsOnly}`);
30
- debugOptions(`Compare without indicators ${compareWithoutIndicators}`);
53
+ debugOptions(`Omit indicator 1 from comparison: ${ignoreInd1}`);
54
+ debugOptions(`Omit indicator 2 from comparison: ${ignoreInd2}`);
31
55
  debugOptions(`Copy if identical: ${subfieldsMustBeIdentical}`);
32
56
  debugOptions(`Exclude subfields: [${excludeSubfields}]`);
33
57
  debugOptions(`Drop subfields [${dropSubfields}]`);
@@ -40,7 +64,7 @@ export default ({
40
64
  if (doNotCopy) {
41
65
  return baseRecord.toObject();
42
66
  }
43
-
67
+ debug(`FFS: ${compareWithoutIndicator1}, ${compareWithoutIndicators}, ${ignoreInd1}`);
44
68
  debug(`Base fields: `, baseFields);
45
69
  debug(`Source fields: `, sourceFields);
46
70
 
@@ -57,6 +81,8 @@ export default ({
57
81
 
58
82
  // Add fields to base;
59
83
  uniqueFields.forEach(field => baseRecord.insertField(field));
84
+ debugData(`baseRecord before return: ${JSON.stringify(baseRecord)}`);
85
+ //return baseRecord;
60
86
  return baseRecord.toObject();
61
87
 
62
88
  function compareFields(sourceFields, baseCompareFields, uniqFields = []) {
@@ -132,7 +158,7 @@ export default ({
132
158
  }
133
159
  }
134
160
 
135
- // compare objects have only fields that matter in comparing
161
+ // compare objects have only fields that matter in comparison
136
162
  function createCompareField(field) {
137
163
  if (compareTagsOnly) {
138
164
  return {tag: field.tag};
@@ -148,8 +174,8 @@ export default ({
148
174
 
149
175
  const params = [
150
176
  {name: 'tag', value: compareWithoutTag ? replacementTag : field.tag},
151
- {name: 'ind1', value: compareWithoutIndicators ? undefined : field.ind1},
152
- {name: 'ind2', value: compareWithoutIndicators ? undefined : field.ind2},
177
+ {name: 'ind1', value: ignoreInd1 ? undefined : field.ind1},
178
+ {name: 'ind2', value: ignoreInd2 ? undefined : field.ind2},
153
179
  {name: 'subfields', value: createCompareSubfields(filteredField.subfields)}
154
180
  ].map(param => [param.name, param.value]);
155
181
 
@@ -23,6 +23,8 @@ function callback({
23
23
  compareTagsOnly = false,
24
24
  compareWithoutTag = false,
25
25
  compareWithoutIndicators = false,
26
+ compareWithoutIndicator1 = false,
27
+ compareWithoutIndicator2 = false,
26
28
  subfieldsMustBeIdentical = false,
27
29
  copyUnless = undefined,
28
30
  excludeSubfields = undefined,
@@ -37,7 +39,7 @@ function callback({
37
39
  const expectedRecord = getFixture('merged.json');
38
40
 
39
41
  const merged = createReducer({
40
- tagPattern, compareTagsOnly, compareWithoutTag, compareWithoutIndicators,
42
+ tagPattern, compareTagsOnly, compareWithoutTag, compareWithoutIndicators, compareWithoutIndicator1, compareWithoutIndicator2,
41
43
  copyUnless, subfieldsMustBeIdentical, excludeSubfields,
42
44
  dropSubfields, swapSubfieldCode, swapTag,
43
45
  doNotCopyIfFieldPresent
@@ -0,0 +1,55 @@
1
+ import {expect} from 'chai';
2
+ import {READERS} from '@natlibfi/fixura';
3
+ import createReducer from './copy';
4
+ import generateTests from '@natlibfi/fixugen';
5
+
6
+ //import createDebugLogger from 'debug'; // <---
7
+ //const debug = createDebugLogger('@natlibfi/marc-record-merge/copy.spec.js'); // <---
8
+
9
+ generateTests({
10
+ callback,
11
+ path: [__dirname, '..', '..', 'test-fixtures', 'reducers', 'copy'],
12
+ useMetadataFile: true,
13
+ recurse: true,
14
+ fixura: {
15
+ reader: READERS.JSON,
16
+ failWhenNotFound: false
17
+ }
18
+ });
19
+
20
+
21
+ function callback({
22
+ getFixture,
23
+ tagPatternRegExp,
24
+ compareTagsOnly = false,
25
+ compareWithoutTag = false,
26
+ compareWithoutIndicators = false,
27
+ compareWithoutIndicator1 = false,
28
+ compareWithoutIndicator2 = false,
29
+ subfieldsMustBeIdentical = false,
30
+ copyUnless = undefined,
31
+ excludeSubfields = undefined,
32
+ dropSubfields = undefined,
33
+ swapSubfieldCode = [],
34
+ swapTag = [],
35
+ doNotCopyIfFieldPresent = false
36
+ }) {
37
+ const base = getFixture('base.json');
38
+ const source = getFixture('source.json');
39
+ const tagPattern = new RegExp(tagPatternRegExp, 'u');
40
+ const expectedRecord = getFixture('merged.json');
41
+
42
+ const merged = createReducer({
43
+ tagPattern, compareTagsOnly, compareWithoutTag, compareWithoutIndicators, compareWithoutIndicator1, compareWithoutIndicator2,
44
+ copyUnless, subfieldsMustBeIdentical, excludeSubfields,
45
+ dropSubfields, swapSubfieldCode, swapTag,
46
+ doNotCopyIfFieldPresent
47
+ })({base, source});
48
+ //debug(`*** mergedRecord: `, mergedRecord); //<--
49
+ //debug(`*** mergedRecord,Strfy: `, JSON.stringify(mergedRecord)); //<--
50
+ //debug(`*** expectedRecord: `, expectedRecord); //<--
51
+ //debug(`*** expectedRecord,Strfy: `, JSON.stringify(expectedRecord)); //<--
52
+ expect(merged.constructor.name).not.to.eql('MarcRecord');
53
+ expect(merged.constructor.name).to.eql('Object');
54
+ expect(merged).to.eql(expectedRecord);
55
+ }
@@ -12,10 +12,31 @@ export function subsetEquality(subfieldA, subfieldB) {
12
12
  (subfieldA.value.indexOf(subfieldB.value) !== -1 || subfieldB.value.indexOf(subfieldA.value) !== -1);
13
13
  }
14
14
  // EqualityFunction can be either strictEquality or subsetEquality
15
- export default ({tagPattern, equalityFunction = strictEquality}) => (base, source) => {
15
+
16
+ export default ({
17
+ tagPattern,
18
+ equalityFunction = strictEquality,
19
+ baseValidators = {subfieldValues: false},
20
+ sourceValidators = {subfieldValues: false}
21
+ // eslint-disable-next-line max-statements
22
+ }) => (base, source) => {
16
23
  const debug = createDebugLogger('@natlibfi/marc-record-merge:select');
17
- const baseRecord = new MarcRecord(base, {subfieldValues: false});
18
- const sourceRecord = new MarcRecord(source, {subfieldValues: false});
24
+
25
+ const {baseRecord, sourceRecord} = getRecordsFromParameters(base, source, baseValidators, sourceValidators);
26
+
27
+ function getRecordsFromParameters(base, source, baseValidators, sourceValidators) {
28
+ // records if we got an object ({base, source}) as a parameter
29
+ if (source === undefined && base.base !== undefined && base.source !== undefined) {
30
+ const baseRecord = new MarcRecord(base.base, baseValidators);
31
+ const sourceRecord = new MarcRecord(base.source, sourceValidators);
32
+ return {baseRecord, sourceRecord};
33
+ }
34
+ // records if we got an non-object (base, source) as a parameter
35
+ const baseRecord = new MarcRecord(base, baseValidators);
36
+ const sourceRecord = new MarcRecord(source, sourceValidators);
37
+ return {baseRecord, sourceRecord};
38
+ }
39
+
19
40
  const baseFields = baseRecord.get(tagPattern);
20
41
  const sourceFields = sourceRecord.get(tagPattern);
21
42
  const fieldTag = sourceFields.map(field => field.tag);
@@ -27,7 +48,7 @@ export default ({tagPattern, equalityFunction = strictEquality}) => (base, sourc
27
48
  if (baseFields.length > 1 || sourceFields.length > 1) {
28
49
  debug(`Multiple fields in base or source`);
29
50
  debug(`No changes to base`);
30
- return base;
51
+ return baseRecord.toObject();
31
52
  }
32
53
  const [baseField] = baseFields;
33
54
  const [sourceField] = sourceFields;
@@ -35,7 +56,7 @@ export default ({tagPattern, equalityFunction = strictEquality}) => (base, sourc
35
56
  if (baseField.tag === sourceField.tag === false) {
36
57
  debug(`Base tag ${baseField.tag} is not equal to source tag ${sourceField.tag}`);
37
58
  debug(`No changes to base`);
38
- return base;
59
+ return baseRecord.toObject();
39
60
  }
40
61
  const baseSubs = baseField.subfields;
41
62
  const sourceSubs = sourceField.subfields;
@@ -61,7 +82,7 @@ export default ({tagPattern, equalityFunction = strictEquality}) => (base, sourc
61
82
  if (baseSubs.length === sourceSubs.length && equalSubfieldsBase.length < baseSubs.length) {
62
83
  debug(`Base and source subfields are not equal`);
63
84
  debug(`No changes to base`);
64
- return base;
85
+ return baseRecord.toObject();
65
86
  }
66
87
 
67
88
  if (baseSubs.length === sourceSubs.length && equalSubfieldsBase.length === equalSubfieldsSource.length) {
@@ -74,16 +95,16 @@ export default ({tagPattern, equalityFunction = strictEquality}) => (base, sourc
74
95
  .reduce((acc, value) => acc + value);
75
96
 
76
97
  if (totalSubfieldLengthSource > totalSubfieldLengthBase) {
77
- return replaceBasefieldWithSourcefield(base);
98
+ return replaceBasefieldWithSourcefield(baseRecord.toObject());
78
99
  }
79
100
  }
80
101
 
81
102
  if (sourceSubs.length > baseSubs.length && equalSubfieldsBase.length === baseSubs.length) {
82
- return replaceBasefieldWithSourcefield(base);
103
+ return replaceBasefieldWithSourcefield(baseRecord.toObject());
83
104
  }
84
105
 
85
106
  debug(`No changes to base`);
86
- return base;
107
+ return baseRecord.toObject();
87
108
 
88
109
  function replaceBasefieldWithSourcefield(base) {
89
110
  const index = base.fields.findIndex(field => field === baseField);
@@ -94,7 +115,7 @@ export default ({tagPattern, equalityFunction = strictEquality}) => (base, sourc
94
115
 
95
116
  function checkFieldType(fields) {
96
117
  const checkedFields = fields.map(field => {
97
- if ('value' in field) { // eslint-disable-line functional/no-conditional-statement
118
+ if ('value' in field) { // eslint-disable-line functional/no-conditional-statements
98
119
  throw new Error('Invalid control field, expected data field');
99
120
  }
100
121
  return field;
@@ -0,0 +1,49 @@
1
+ import {expect} from 'chai';
2
+ import {MarcRecord} from '@natlibfi/marc-record';
3
+ import createReducer, {subsetEquality} from './select';
4
+ import {READERS} from '@natlibfi/fixura';
5
+ import generateTests from '@natlibfi/fixugen';
6
+
7
+ MarcRecord.setValidationOptions({subfieldValues: false});
8
+
9
+ generateTests({
10
+ callback,
11
+ path: [__dirname, '..', '..', 'test-fixtures', 'reducers', 'select'],
12
+ useMetadataFile: true,
13
+ recurse: false,
14
+ fixura: {
15
+ reader: READERS.JSON,
16
+ failWhenNotFound: false
17
+ }
18
+ });
19
+
20
+ function callback({
21
+ getFixture,
22
+ disabled = false,
23
+ tagPatternRegExp = false,
24
+ expectedError = false,
25
+ useSubsetEquality = false
26
+ }) {
27
+ if (disabled) {
28
+ console.log('TEST DISABLED!'); // eslint-disable-line no-console
29
+ return;
30
+ }
31
+ // const base = new MarcRecord(getFixture('base.json'), {subfieldValues: false});
32
+ // const source = new MarcRecord(getFixture('source.json'), {subfieldValues: false});
33
+
34
+ const base = getFixture('base.json');
35
+ const source = getFixture('source.json');
36
+
37
+ const tagPattern = new RegExp(tagPatternRegExp, 'u');
38
+ const expectedRecord = getFixture('merged.json');
39
+ const equalityFunction = useSubsetEquality ? subsetEquality : undefined;
40
+
41
+ // Bypass expected error in testing
42
+ if (expectedError) {
43
+ expect(() => createReducer.to.throw(Error, 'control field'));
44
+ return;
45
+ }
46
+
47
+ const mergedRecord = createReducer({tagPattern, equalityFunction})({base, source});
48
+ expect(mergedRecord).to.eql(expectedRecord);
49
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "leader": "01331cam a22003494i 4500",
3
+ "fields": [
4
+ {
5
+ "tag": "001",
6
+ "value": "001_base"
7
+ },
8
+ {
9
+ "tag": "010",
10
+ "ind1": " ",
11
+ "ind2": " ",
12
+ "subfields": [
13
+ {
14
+ "code": "a",
15
+ "value": "010a_base"
16
+ },
17
+ {
18
+ "code": "b",
19
+ "value": "010b_base"
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "leader": "01331cam a22003494i 4500",
3
+ "fields": [
4
+ {
5
+ "tag": "001",
6
+ "value": "001_base"
7
+ },
8
+ {
9
+ "tag": "010",
10
+ "ind1": " ",
11
+ "ind2": " ",
12
+ "subfields": [
13
+ {
14
+ "code": "a",
15
+ "value": "010a_base"
16
+ },
17
+ {
18
+ "code": "b",
19
+ "value": "010b_base"
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "description":"Reducers should run after each another - two reducers",
3
+ "reducerConfigs": [
4
+ {"tagPattern": "/010/u", "compareTagsOnly": true},
5
+ {"tagPattern": "/33./u"}
6
+
7
+ ]
8
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "leader": "01331cam a22003494i 4500",
3
+ "fields": [
4
+ {
5
+ "tag": "001",
6
+ "value": "001_sorsa"
7
+ },
8
+ {
9
+ "tag": "010",
10
+ "ind1": " ",
11
+ "ind2": " ",
12
+ "subfields": [
13
+ {
14
+ "code": "a",
15
+ "value": "010a_sorsa"
16
+ },
17
+ {
18
+ "code": "b",
19
+ "value": "010b_sorsa"
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "tag": "650",
25
+ "ind1": " ",
26
+ "ind2": "7",
27
+ "subfields": [
28
+ {
29
+ "code": "a",
30
+ "value": "poista mut"
31
+ },
32
+ {
33
+ "code": "2",
34
+ "value": "ysa"
35
+ }
36
+ ]
37
+ }
38
+
39
+ ]
40
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "leader": "01331cam a22003494i 4500",
3
+ "fields": [
4
+ {
5
+ "tag": "001",
6
+ "value": "001_base"
7
+ },
8
+ {
9
+ "tag": "010",
10
+ "ind1": " ",
11
+ "ind2": " ",
12
+ "subfields": [
13
+ {
14
+ "code": "a",
15
+ "value": "010a_base"
16
+ },
17
+ {
18
+ "code": "b",
19
+ "value": "010b_base"
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "leader": "01331cam a22003494i 4500",
3
+ "fields": [
4
+ {
5
+ "tag": "001",
6
+ "value": "001_base"
7
+ },
8
+ {
9
+ "tag": "010",
10
+ "ind1": " ",
11
+ "ind2": " ",
12
+ "subfields": [
13
+ {
14
+ "code": "a",
15
+ "value": "010a_base"
16
+ },
17
+ {
18
+ "code": "b",
19
+ "value": "010b_base"
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "description":"Reducers should run after each another - single reducer",
3
+ "reducerConfigs": [
4
+ {"tagPattern": "/33./u"}
5
+ ],
6
+ "skip": false
7
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "leader": "01331cam a22003494i 4500",
3
+ "fields": [
4
+ {
5
+ "tag": "001",
6
+ "value": "001_sorsa"
7
+ },
8
+ {
9
+ "tag": "010",
10
+ "ind1": " ",
11
+ "ind2": " ",
12
+ "subfields": [
13
+ {
14
+ "code": "a",
15
+ "value": "010a_sorsa"
16
+ },
17
+ {
18
+ "code": "b",
19
+ "value": "010b_sorsa"
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "tag": "650",
25
+ "ind1": " ",
26
+ "ind2": "7",
27
+ "subfields": [
28
+ {
29
+ "code": "a",
30
+ "value": "poista mut"
31
+ },
32
+ {
33
+ "code": "2",
34
+ "value": "ysa"
35
+ }
36
+ ]
37
+ }
38
+
39
+ ]
40
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "description": "Copy fields 730: omit ind 1 from comparison - same field no copy",
3
+ "tagPatternRegExp": "^730$",
4
+ "compareWithoutIndicator1": true,
5
+ "skip": true
6
+ }