<NME> GBrowseParser.spec.js
<BEF> require(['JBrowse/ConfigAdaptor/conf'], function ( gbrowseConfigAdaptor ) {
    describe( 'GBrowse-like config file parser', function() {
        var gbrowse = new gbrowseConfigAdaptor();
        var gbConfig;

        // run the script with GBrowseParseTestBasic.conf as input
        // to test different kinds of input
        // config file => ./spec/GBrowseParseTestBasic.conf

        it('should parse', function() {
            gbrowse.load({
                             config: { url: 'spec/GBrowseParseTestBasic.conf' }
                         })
                   .then(function( c ) {
                             gbConfig = c;
                         },
                         function( error ) {
                             console.error( error.stack || ''+error );
                         });

            waitsFor( function() { return gbConfig; } );
            runs(function() {
                expect( typeof gbConfig).toEqual('object');
                expect(gbConfig['TRACK DEFAULTS']).toBeTruthy();
                expect(gbConfig['TRACK DEFAULTS']['glyph'           ]).toBe('generic');
                expect(gbConfig['TRACK DEFAULTS']['height'          ]).toBe(8);
                expect(gbConfig['TRACK DEFAULTS']['bgcolor'         ]).toBe('#fefefe');
                expect(gbConfig['TRACK DEFAULTS']['fgcolor'         ]).toBe('black');
                expect(gbConfig['TRACK DEFAULTS']['label density'   ]).toBe(25);
                expect(gbConfig['TRACK DEFAULTS']['bump density'    ]).toBe(25);
                expect(gbConfig['TRACK DEFAULTS']['fogbat'    ]).toBe('');

                expect(gbConfig['Markers:region']).toBeTruthy();
                expect(gbConfig['Markers:region']['feature'         ]).toBe('match:ITAG_sgn_markers');
                expect(gbConfig['Markers:region']['ignore_sub_part' ]).toBe('match_part');
                expect(gbConfig['Markers:region']['key'             ]).toBe('Markers');
                expect(gbConfig['Markers:region']['fgcolor'         ]).toBe('black');
                expect(gbConfig['Markers:region']['bgcolor'         ]).toBe('yellow');
                expect(gbConfig['Markers:region']['glyph'           ]).toBe('generic');
                expect(gbConfig['Markers:region']['label density'   ]).toBe(100);
                expect(gbConfig['Markers:region']['bump density'    ]).toBe(100);
                expect(gbConfig['Markers:region']['link'            ]).toBe('/search/quick?term=$name');
                expect(gbConfig['Markers:region']['citation'        ]).toBe('GenomeThreader alignments of SGN marker sequences.');

                expect(gbConfig['DM_BAC']).toBeTruthy();
                expect(gbConfig['DM_BAC']['feature'  ]).toBe('\"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_sg\" \"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_sb\" \"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_lg\" \"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_lb\" \"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_hg\" \"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_hb\"');
                expect(gbConfig['DM_BAC']['citation' ]).toBe('BAC ends from the \'POTATO-B-01-100-110KB\' library aligned using SSAHA2. The clone ends pair correctly (solid connector) or not (dashed connector), and are color coded by insert-size.  Provided by Dan Bolser, <a href="http://www.compbio.dundee.ac.uk/">University of Dundee</a>.');

                expect(gbConfig['sub']['section']['giant word']).toBe('Antidisestablishmentarianism');
                expect(gbConfig['sub']['section']['multiline']).toBe('herp derp');
                expect(gbConfig['sub']['section']['fancyMultiline']).toBe('Le herp derp');
                expect(gbConfig.sub.section.array.length).toBe(3);

            expect(gbConfig['sub']['section']['giant word']).toBe('Antidisestablishmentarianism');
            expect(gbConfig['sub']['section']['multiline']).toBe('herp derp');
            
            var x = gbConfig.function_testing.meaningOfLife();
            expect(x).toBe(42);

                expect( gbConfig.em.bedded.json.myjson.length ).toBe(2);
                expect( gbConfig.em.bedded.json.myjson[0].zee ).toBe('hallo');
                expect( gbConfig.em.bedded.json.myjson[1] ).toBe(53);


                expect( gbConfig.function_testing.randomNumberTitle.charAt( gbConfig.function_testing.randomNumberTitle.length-1 ) )
                     .toBe('}');

                expect( gbConfig.function_testing.alertTest.charAt( gbConfig.function_testing.alertTest.length-1 ) )
                         .toBe('}');

                expect( gbConfig.array_of_objects.foo[0].nog ).toBe( 1 );
                expect( gbConfig.array_of_objects.foo[1].egg ).toBe( 2 );

                expect( gbConfig.array_of_objects.bar[0] ).toBe( 'one' );
                expect( gbConfig.array_of_objects.bar[1] ).toBe( 'two' );
                expect( gbConfig.array_of_objects.bar[2] ).toBe( 'three and a half' );
                expect( gbConfig.array_of_objects.bar[3] ).toBe( 'four' );

        });
    });
});
});

