jenkins-bot has submitted this change and it was merged.

Change subject: Allow structured citoid fields to be flattened
......................................................................


Allow structured citoid fields to be flattened

In the case where the field in the citation is
an Array [] or a 2D Array [[]], allow the values
to be concatenated if the templateData field is
of a lower dimension. At the inner level of the
2D arrays, values are concatenated with a space
as separator. At the higher level or in 1D arrays,
values are concatenated with a comma and a space.

Bug: T97044
Change-Id: I9746a36b951647bf40f66769290b064dd0b6d302
---
M modules/tests/index.test.js
M modules/ve.ui.CiteFromIdInspector.js
2 files changed, 306 insertions(+), 78 deletions(-)

Approvals:
  Esanders: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/tests/index.test.js b/modules/tests/index.test.js
index e31a09d..fce860b 100644
--- a/modules/tests/index.test.js
+++ b/modules/tests/index.test.js
@@ -9,13 +9,14 @@
 /* Functions */
 
 /**
- * A function which creates a template given a templateData map
- * with a given citation, and compares it to the expected output.
- * @param  {Object} maps      templateData maps value
- * @param  {Object} citation  Citation in citoid mediawiki output format
- * @param  {Object} expected  Expected serialized template
- * @param  {Function} assert  QUnit assert function
- * @return {Object}           a Promise for the transclusion with added 
template
+ * Creates a template given a templateData map and citation,
+ * and compares it to the expected output.
+ *
+ * @param {Object} maps templateData maps value
+ * @param {Object} citation Citation in citoid mediawiki output format
+ * @param {Object} expected Expected serialized template
+ * @param {Function} assert QUnit assert function
+ * @returns {Object} a Promise for the transclusion with added template
  */
 var testMaps = function ( maps, citation, expected, assert ) {
        var serial,
@@ -1426,7 +1427,7 @@
        serial = template.serialize().template;
 
        // Make sure serialised template matches expected data
-       assert.deepEqual( expected, serial );
+       assert.deepEqual( serial, expected );
 
        return assert.ok( transclusion.addPart( template ) ) ; // Make sure 
template can be added to transclusion
 
@@ -1512,12 +1513,12 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
 
 QUnit.test( 'Invalid templateData; String (cit) / Array (td) mismatch', 2, 
function ( assert ) {
-       // This test mismatches a flat field in the citation data with an Array 
in the TemplateData
-       // Expected result is for the field to be skipped in the resulting 
template, and for no VE
-       // errors to be thrown.
+       // This test mismatches a flat field in the citation data (title) with 
an Array in the
+       // TemplateData. Expected result is for the field to be skipped in the 
resulting template,
+       // and for no VE errors to be thrown.
        var expected = {
                target: {
                        wt: 'Cite web',
@@ -1593,10 +1594,10 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
 
 QUnit.test( 'Invalid templateData; String (cit) / 2D Array (td) mismatch', 2, 
function ( assert ) {
-       // This test mismatches a flat field in the citation data with a 2D 
Array in the TemplateData
+       // This test mismatches a flat field in the citation data (title) with 
a 2D Array in the TemplateData
        // Expected result is for the field to be skipped in the resulting 
template, and for no VE
        // errors to be thrown.
        var expected = {
@@ -1674,12 +1675,12 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
 
-QUnit.test( 'Invalid templateData; Array (cit) / String (td) mismatch', 2, 
function ( assert ) {
-       // This test mismatches an Array in the citation data with a flat field 
in the TemplateData
-       // Expected result is for the field to be skipped in the resulting 
template, and for no VE
-       // errors to be thrown.
+QUnit.test( 'Mismatched templateData; Array (cit) / String (td) mismatch', 2, 
function ( assert ) {
+       // This test mismatches an Array in the citation data (isbn) with a 
flat field in the TemplateData
+       // Expected result is for the array to be turned into a string with the 
fields separated by
+       // a comma, and for no VE errors to be thrown.
        var expected = {
                target: {
                        wt: 'Cite web',
@@ -1691,6 +1692,9 @@
                        },
                        url: {
                                wt: 'http://www.example.com/'
+                       },
+                       isbn: {
+                               wt: '978-3-16-148410-0, 978-9-99-999999-x'
                        },
                        first: {
                                wt: 'First'
@@ -1714,7 +1718,7 @@
                url: 'http://www.example.com/',
                isbn: [ // Test example of Array
                        '978-3-16-148410-0',
-                       'this text should not appear anywhere'
+                       '978-9-99-999999-x'
                ],
                author: [
                        [ 'First', 'Last' ],
@@ -1755,10 +1759,10 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
 
-QUnit.test( 'Invalid templateData; Array (cit) / 2D Array (td) mismatch', 2, 
function ( assert ) {
-       // This test mismatches an Array in the citation data with a 2D array 
in the TemplateData
+QUnit.test( 'Mismatched templateData; Array (cit) / 2D Array (td) mismatch', 
2, function ( assert ) {
+       // This test mismatches a Array in the citation data (isbn) with a flat 
field in the TemplateData
        // Expected result is for the field to be skipped in the resulting 
template, and for no VE
        // errors to be thrown.
        var expected = {
@@ -1773,8 +1777,17 @@
                        url: {
                                wt: 'http://www.example.com/'
                        },
-                       isbn: {
-                               wt: '978-3-16-148410-0'
+                       first: {
+                               wt: 'First'
+                       },
+                       last: {
+                               wt: 'Last'
+                       },
+                       first2: {
+                               wt: 'First2'
+                       },
+                       last2: {
+                               wt: 'Last2'
                        }
                },
                i: 0
@@ -1784,7 +1797,85 @@
                title: 'Example Domain',
                itemType: 'webpage',
                url: 'http://www.example.com/',
-               isbn: [ // Test example of Array
+               isbn: [
+                       '978-3-16-148410-0',
+                       'this text should not appear anywhere'
+               ],
+               author: [
+                       [ 'First', 'Last' ],
+                       [ 'First2', 'Last2' ]
+               ]
+       },
+       maps = {
+               citoid: {
+                       title: 'title',
+                       url: 'url',
+                       publicationTitle: 'website',
+                       publisher: 'publisher',
+                       date: 'date',
+                       PMCID: 'pmc',
+                       PMID: 'pmid',
+                       pages: 'pages',
+                       series: 'series',
+                       accessDate: 'accessdate',
+                       DOI: 'doi',
+                       language: 'language',
+                       isbn: [ [ 'isbn' ] ], // Bad line of template data - 
should be 1D array
+                       author: [
+                               [ 'first', 'last' ],
+                               [ 'first2', 'last2' ],
+                               [ 'first3', 'last3' ],
+                               [ 'first4', 'last4' ],
+                               [ 'first5', 'last5' ],
+                               [ 'first6', 'last6' ],
+                               [ 'first7', 'last7' ],
+                               [ 'first8', 'last8' ],
+                               [ 'first9', 'last9' ]
+                       ],
+                       editor: [
+                               [ 'editor-first', 'editor-last' ]
+                       ]
+               }
+       };
+
+       return testMaps( maps, citation, expected, assert );
+
+} );
+
+QUnit.test( 'Mismatched templateData; 2D Array (cit) / Array (td) mismatch', 
2, function ( assert ) {
+       // This test mismatches a 2D Array in the citation data (author) with a 
1D array in the
+       // TemplateData. Expected result is for the inner fields to be 
concatenated with a space divider,
+       // and for no VE errors to be thrown.
+       var expected = {
+               target: {
+                       wt: 'Cite web',
+                       href: './Template:Cite_web'
+               },
+               params: {
+                       title: {
+                               wt: 'Example Domain'
+                       },
+                       url: {
+                               wt: 'http://www.example.com/'
+                       },
+                       isbn: {
+                               wt: '978-3-16-148410-0'
+                       },
+                       last: {
+                               wt: 'First Last'
+                       },
+                       last2: {
+                               wt: 'First2 Last2'
+                       }
+               },
+               i: 0
+       },
+       citation =
+       {
+               title: 'Example Domain',
+               itemType: 'webpage',
+               url: 'http://www.example.com/',
+               isbn: [
                        '978-3-16-148410-0',
                        'this text should not appear anywhere'
                ],
@@ -1808,7 +1899,7 @@
                        DOI: 'doi',
                        language: 'language',
                        isbn: [ 'isbn' ],
-                       author: [ // Bad template data - should be 2D Array
+                       author: [ // Mismatched template data - should be 2D 
Array
                                'last',
                                'last2',
                                'last3'
@@ -1821,12 +1912,14 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
 
-QUnit.test( 'Invalid templateData; 2D Array (cit) / String (td) mismatch', 2, 
function ( assert ) {
-       // This test mismatches a 2D Array in the citation data with a flat 
field in the TemplateData
-       // Expected result is for the field to be skipped in the resulting 
template, and for no VE
-       // errors to be thrown.
+QUnit.test( 'Mismatched templateData; 2D Array (cit) / String (td) mismatch', 
2, function ( assert ) {
+       // This test mismatches a 2D Array in the citation data (author) with a 
flat field in the TemplateData
+       // Expected result is for the fields to be concatenated, with the inner 
fields separated with a space,
+       // and the outer fields to be separated by a comma.
+
+       // No VE errors should be thrown.
        var expected = {
                target: {
                        wt: 'Cite web',
@@ -1841,6 +1934,9 @@
                        },
                        isbn: {
                                wt: '978-3-16-148410-0'
+                       },
+                       last: {
+                               wt: 'First Last, First2 Last2'
                        }
                },
                i: 0
@@ -1883,12 +1979,9 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
 
-QUnit.test( 'Invalid templateData; 2D Array (cit) / Array (td) mismatch', 2, 
function ( assert ) {
-       // This test mismatches a 2D Array in the citation data with a flat 
field in the TemplateData
-       // Expected result is for the field to be skipped in the resulting 
template, and for no VE
-       // errors to be thrown.
+QUnit.test( 'Unbalanced templateData', 2, function ( assert ) {
        var expected = {
                target: {
                        wt: 'Cite web',
@@ -1903,6 +1996,15 @@
                        },
                        isbn: {
                                wt: '978-3-16-148410-0'
+                       },
+                       first: {
+                               wt: 'First'
+                       },
+                       last: {
+                               wt: 'Last'
+                       },
+                       last2: {
+                               wt: 'First2 Last2'
                        }
                },
                i: 0
@@ -1936,7 +2038,11 @@
                        DOI: 'doi',
                        language: 'language',
                        isbn: [ 'isbn' ],
-                       author: [ 'first', 'last' ], // Bad line of template 
data - should be 2D array
+                       author: [ // Jagged array
+                               [ 'first', 'last' ],
+                               'last2',
+                               [ 'first3', 'last3' ]
+                       ],
                        editor: [
                                [ 'editor-first', 'editor-last' ]
                        ]
@@ -1945,15 +2051,85 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
+
+QUnit.test( 'Unbalanced citation', 2, function ( assert ) {
+       var expected = {
+               target: {
+                       wt: 'Cite web',
+                       href: './Template:Cite_web'
+               },
+               params: {
+                       title: {
+                               wt: 'Example Domain'
+                       },
+                       url: {
+                               wt: 'http://www.example.com/'
+                       },
+                       isbn: {
+                               wt: '978-3-16-148410-0'
+                       },
+                       first: {
+                               wt: 'First'
+                       },
+                       last: {
+                               wt: 'Last'
+                       },
+               },
+               i: 0
+       },
+       citation =
+       {
+               title: 'Example Domain',
+               itemType: 'webpage',
+               url: 'http://www.example.com/',
+               isbn: [
+                       '978-3-16-148410-0',
+                       'this text should not appear anywhere'
+               ],
+               author: [ // Jagged array
+                       [ 'First', 'Last' ],
+                       'First2'
+               ]
+       },
+       maps = {
+               citoid: {
+                       title: 'title',
+                       url: 'url',
+                       publicationTitle: 'website',
+                       publisher: 'publisher',
+                       date: 'date',
+                       PMCID: 'pmc',
+                       PMID: 'pmid',
+                       pages: 'pages',
+                       series: 'series',
+                       accessDate: 'accessdate',
+                       DOI: 'doi',
+                       language: 'language',
+                       isbn: [ 'isbn' ],
+                       author: [
+                               [ 'first', 'last' ],
+                               [ 'first2', 'last2' ]
+                       ],
+                       editor: [
+                               [ 'editor-first', 'editor-last' ]
+                       ]
+               }
+       };
+
+       return testMaps( maps, citation, expected, assert );
+
+} );
 
 QUnit.test( 'Invalid templateData; Object in citation and templateData', 2, 
function ( assert ) {
-       // This test mismatches a flat field in the citation data with an 
Object in the TemplateData.
-       // It also has an object in the citation. Neither of this situations 
should occur in the wild,
-       // as citoid should not return Objects as values, and the templateData 
extension should prevent
-       // any Objects as values from being saved.
+       // This test mismatches a flat field in the citation data with an 
Object in the TemplateData
+       // (title).
+
+       // It also has an object in the citation (author). Neither of these 
situations should occur in
+       // the wild, as citoid should not return Objects as values, and the 
templateData extension should
+       // prevent any Objects as values from being saved.
        //
-       // Expected result is for the field to be skipped in the resulting 
template, and for no VE
+       // Expected result is for the fields to be skipped in the resulting 
template, and for no VE
        // errors to be thrown.
        var expected = {
                target: {
@@ -1986,9 +2162,7 @@
        },
        maps = {
                citoid: {
-                       // Bad line of template data- this is actually 
disallowed by the templateData extension,
-                       // however.
-                       title: { title: 'title' },
+                       title: { title: 'title' }, // Bad line of template 
data- this is actually disallowed by the templateData extension
                        url: 'url',
                        publicationTitle: 'website',
                        publisher: 'publisher',
@@ -2020,4 +2194,4 @@
 
        return testMaps( maps, citation, expected, assert );
 
-});
+} );
diff --git a/modules/ve.ui.CiteFromIdInspector.js 
b/modules/ve.ui.CiteFromIdInspector.js
index cfb7c65..e4006ab 100644
--- a/modules/ve.ui.CiteFromIdInspector.js
+++ b/modules/ve.ui.CiteFromIdInspector.js
@@ -619,47 +619,101 @@
  */
 ve.ui.CiteFromIdInspector.static.populateTemplate = function ( template, 
citation ) {
        var citoidField, templateField, i, j,
+               concatCitoidField, // for storing a concatenated citoid value 
composed of array elements
+               concat2dField, // for storing elements of a 2d array converted 
to a 1d element
                spec = template.getSpec(),
                maps = spec.getMaps(),
                map = maps[ ve.ui.CiteFromIdInspector.static.templateDataName ];
 
        for ( citoidField in map ) {
                templateField = map[ citoidField ];
+               concatCitoidField = null; // Wipe field from previous iteration
+
                // Construct parameters
-               if ( typeof templateField === 'string' &&
-                       citation[ citoidField ] && typeof citation[ citoidField 
] === 'string' ) {
-                       // Case: Citoid parameter directly equivalent to 
TemplateData parameter
-                       template.addParameter( new ve.dm.MWParameterModel(
-                               template, templateField, citation[ citoidField 
] )
+
+               // Case: Citoid parameter directly equivalent to TemplateData 
parameter
+               if ( typeof templateField === 'string' && typeof citation[ 
citoidField ] === 'string' ) {
+                       template.addParameter(
+                               new ve.dm.MWParameterModel(
+                                       template, templateField, 
citation[citoidField ]
+                               )
                        );
-               // Check that both typeof citoidField and templateField match
-               } else if ( Array.isArray( citation[ citoidField ] ) && 
Array.isArray( templateField ) ) {
-                       // Case: Citoid parameter equivalent to 1 or 2D Array 
of TD parameters
+               // Case: Citoid parameter contains a 1 or 2D Array
+               } else if ( Array.isArray( citation[ citoidField ] ) ) {
+                       // Iterate through first dimension of array
                        for ( i = 0; i < citation[ citoidField ].length; i++ ) {
-                               // Iterate through first dimension of array
-                               if ( typeof citation[ citoidField ][ i ] === 
'string' &&
-                                       typeof templateField[ i ] === 'string' 
) {
-                                       // Case: Citoid parameter equivalent to 
1D Array of TD parameters
-                                       template.addParameter(
-                                               new ve.dm.MWParameterModel(
-                                                       template, 
templateField[ i ], citation[ citoidField ][ i ]
-                                               )
-                                       );
-                               // Check that both typeof citoidField and 
templateField match
-                               } else if ( Array.isArray( citation[ 
citoidField ][ i ] ) &&
-                                       Array.isArray( templateField[ i ] ) ) {
-                                       // Case: Citoid parameter equivalent to 
2D Array of TD parameters
-                                       for ( j = 0; j < citation[ citoidField 
][ i ].length; j++ ) {
-                                               // Iterate through 2nd 
dimension of Array
-                                               if ( typeof citation[ 
citoidField ][ i ][ j ] === 'string' &&
-                                                       templateField[ i ] && 
templateField[ i ][ j ] ) {
-                                                       template.addParameter(
-                                                               new 
ve.dm.MWParameterModel(
-                                                                       
template, templateField[ i ][ j ], citation[ citoidField ][ i ][ j ]
-                                                               )
-                                                       );
+                               // Case: Citoid parameter equivalent to 1D 
Array of TD parameters
+                               if ( typeof citation[ citoidField ][ i ] === 
'string' ) {
+                                       // Case: Citoid parameter equivalent to 
TD parameter
+                                       if ( Array.isArray( templateField ) && 
templateField[ i ] &&
+                                               typeof templateField[ i ] === 
'string' ) {
+                                               template.addParameter( new 
ve.dm.MWParameterModel(
+                                                       template, 
templateField[ i ], citation[ citoidField ][ i ] )
+                                               );
+                                       // Case: No equivalent TD parameter, 
add value to flattened string instead.
+                                       } else if ( typeof templateField === 
'string' ) {
+                                               if ( !concatCitoidField ) {
+                                                       concatCitoidField = 
citation[ citoidField ][ i ];
+                                               } else {
+                                                       concatCitoidField += ', 
' + citation[ citoidField ][ i ] ;
                                                }
                                        }
+                               // Case: Citoid parameter equivalent to 2D 
Array of TD parameters
+                               } else if ( Array.isArray( citation[ 
citoidField ][ i ] ) ) {
+                                       concat2dField = null; // Wipe field 
from previous iteration
+
+                                       // Iterate through inner dimension of 
array
+                                       for ( j = 0; j < citation[ citoidField 
][ i ].length; j++ ) {
+                                               // Case: 2nd degree parameter 
exists
+                                               if ( typeof citation[ 
citoidField ][ i ][ j ] === 'string' ) {
+                                                       // Case: Citoid 
parameter equivalent to TD parameter
+                                                       if ( Array.isArray( 
templateField[ i ] ) &&
+                                                               templateField[ 
i ][ j ] && typeof templateField[ i ][ j ] === 'string' ) {
+                                                               
template.addParameter(
+                                                                       new 
ve.dm.MWParameterModel(
+                                                                               
template, templateField[ i ][ j ],
+                                                                               
citation[ citoidField ][ i ][ j ]
+                                                                       )
+                                                               );
+                                                       // Case: Citoid 
parameter deeper than TD parameter
+                                                       } else if ( 
templateField[ i ] && typeof templateField[ i ] === 'string' ) {
+                                                               if ( 
!concat2dField ) {
+                                                                       
concat2dField = citation[ citoidField][ i ][ j ];
+                                                               } else {
+                                                                       
concat2dField += ' ' + citation[ citoidField ][ i ][ j ];
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       // Done iterating; Deal with 
concatenated values
+                                       if ( concat2dField ) {
+                                               // Case: Concat 2d value is 
equivalent to a 1d template field value
+                                               if ( Array.isArray( 
templateField ) && typeof templateField[ i ] === 'string' ) {
+                                                       template.addParameter(
+                                                               new 
ve.dm.MWParameterModel(
+                                                                       
template, templateField[ i ], concat2dField
+                                                               )
+                                                       );
+                                               // Case: Concat value is likely 
equivalent to a flat template field value
+                                               } else {
+                                                       if ( !concatCitoidField 
) {
+                                                               
concatCitoidField = concat2dField;
+                                                       } else {
+                                                               
concatCitoidField += ', ' + concat2dField;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       // Done iterating; add final citoidConcatValue to TD
+                       if ( concatCitoidField ) {
+                               // Case: Concat value is equivalent to flat 
templateField value
+                               if ( templateField && typeof templateField === 
'string' ) {
+                                       template.addParameter(
+                                               new ve.dm.MWParameterModel(
+                                                       template, 
templateField, concatCitoidField
+                                               )
+                                       );
                                }
                        }
                }

-- 
To view, visit https://gerrit.wikimedia.org/r/218946
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I9746a36b951647bf40f66769290b064dd0b6d302
Gerrit-PatchSet: 10
Gerrit-Project: mediawiki/extensions/Citoid
Gerrit-Branch: master
Gerrit-Owner: Mvolz <[email protected]>
Gerrit-Reviewer: Alex Monk <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Mvolz <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to