403 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			403 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// Copyright 2014 Simon Lydell
 | 
						|
// X11 (“MIT”) Licensed. (See LICENSE.)
 | 
						|
 | 
						|
var expect = require("expect.js")
 | 
						|
 | 
						|
var sourceMappingURL = require("../")
 | 
						|
 | 
						|
var comments = {
 | 
						|
 | 
						|
  universal: [
 | 
						|
    "/*# sourceMappingURL=foo.js.map */"
 | 
						|
  ],
 | 
						|
 | 
						|
  js: [
 | 
						|
    "//# sourceMappingURL=foo.js.map"
 | 
						|
  ],
 | 
						|
 | 
						|
  block: [
 | 
						|
    "/*",
 | 
						|
    "# sourceMappingURL=foo.js.map",
 | 
						|
    "*/"
 | 
						|
  ],
 | 
						|
 | 
						|
  mix: [
 | 
						|
    "/*",
 | 
						|
    "//# sourceMappingURL=foo.js.map",
 | 
						|
    "*/"
 | 
						|
  ]
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
var nonTrailingComments = {
 | 
						|
 | 
						|
  jsLeading: {
 | 
						|
    contents: [
 | 
						|
      "//# sourceMappingURL=foo.js.map",
 | 
						|
      "(function(){})"
 | 
						|
    ],
 | 
						|
    solution: [
 | 
						|
      "(function(){})"
 | 
						|
    ]
 | 
						|
  },
 | 
						|
 | 
						|
  mixEmbedded: {
 | 
						|
    contents: [
 | 
						|
      "/*! Library Name v1.0.0",
 | 
						|
      "//# sourceMappingURL=foo.js.map",
 | 
						|
      "*/",
 | 
						|
      "(function(){})"
 | 
						|
    ],
 | 
						|
    solution: [
 | 
						|
      "/*! Library Name v1.0.0",
 | 
						|
      "*/",
 | 
						|
      "(function(){})"
 | 
						|
    ]
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
function forEachComment(fn) {
 | 
						|
  forOf(comments, function(name, comment) {
 | 
						|
    var description = "the '" + name + "' syntax with "
 | 
						|
    fn(comment.join("\n"),   description + "regular newlines")
 | 
						|
    fn(comment.join("\r\n"), description + "Windows newlines")
 | 
						|
  })
 | 
						|
}
 | 
						|
 | 
						|
function forEachNonTrailingComment(fn) {
 | 
						|
  forOf(nonTrailingComments, function(name, comment) {
 | 
						|
 | 
						|
    var description = "the '" + name + "' syntax with "
 | 
						|
 | 
						|
    fn({
 | 
						|
      contents: comment.contents.join("\n"),
 | 
						|
      solution: comment.solution.join("\n")
 | 
						|
    }, description + "regular newlines")
 | 
						|
 | 
						|
    fn({
 | 
						|
      contents: comment.contents.join("\r\n"),
 | 
						|
      solution: comment.solution.join("\r\n")
 | 
						|
    }, description + "Windows newlines")
 | 
						|
  })
 | 
						|
}
 | 
						|
 | 
						|
function forOf(obj, fn) {
 | 
						|
  for (var key in obj) {
 | 
						|
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
 | 
						|
      fn(key, obj[key])
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
describe("sourceMappingURL", function() {
 | 
						|
 | 
						|
  describe(".getFrom", function() {
 | 
						|
 | 
						|
    forEachComment(function(comment, description) {
 | 
						|
 | 
						|
      it("gets the url from " + description, function() {
 | 
						|
        expect(sourceMappingURL.getFrom("code\n" + comment))
 | 
						|
          .to.equal("foo.js.map")
 | 
						|
 | 
						|
        expect(sourceMappingURL.getFrom("code" + comment))
 | 
						|
          .to.equal("foo.js.map")
 | 
						|
 | 
						|
        expect(sourceMappingURL.getFrom(comment))
 | 
						|
          .to.equal("foo.js.map")
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
    forEachNonTrailingComment(function(comment, description) {
 | 
						|
 | 
						|
      it("gets the url from " + description, function() {
 | 
						|
        expect(sourceMappingURL.getFrom("code\n" + comment.contents))
 | 
						|
          .to.equal("foo.js.map")
 | 
						|
 | 
						|
        expect(sourceMappingURL.getFrom("code" + comment.contents))
 | 
						|
          .to.equal("foo.js.map")
 | 
						|
 | 
						|
        expect(sourceMappingURL.getFrom(comment.contents))
 | 
						|
          .to.equal("foo.js.map")
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("returns null if no comment", function() {
 | 
						|
      expect(sourceMappingURL.getFrom("code"))
 | 
						|
        .to.equal(null)
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("can return an empty string as url", function() {
 | 
						|
      expect(sourceMappingURL.getFrom("/*# sourceMappingURL= */"))
 | 
						|
        .to.equal("")
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("is detachable", function() {
 | 
						|
      var get = sourceMappingURL.getFrom
 | 
						|
      expect(get("/*# sourceMappingURL=foo */"))
 | 
						|
        .to.equal("foo")
 | 
						|
    })
 | 
						|
 | 
						|
  })
 | 
						|
 | 
						|
 | 
						|
  describe(".existsIn", function() {
 | 
						|
 | 
						|
    forEachComment(function(comment, description) {
 | 
						|
 | 
						|
      it("returns true for " + description, function() {
 | 
						|
        expect(sourceMappingURL.existsIn("code\n" + comment))
 | 
						|
          .to.equal(true)
 | 
						|
 | 
						|
        expect(sourceMappingURL.existsIn("code" + comment))
 | 
						|
          .to.equal(true)
 | 
						|
 | 
						|
        expect(sourceMappingURL.existsIn(comment))
 | 
						|
          .to.equal(true)
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
    forEachNonTrailingComment(function(comment, description) {
 | 
						|
 | 
						|
      it("returns true for " + description, function() {
 | 
						|
        expect(sourceMappingURL.existsIn("code\n" + comment.contents))
 | 
						|
          .to.equal(true)
 | 
						|
 | 
						|
        expect(sourceMappingURL.existsIn("code" + comment.contents))
 | 
						|
          .to.equal(true)
 | 
						|
 | 
						|
        expect(sourceMappingURL.existsIn(comment.contents))
 | 
						|
          .to.equal(true)
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("returns false if no comment", function() {
 | 
						|
      expect(sourceMappingURL.existsIn("code"))
 | 
						|
        .to.equal(false)
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("is detachable", function() {
 | 
						|
      var has = sourceMappingURL.existsIn
 | 
						|
      expect(has("/*# sourceMappingURL=foo */"))
 | 
						|
        .to.equal(true)
 | 
						|
    })
 | 
						|
 | 
						|
  })
 | 
						|
 | 
						|
 | 
						|
  describe(".removeFrom", function() {
 | 
						|
 | 
						|
    forEachComment(function(comment, description) {
 | 
						|
 | 
						|
      it("removes the comment for " + description, function() {
 | 
						|
        expect(sourceMappingURL.removeFrom("code\n" + comment))
 | 
						|
          .to.equal("code\n")
 | 
						|
 | 
						|
        expect(sourceMappingURL.removeFrom("code" + comment))
 | 
						|
          .to.equal("code")
 | 
						|
 | 
						|
        expect(sourceMappingURL.removeFrom(comment))
 | 
						|
          .to.equal("")
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
    forEachNonTrailingComment(function(comment, description) {
 | 
						|
 | 
						|
      it("removes the comment for " + description, function() {
 | 
						|
        expect(sourceMappingURL.removeFrom("code\n" + comment.contents))
 | 
						|
          .to.equal("code\n" + comment.solution)
 | 
						|
 | 
						|
        expect(sourceMappingURL.removeFrom("code" + comment.contents))
 | 
						|
          .to.equal("code" + comment.solution)
 | 
						|
 | 
						|
        expect(sourceMappingURL.removeFrom(comment.contents))
 | 
						|
          .to.equal(comment.solution)
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("does nothing if no comment", function() {
 | 
						|
      expect(sourceMappingURL.removeFrom("code\n"))
 | 
						|
        .to.equal("code\n")
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("is detachable", function() {
 | 
						|
      var remove = sourceMappingURL.removeFrom
 | 
						|
      expect(remove("/*# sourceMappingURL=foo */"))
 | 
						|
        .to.equal("")
 | 
						|
    })
 | 
						|
 | 
						|
  })
 | 
						|
 | 
						|
 | 
						|
  describe(".insertBefore", function() {
 | 
						|
 | 
						|
    forEachComment(function(comment, description) {
 | 
						|
 | 
						|
      it("inserts a string before the comment for " + description, function() {
 | 
						|
        expect(sourceMappingURL.insertBefore("code\n" + comment, "more code\n"))
 | 
						|
          .to.equal("code\nmore code\n" + comment)
 | 
						|
 | 
						|
        expect(sourceMappingURL.insertBefore("code" + comment, "\nmore code"))
 | 
						|
          .to.equal("code\nmore code" + comment)
 | 
						|
 | 
						|
        expect(sourceMappingURL.insertBefore(comment, "some code"))
 | 
						|
          .to.equal("some code" + comment)
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("inserts a string before an embedded comment", function() {
 | 
						|
      expect(sourceMappingURL.insertBefore("/*! Library Name v1.0.0\n" +
 | 
						|
        "//# sourceMappingURL=foo.js.map\n*/\n(function(){})", "code\n"))
 | 
						|
        .to.equal("/*! Library Name v1.0.0\ncode\n" +
 | 
						|
          "//# sourceMappingURL=foo.js.map\n*/\n(function(){})")
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("inserts a string before a leading comment", function() {
 | 
						|
      expect(sourceMappingURL.insertBefore("//# sourceMappingURL=foo.js.map\n" +
 | 
						|
        "(function(){})", "code\n"))
 | 
						|
        .to.equal("code\n//# sourceMappingURL=foo.js.map\n" +
 | 
						|
          "(function(){})")
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("appends if no comment", function() {
 | 
						|
      expect(sourceMappingURL.insertBefore("code", "\nmore code"))
 | 
						|
        .to.equal("code\nmore code")
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("is detachable", function() {
 | 
						|
      var insertBefore = sourceMappingURL.insertBefore
 | 
						|
      expect(insertBefore("/*# sourceMappingURL=foo */", "bar"))
 | 
						|
        .to.equal("bar/*# sourceMappingURL=foo */")
 | 
						|
    })
 | 
						|
 | 
						|
  })
 | 
						|
 | 
						|
 | 
						|
  describe(".regex", function() {
 | 
						|
 | 
						|
    it("includes ._innerRegex", function() {
 | 
						|
      expect(sourceMappingURL.regex.source)
 | 
						|
        .to.contain(sourceMappingURL._innerRegex.source)
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    var match = function(code) {
 | 
						|
      expect(code)
 | 
						|
        .to.match(sourceMappingURL.regex)
 | 
						|
    }
 | 
						|
 | 
						|
    var noMatch = function(code) {
 | 
						|
      expect(code)
 | 
						|
        .not.to.match(sourceMappingURL.regex)
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    forEachComment(function(comment, description) {
 | 
						|
 | 
						|
      it("matches " + description, function() {
 | 
						|
        match("code\n" + comment)
 | 
						|
        match("code" + comment)
 | 
						|
        match(comment)
 | 
						|
      })
 | 
						|
 | 
						|
 | 
						|
      it("matches " + description + ", with trailing whitespace", function() {
 | 
						|
        match(comment + "  ")
 | 
						|
        match(comment + "\n")
 | 
						|
        match(comment + "\n\n\t\n    \t  ")
 | 
						|
      })
 | 
						|
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("does not match some cases that are easy to mess up", function() {
 | 
						|
      noMatch(
 | 
						|
        "/* # sourceMappingURL=foo */"
 | 
						|
      )
 | 
						|
 | 
						|
      noMatch(
 | 
						|
        "// # sourceMappingURL=foo"
 | 
						|
      )
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("is liberal regarding inner whitespace", function() {
 | 
						|
      match(
 | 
						|
        "/*# sourceMappingURL=foo*/"
 | 
						|
      )
 | 
						|
 | 
						|
      match(
 | 
						|
        "/*# sourceMappingURL=foo    */"
 | 
						|
      )
 | 
						|
 | 
						|
      match(
 | 
						|
        "/*# sourceMappingURL=foo   \t\n" +
 | 
						|
        "*/"
 | 
						|
      )
 | 
						|
 | 
						|
      match(
 | 
						|
        "/*    \n" +
 | 
						|
        "# sourceMappingURL=foo\n" +
 | 
						|
        "*/"
 | 
						|
      )
 | 
						|
 | 
						|
      match(
 | 
						|
        "/*\n" +
 | 
						|
        "# sourceMappingURL=foo\n" +
 | 
						|
        "     */"
 | 
						|
      )
 | 
						|
 | 
						|
      match(
 | 
						|
        "/*\n" +
 | 
						|
        "# sourceMappingURL=foo\n" +
 | 
						|
        "\n" +
 | 
						|
        "\t\n" +
 | 
						|
        "*/"
 | 
						|
      )
 | 
						|
    })
 | 
						|
 | 
						|
  })
 | 
						|
 | 
						|
 | 
						|
  describe("._innerRegex", function() {
 | 
						|
 | 
						|
    it("matches the contents of sourceMappingURL comments", function() {
 | 
						|
      expect("# sourceMappingURL=http://www.example.com/foo/bar.js.map")
 | 
						|
        .to.match(sourceMappingURL._innerRegex)
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("captures the url in the first capture group", function() {
 | 
						|
      expect(sourceMappingURL._innerRegex.exec("# sourceMappingURL=foo")[1])
 | 
						|
        .to.equal("foo")
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
    it("supports the legacy syntax", function() {
 | 
						|
      expect("@ sourceMappingURL=http://www.example.com/foo/bar.js.map")
 | 
						|
        .to.match(sourceMappingURL._innerRegex)
 | 
						|
    })
 | 
						|
 | 
						|
  })
 | 
						|
 | 
						|
})
 |