<MSG> Merge branch 'movearound140' of github.com:GMOD/jbrowse into movearound140

Conflicts:
	src/JBrowse/ConfigAdaptor/gbrowse.js

<DFF> @@ -53,6 +53,7 @@ require(['JBrowse/ConfigAdaptor/gbrowse'], function ( gbrowseConfigAdaptor ) {
 
             expect(gbConfig['sub']['section']['giant word']).toBe('Antidisestablishmentarianism');
             expect(gbConfig['sub']['section']['multiline']).toBe('herp derp');
+            expect(gbConfig['sub']['section']['fancyMultiline']).toBe('Le herp derp');
             
             var x = gbConfig.function_testing.meaningOfLife();
             expect(x).toBe(42);

{'commit': 'diff --git a/src/JBrowse/ConfigAdaptor/gbrowse.js b/src/JBrowse/ConfigAdaptor/gbrowse.js\nindex 27059e164..3b6f206a9 100644\n--- a/src/JBrowse/ConfigAdaptor/gbrowse.js\n+++ b/src/JBrowse/ConfigAdaptor/gbrowse.js\n@@ -34,7 +34,6 @@ return declare(\'JBrowse.ConfigAdaptor.gbrowse\',null,\n                 section:    /^\\s*\\[\\s*([^\\]\\/]*)\\s*\\]\\s*$/,\n                 subsection: /^\\s*\\[\\s*([^\\]]*)\\/([^\\]]*)\\s*\\]\\s*$/,\n                 param:      /^(\\w[\\w\\.\\-\\_\\:\\s]+)=\\s*(.*?)\\s*$/,\n-                halfParam:  /^(\\w[\\w\\.\\-\\_\\:\\s]+)=\\s*$/,\n                 comment:    /^\\s*(#|\\/\\/).*$/,\n                 emptyLine:  /^\\s*$/,\n                 newLine:    /\\r\\n|\\r|\\n/,\n@@ -51,10 +50,8 @@ return declare(\'JBrowse.ConfigAdaptor.gbrowse\',null,\n             for (var i = 0; i < n; i++) {\n                 if (this.regex.comment.test(this.lines[i])) {                      //      #this is a comment\n                     // do nothing, since it\'s a comment.                           //      // this is also a comment\n-                } else if (this.regex.halfParam.test(this.lines[i])) {             //      halfParam = \n-                    i = this.multiLine(i); // skips lines, so get \'i\': where to continue\n-                } else if (this.regex.param.test(this.lines[i])) {                 //      param = value\n-                    this.param(i);\n+                } else if (this.regex.param.test(this.lines[i])) {                 //      param = *\n+                    i = this.param(i);\n                 } else if (this.regex.subsection.test(this.lines[i])) {            //      [section_name]\n                     this.subSection(i);\n                 } else if (this.regex.section.test(this.lines[i])){                //      [section/subsection]\n@@ -65,12 +62,20 @@ return declare(\'JBrowse.ConfigAdaptor.gbrowse\',null,\n             return AdaptorUtil.evalHooks(this.value); //Returns the JS object\n         },\n \n-        //called for:  something =\n-        multiLine: function(i){\n+        //called for:  something = *\n+        param: function(i){\n             var line = this.lines; var rx = this.regex;\n             var lineNum = i+1;\n-            var tmpStrVal = \'\';\n+\n+            var match = this.lines[i].match(this.regex.param);  // Check for a value\n+            match[2].trim();                                    // on the first\n+            if (!isNaN(match[2].trim())) {                      // line, then check\n+                match[2] = parseFloat(match[2]);                // the rest of the\n+            }                                                   // block\n+\n+            var tmpStrVal = match[2] ? match[2] : \'\';\n             var divider = this.regex.code.test(line[lineNum]) ? "\\n" : \' \';\n+\n             // while (line is defined, and not a parameter, section, or subsection)\n             while (typeof line[lineNum] !== \'undefined\' && (! ( rx.param.test(line[lineNum]) ||\n                     rx.section.test(line[lineNum]) || rx.subsection.test(line[lineNum])))){\n@@ -95,22 +100,6 @@ return declare(\'JBrowse.ConfigAdaptor.gbrowse\',null,\n             return lineNum - 1; //The line it should continue at.\n         },\n \n-        //called for:  something = value\n-        param: function(i) {\n-            var match = this.lines[i].match(this.regex.param);\n-            match[2].trim();\n-            if (!isNaN(match[2].trim())) {\n-                match[2] = parseFloat(match[2]);\n-            }\n-            if (this.subsection && this.section) {\n-                this.value[this.section][this.subsection][match[1].trim()] = match[2];\n-            } else if (this.section) {\n-                this.value[this.section][match[1].trim()] = match[2];\n-            } else{\n-                this.value[match[1].trim()] = match[2];\n-            }\n-        },\n-\n         //called for:  [foobar]\n         mainSection: function(i) {\n             var match = this.lines[i].match(this.regex.section);\ndiff --git a/tests/js_tests/spec/GBrowseParseTestBasic.conf b/tests/js_tests/spec/GBrowseParseTestBasic.conf\nindex e11d4d2da..94e47649a 100644\n--- a/tests/js_tests/spec/GBrowseParseTestBasic.conf\n+++ b/tests/js_tests/spec/GBrowseParseTestBasic.conf\n@@ -42,6 +42,9 @@ giant word = Antidisestablishmentarianism\n multiline =\n   herp\n   derp\n+fancyMultiline = Le\n+                 herp\n+                 derp\n \n [function_testing]\n meaningOfLife = \ndiff --git a/tests/js_tests/spec/GBrowseParser.spec.js b/tests/js_tests/spec/GBrowseParser.spec.js\nindex 3d45772f1..191cbaae3 100644\n--- a/tests/js_tests/spec/GBrowseParser.spec.js\n+++ b/tests/js_tests/spec/GBrowseParser.spec.js\n@@ -53,6 +53,7 @@ require([\'JBrowse/ConfigAdaptor/gbrowse\'], function ( gbrowseConfigAdaptor ) {\n \n             expect(gbConfig[\'sub\'][\'section\'][\'giant word\']).toBe(\'Antidisestablishmentarianism\');\n             expect(gbConfig[\'sub\'][\'section\'][\'multiline\']).toBe(\'herp derp\');\n+            expect(gbConfig[\'sub\'][\'section\'][\'fancyMultiline\']).toBe(\'Le herp derp\');\n             \n             var x = gbConfig.function_testing.meaningOfLife();\n             expect(x).toBe(42);\n', 'commit_subject': "Merge branch 'movearound140' of github.com:GMOD/jbrowse into movearound140", 'repo_name': 'GMOD/jbrowse', 'committer': {'name': 'Robert Buels', 'email': '08f6e0b425f11eb922c9a362cbdf67a59bd5bd95@gmail.com', 'time_sec': '1358798008', 'tz_offset': '-300', 'date': {'seconds': '1358798008'}}, 'commit_tree': '48133c53c83008302f636cc93186ab74ad396fc1', 'commit_message': "Merge branch 'movearound140' of github.com:GMOD/jbrowse into movearound140\n\nConflicts:\n\tsrc/JBrowse/ConfigAdaptor/gbrowse.js\n", 'language_name': 'HTML', 'license': 'lgpl-2.1', 'hunks': "@@ -53,6 +53,7 @@ require(['JBrowse/ConfigAdaptor/gbrowse'], function ( gbrowseConfigAdaptor ) {\n \n             expect(gbConfig['sub']['section']['giant word']).toBe('Antidisestablishmentarianism');\n             expect(gbConfig['sub']['section']['multiline']).toBe('herp derp');\n+            expect(gbConfig['sub']['section']['fancyMultiline']).toBe('Le herp derp');\n             \n             var x = gbConfig.function_testing.meaningOfLife();\n             expect(x).toBe(42);\n", 'addition_count': 1, 'deletion_count': 0, 'src_file': 'a/tests/js_tests/spec/GBrowseParser.spec.js', 'tgt_file': 'b/tests/js_tests/spec/GBrowseParser.spec.js', 'file_extension': '.js', 'before_file': 'require([\'JBrowse/ConfigAdaptor/conf\'], function ( gbrowseConfigAdaptor ) {\n    describe( \'GBrowse-like config file parser\', function() {\n        var gbrowse = new gbrowseConfigAdaptor();\n        var gbConfig;\n\n        // run the script with GBrowseParseTestBasic.conf as input\n        // to test different kinds of input\n        // config file => ./spec/GBrowseParseTestBasic.conf\n\n        it(\'should parse\', function() {\n            gbrowse.load({\n                             config: { url: \'spec/GBrowseParseTestBasic.conf\' }\n                         })\n                   .then(function( c ) {\n                             gbConfig = c;\n                         },\n                         function( error ) {\n                             console.error( error.stack || \'\'+error );\n                         });\n\n            waitsFor( function() { return gbConfig; } );\n            runs(function() {\n                expect( typeof gbConfig).toEqual(\'object\');\n                expect(gbConfig[\'TRACK DEFAULTS\']).toBeTruthy();\n                expect(gbConfig[\'TRACK DEFAULTS\'][\'glyph\'           ]).toBe(\'generic\');\n                expect(gbConfig[\'TRACK DEFAULTS\'][\'height\'          ]).toBe(8);\n                expect(gbConfig[\'TRACK DEFAULTS\'][\'bgcolor\'         ]).toBe(\'#fefefe\');\n                expect(gbConfig[\'TRACK DEFAULTS\'][\'fgcolor\'         ]).toBe(\'black\');\n                expect(gbConfig[\'TRACK DEFAULTS\'][\'label density\'   ]).toBe(25);\n                expect(gbConfig[\'TRACK DEFAULTS\'][\'bump density\'    ]).toBe(25);\n                expect(gbConfig[\'TRACK DEFAULTS\'][\'fogbat\'    ]).toBe(\'\');\n\n                expect(gbConfig[\'Markers:region\']).toBeTruthy();\n                expect(gbConfig[\'Markers:region\'][\'feature\'         ]).toBe(\'match:ITAG_sgn_markers\');\n                expect(gbConfig[\'Markers:region\'][\'ignore_sub_part\' ]).toBe(\'match_part\');\n                expect(gbConfig[\'Markers:region\'][\'key\'             ]).toBe(\'Markers\');\n                expect(gbConfig[\'Markers:region\'][\'fgcolor\'         ]).toBe(\'black\');\n                expect(gbConfig[\'Markers:region\'][\'bgcolor\'         ]).toBe(\'yellow\');\n                expect(gbConfig[\'Markers:region\'][\'glyph\'           ]).toBe(\'generic\');\n                expect(gbConfig[\'Markers:region\'][\'label density\'   ]).toBe(100);\n                expect(gbConfig[\'Markers:region\'][\'bump density\'    ]).toBe(100);\n                expect(gbConfig[\'Markers:region\'][\'link\'            ]).toBe(\'/search/quick?term=$name\');\n                expect(gbConfig[\'Markers:region\'][\'citation\'        ]).toBe(\'GenomeThreader alignments of SGN marker sequences.\');\n\n                expect(gbConfig[\'DM_BAC\']).toBeTruthy();\n                expect(gbConfig[\'DM_BAC\'][\'feature\'  ]).toBe(\'\\"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_sg\\" \\"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_sb\\" \\"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_lg\\" \\"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_lb\\" \\"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_hg\\" \\"BAC_clone:DBolser_Dundee_BES_SSAHA_dm_bes_hb\\"\');\n                expect(gbConfig[\'DM_BAC\'][\'citation\' ]).toBe(\'BAC ends from the \\\'POTATO-B-01-100-110KB\\\' library aligned using SSAHA2. The clone ends pair correctly (solid connector) or not (dashed connector), and are color coded by insert-size.  Provided by Dan Bolser, <a href="http://www.compbio.dundee.ac.uk/">University of Dundee</a>.\');\n\n                expect(gbConfig[\'sub\'][\'section\'][\'giant word\']).toBe(\'Antidisestablishmentarianism\');\n                expect(gbConfig[\'sub\'][\'section\'][\'multiline\']).toBe(\'herp derp\');\n                expect(gbConfig[\'sub\'][\'section\'][\'fancyMultiline\']).toBe(\'Le herp derp\');\n                expect(gbConfig.sub.section.array.length).toBe(3);\n\n            expect(gbConfig[\'sub\'][\'section\'][\'giant word\']).toBe(\'Antidisestablishmentarianism\');\n            expect(gbConfig[\'sub\'][\'section\'][\'multiline\']).toBe(\'herp derp\');\n            \n            var x = gbConfig.function_testing.meaningOfLife();\n            expect(x).toBe(42);\n\n                expect( gbConfig.em.bedded.json.myjson.length ).toBe(2);\n                expect( gbConfig.em.bedded.json.myjson[0].zee ).toBe(\'hallo\');\n                expect( gbConfig.em.bedded.json.myjson[1] ).toBe(53);\n\n\n                expect( gbConfig.function_testing.randomNumberTitle.charAt( gbConfig.function_testing.randomNumberTitle.length-1 ) )\n                     .toBe(\'}\');\n\n                expect( gbConfig.function_testing.alertTest.charAt( gbConfig.function_testing.alertTest.length-1 ) )\n                         .toBe(\'}\');\n\n                expect( gbConfig.array_of_objects.foo[0].nog ).toBe( 1 );\n                expect( gbConfig.array_of_objects.foo[1].egg ).toBe( 2 );\n\n                expect( gbConfig.array_of_objects.bar[0] ).toBe( \'one\' );\n                expect( gbConfig.array_of_objects.bar[1] ).toBe( \'two\' );\n                expect( gbConfig.array_of_objects.bar[2] ).toBe( \'three and a half\' );\n                expect( gbConfig.array_of_objects.bar[3] ).toBe( \'four\' );\n\n        });\n    });\n});\n});\n', 'message': "Merge branch 'movearound140' of github.com:GMOD/jbrowse into movearound140\n\nConflicts:\n\tsrc/JBrowse/ConfigAdaptor/gbrowse.js\n", 'author_name': 'Robert Buels', 'lang': 'spec'}