text: 'use strict';
  /*jshint asi: true */
  
  var test            =  require('tap').test;
  var convert         =  require('convert-source-map');
  var commentRegex    =  require('convert-source-map').commentRegex;
  var combine         =  require('..');
  var mappingsFromMap =  require('../lib/mappings-from-map');
  
  function checkMappings(foo, sm, lineOffset) {
      function inspect(obj, depth) {
          return require('util').inspect(obj, false, depth || 5, true);
      }
  
      var fooMappings = mappingsFromMap(foo);
      var mappings = mappingsFromMap(sm);
  
      var genLinesOffset = true;
      var origLinesSame = true;
      for (var i = 0; i < mappings.length; i++) {
          var fooGen = fooMappings[i].generated;
          var fooOrig = fooMappings[i].original;
          var gen = mappings[i].generated
          var orig = mappings[i].original;
  
          if (gen.column !== fooGen.column || gen.line !== (fooGen.line + lineOffset)) {
            console.error(
              'generated mapping at %s not offset properly:\ninput:  [%s]\noutput:[%s]\n\n',
              i ,
              inspect(fooGen),
              inspect(gen)
            );
            genLinesOffset = false;
          }
  
          if (orig.column !== fooOrig.column || orig.line !== fooOrig.line) {
            console.error(
              'original mapping at %s is not the same as the genrated mapping:\ninput:  [%s]\noutput:[%s]\n\n',
              i ,
              inspect(fooOrig),
              inspect(orig)
            );
            origLinesSame = false;
          }
      }
      return { genLinesOffset: genLinesOffset, origLinesSame: origLinesSame };
  }
  
  var foo = {
    version        :  3,
    file           :  'foo.js',
    sourceRoot     :  '',
    sources        :  [ 'foo.coffee' ],
    names          :  [],
    mappings       :  ';AAAA;CAAA;CAAA,CAAA,CAAA,IAAO,GAAK;CAAZ',
    sourcesContent :  [ 'console.log(require \'./bar.js\')\n' ] };
  
  test('add one file with inlined source', function (t) {
  
    var mapComment = convert.fromObject(foo).toComment();
    var file = {
        id: 'xyz'
      , source: '(function() {\n\n  console.log(require(\'./bar.js\'));\n\n}).call(this);\n' + '\n' + mapComment
      , sourceFile: 'foo.js'
    };
  
    var lineOffset = 3
    var base64 = combine.create()
      .addFile(file, { line: lineOffset })
      .base64()
  
    var sm = convert.fromBase64(base64).toObject();
    var res = checkMappings(foo, sm, lineOffset);
  
    t.ok(res.genLinesOffset, 'all generated lines are offset properly and columns unchanged')
    t.ok(res.origLinesSame, 'all original lines and columns are unchanged')
    t.deepEqual(sm.sourcesContent, foo.sourcesContent, 'includes the original source')
    t.deepEqual(sm.sources, ['foo.coffee'], 'includes original filename')
    t.end()
  });
  
  
  test('add one file without inlined source', function (t) {
  
    var mapComment = convert
      .fromObject(foo)
      .setProperty('sourcesContent', [])
      .toComment();
  
    var file = {
        id: 'xyz'
      , source: '(function() {\n\n  console.log(require(\'./bar.js\'));\n\n}).call(this);\n' + '\n' + mapComment
      , sourceFile: 'foo.js'
    };
  
    var lineOffset = 3
    var base64 = combine.create()
      .addFile(file, { line: lineOffset })
      .base64()
  
    var sm = convert.fromBase64(base64).toObject();
    var mappings = mappingsFromMap(sm);
  
    t.deepEqual(sm.sourcesContent, [file.source], 'includes the generated source')
    t.deepEqual(sm.sources, ['foo.js'], 'includes generated filename')
  
    t.deepEqual(
        mappings
      , [ { generated: { line: 4, column: 0 },
          original: { line: 1, column: 0 },
          source: 'foo.js', name: null },
        { generated: { line: 5, column: 0 },
          original: { line: 2, column: 0 },
          source: 'foo.js', name: null },
        { generated: { line: 6, column: 0 },
          original: { line: 3, column: 0 },
          source: 'foo.js', name: null },
        { generated: { line: 7, column: 0 },
          original: { line: 4, column: 0 },
          source: 'foo.js', name: null },
        { generated: { line: 8, column: 0 },
          original: { line: 5, column: 0 },
          source: 'foo.js', name: null },
        { generated: { line: 9, column: 0 },
          original: { line: 6, column: 0 },
          source: 'foo.js', name: null },
        { generated: { line: 10, column: 0 },
          original: { line: 7, column: 0 },
          source: 'foo.js', name: null } ]
      , 'generates mappings offset by the given line'
    )
    t.end()
  })
  
  test('add one file with inlined sources from multiple files', function(t) {
    var gen1Map = {
      version: 3,
      sources: [ 'one.js', 'two.js' ],
      names: [],
      mappings: 'AAAA;ACAA',
      sourcesContent: [ 'console.log(1);', 'console.log(2);' ]
    };
  
    var gen2Map = {
      version: 3,
      sources: [ 'three.js', 'four.js' ],
      names: [],
      mappings: 'AAAA;ACAA',
      sourcesContent: [ 'console.log(3);', 'console.log(4);' ]
    };
  
    var base64 = combine.create()
      .addFile({
        source: 'console.log(1);\nconsole.log(2);\n' + convert.fromObject(gen1Map).toComment(),
        sourceFile: 'gen1.js'
      })
      .addFile({
        source: 'console.log(3);\nconsole.log(4);\n' + convert.fromObject(gen2Map).toComment(),
        sourceFile: 'gen2.js'
      }, {line: 2})
      .base64()
  
    var sm = convert.fromBase64(base64).toObject();
  
  
    t.deepEqual(sm.sources, ['one.js', 'two.js', 'three.js', 'four.js'], 'include the correct source');
  
    t.deepEqual(sm.sourcesContent, [
      'console.log(1);',
      'console.log(2);',
      'console.log(3);',
      'console.log(4);'
    ], 'include the correct source file content');
  
    t.deepEqual(
        mappingsFromMap(sm)
      , [ { original: { column: 0, line: 1 },
          generated: { column: 0, line: 1 },
          source: 'one.js',
          name: null },
        { original: { column: 0, line: 1 },
          generated: { column: 0, line: 2 },
          source: 'two.js',
          name: null },
        { original: { column: 0, line: 1 },
          generated: { column: 0, line: 3 },
          source: 'three.js',
          name: null },
        { original: { column: 0, line: 1 },
          generated: { column: 0, line: 4 },
          source: 'four.js',
          name: null } ], 'should properly map multiple files');
    t.end()
  });
  
  test('relative path from multiple files', function(t) {
    // Folder structure as follows:
    //
    //  project
    //   +- src
    //    +- package1
    //     +- sub
    //      -- one.js
    //      -- two.js
    //    +- package2
    //     +- sub
    //      -- three.js
    //      -- four.js
    //   +- gen
    //    +- gen1.js
    //    +- gen2.js
    //   -- combined.js
    //
    // Where 'one.js', 'two.js' were combined to 'gen1.js'
    // and 'three.js', 'four.js' were combined to 'gen2.js'.
    // Now 'gen1.js' and 'gen2.js' are being combined from
    // the project root folder.
    var gen1Map = {
      version: 3,
      sources: [ 'sub/one.js', 'sub/two.js' ],
      names: [],
      mappings: 'AAAA;ACAA',
      sourcesContent: [ 'console.log(1);', 'console.log(2);' ],
      sourceRoot: '../src/package1'
    };
  
    var gen2Map = {
      version: 3,
      sources: [ 'sub/three.js', 'sub/four.js' ],
      names: [],
      mappings: 'AAAA;ACAA',
      sourcesContent: [ 'console.log(3);', 'console.log(4);' ],
      sourceRoot: '../src/package2'
    };
  
    var base64 = combine.create()
      .addFile({
        source: 'console.log(1);\nconsole.log(2);\n' + convert.fromObject(gen1Map).toComment(),
        sourceFile: 'gen/gen1.js'
      })
      .addFile({
        source: 'console.log(3);\nconsole.log(4);\n' + convert.fromObject(gen2Map).toComment(),
        sourceFile: 'gen/gen2.js'
      }, {line: 2})
      .base64()
  
    var sm = convert.fromBase64(base64).toObject();
  
    t.deepEqual(sm.sources, ['src/package1/sub/one.js', 'src/package1/sub/two.js', 
      'src/package2/sub/three.js', 'src/package2/sub/four.js'], 
      'include the correct source');
  
    t.deepEqual(sm.sourcesContent, [
      'console.log(1);',
      'console.log(2);',
      'console.log(3);',
      'console.log(4);'
    ], 'include the correct source file content');
  
    t.deepEqual(
        mappingsFromMap(sm)
      , [ { original: { column: 0, line: 1 },
          generated: { column: 0, line: 1 },
          source: 'src/package1/sub/one.js',
          name: null },
        { original: { column: 0, line: 1 },
          generated: { column: 0, line: 2 },
          source: 'src/package1/sub/two.js',
          name: null },
        { original: { column: 0, line: 1 },
          generated: { column: 0, line: 3 },
          source: 'src/package2/sub/three.js',
          name: null },
        { original: { column: 0, line: 1 },
          generated: { column: 0, line: 4 },
          source: 'src/package2/sub/four.js',
          name: null } ], 'should properly map multiple files');
    t.end()
  });
  
  test('relative path when source and file name are the same', function(t) {
    var gen1Map = {
      version: 3,
      sources: [ 'a/b/one.js' ],
      names: [],
      mappings: 'AAAA',
      file: 'a/b/one.js',
      sourcesContent: [ 'console.log(1);\n' ]
    };
  
    var gen2Map = {
      version: 3,
      sources: [ 'a/b/two.js' ],
      names: [],
      mappings: 'AAAA',
      file: 'a/b/two.js',
      sourcesContent: [ 'console.log(2);\n' ]
    };
  
    var base64 = combine.create()
      .addFile({
        source: 'console.log(1);\n' + convert.fromObject(gen1Map).toComment(),
        sourceFile: 'a/b/one.js'
      })
      .addFile({
        source: 'console.log(2);\n' + convert.fromObject(gen2Map).toComment(),
        sourceFile: 'a/b/two.js'
      }, {line: 1})
      .base64()
  
    var sm = convert.fromBase64(base64).toObject();
  
    t.deepEqual(sm.sources, ['a/b/one.js', 'a/b/two.js'],
      'include the correct source');
  
    t.deepEqual(
        mappingsFromMap(sm)
      , [ { original: { column: 0, line: 1 },
          generated: { column: 0, line: 1 },
          source: 'a/b/one.js',
          name: null },
        { original: { column: 0, line: 1 },
          generated: { column: 0, line: 2 },
          source: 'a/b/two.js',
          name: null } ], 'should properly map multiple files');
    t.end()
  });
  
  test('remove comments', function (t) {
    var mapComment = convert.fromObject(foo).toComment();
  
    function sourcemapComments(src) {
      var matches = src.match(commentRegex);
      return matches ? matches.length : 0;
    }
  
    t.equal(sourcemapComments('var a = 1;\n' + mapComment), 1);
  
    [ ''
    , 'var a = 1;\n' + mapComment
    , 'var a = 1;\n' + mapComment + '\nvar b = 5;\n' + mapComment
    ] .forEach(function (x) {
      var removed = combine.removeComments(x)
      t.equal(sourcemapComments(removed), 0)
    })
    t.end()
  })
  