...

Source file src/github.com/go-sourcemap/sourcemap/consumer_test.go

Documentation: github.com/go-sourcemap/sourcemap

     1  package sourcemap_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/go-sourcemap/sourcemap"
    12  )
    13  
    14  const jqSourceMapURL = "http://code.jquery.com/jquery-2.0.3.min.map"
    15  
    16  var jqSourceMapBytes []byte
    17  
    18  func init() {
    19  	resp, err := http.Get(jqSourceMapURL)
    20  	if err != nil {
    21  		panic(err)
    22  	}
    23  	defer resp.Body.Close()
    24  
    25  	jqSourceMapBytes, err = ioutil.ReadAll(resp.Body)
    26  	if err != nil {
    27  		panic(err)
    28  	}
    29  }
    30  
    31  type sourceMapTest struct {
    32  	genLine      int
    33  	genColumn    int
    34  	wantedSource string
    35  	wantedName   string
    36  	wantedLine   int
    37  	wantedColumn int
    38  }
    39  
    40  func (test *sourceMapTest) String() string {
    41  	return fmt.Sprintf("line=%d col=%d in file=%s", test.genLine, test.genColumn, test.wantedSource)
    42  }
    43  
    44  func (test *sourceMapTest) assert(t *testing.T, smap *sourcemap.Consumer) {
    45  	source, name, line, col, ok := smap.Source(test.genLine, test.genColumn)
    46  	if !ok {
    47  		if test.wantedSource == "" &&
    48  			test.wantedName == "" &&
    49  			test.wantedLine == 0 &&
    50  			test.wantedColumn == 0 {
    51  			return
    52  		}
    53  		t.Fatalf("Source not found for %s", test)
    54  	}
    55  	if source != test.wantedSource {
    56  		t.Fatalf("file: got %q, wanted %q (%s)", source, test.wantedSource, test)
    57  	}
    58  	if name != test.wantedName {
    59  		t.Fatalf("func: got %q, wanted %q (%s)", name, test.wantedName, test)
    60  	}
    61  	if line != test.wantedLine {
    62  		t.Fatalf("line: got %d, wanted %d (%s)", line, test.wantedLine, test)
    63  	}
    64  	if col != test.wantedColumn {
    65  		t.Fatalf("column: got %d, wanted %d (%s)", col, test.wantedColumn, test)
    66  	}
    67  }
    68  
    69  func TestSourceMap(t *testing.T) {
    70  	testSourceMap(t, sourceMapJSON)
    71  }
    72  
    73  func TestIndexedSourceMap(t *testing.T) {
    74  	testSourceMap(t, indexedSourceMapJSON)
    75  }
    76  
    77  func testSourceMap(t *testing.T, json string) {
    78  	smap, err := sourcemap.Parse("", []byte(json))
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  
    83  	tests := []sourceMapTest{
    84  		{1, 1, "/the/root/one.js", "", 1, 1},
    85  		{1, 5, "/the/root/one.js", "", 1, 5},
    86  		{1, 9, "/the/root/one.js", "", 1, 11},
    87  		{1, 18, "/the/root/one.js", "bar", 1, 21},
    88  		{1, 21, "/the/root/one.js", "", 2, 3},
    89  		{1, 28, "/the/root/one.js", "baz", 2, 10},
    90  		{1, 32, "/the/root/one.js", "bar", 2, 14},
    91  
    92  		{2, 1, "/the/root/two.js", "", 1, 1},
    93  		{2, 5, "/the/root/two.js", "", 1, 5},
    94  		{2, 9, "/the/root/two.js", "", 1, 11},
    95  		{2, 18, "/the/root/two.js", "n", 1, 21},
    96  		{2, 21, "/the/root/two.js", "", 2, 3},
    97  		{2, 28, "/the/root/two.js", "n", 2, 10},
    98  
    99  		// Fuzzy match.
   100  		{1, 20, "/the/root/one.js", "bar", 1, 21},
   101  		{1, 30, "/the/root/one.js", "baz", 2, 10},
   102  		{2, 12, "/the/root/two.js", "", 1, 11},
   103  	}
   104  	for i := range tests {
   105  		tests[i].assert(t, smap)
   106  	}
   107  
   108  	content := smap.SourceContent("/the/root/one.js")
   109  	if content != oneSourceContent {
   110  		t.Fatalf("%q != %q", content, oneSourceContent)
   111  	}
   112  
   113  	content = smap.SourceContent("/the/root/two.js")
   114  	if content != twoSourceContent {
   115  		t.Fatalf("%q != %q", content, twoSourceContent)
   116  	}
   117  
   118  	_, _, _, _, ok := smap.Source(3, 0)
   119  	if ok {
   120  		t.Fatal("source must not exist")
   121  	}
   122  }
   123  
   124  func TestSourceRootURL(t *testing.T) {
   125  	jsonStr := sourceMapJSON
   126  	jsonStr = strings.Replace(jsonStr, "/the/root", "http://the/root", 1)
   127  	jsonStr = strings.Replace(jsonStr, "one.js", "../one.js", 1)
   128  
   129  	smap, err := sourcemap.Parse("", []byte(jsonStr))
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  
   134  	tests := []*sourceMapTest{
   135  		{1, 1, "http://the/one.js", "", 1, 1},
   136  		{2, 1, "http://the/root/two.js", "", 1, 1},
   137  	}
   138  	for _, test := range tests {
   139  		test.assert(t, smap)
   140  	}
   141  }
   142  
   143  func TestEmptySourceRootURL(t *testing.T) {
   144  	jsonStr := sourceMapJSON
   145  	jsonStr = strings.Replace(jsonStr, "/the/root", "", 1)
   146  	jsonStr = strings.Replace(jsonStr, "one.js", "../one.js", 1)
   147  
   148  	smap, err := sourcemap.Parse("http://the/root/app.min.map", []byte(jsonStr))
   149  	if err != nil {
   150  		t.Fatal(err)
   151  	}
   152  
   153  	tests := []*sourceMapTest{
   154  		{1, 1, "http://the/one.js", "", 1, 1},
   155  		{2, 1, "http://the/root/two.js", "", 1, 1},
   156  	}
   157  	for _, test := range tests {
   158  		test.assert(t, smap)
   159  	}
   160  }
   161  
   162  func TestAbsSourceURL(t *testing.T) {
   163  	jsonStr := sourceMapJSON
   164  	jsonStr = strings.Replace(jsonStr, "/the/root", "", 1)
   165  	jsonStr = strings.Replace(jsonStr, "one.js", "http://the/root/one.js", 1)
   166  	jsonStr = strings.Replace(jsonStr, "two.js", "/another/root/two.js", 1)
   167  
   168  	testAbsSourceURL(t, "", jsonStr)
   169  	testAbsSourceURL(t, "http://path/to/map", jsonStr)
   170  }
   171  
   172  func testAbsSourceURL(t *testing.T, mapURL, jsonStr string) {
   173  	smap, err := sourcemap.Parse(mapURL, []byte(jsonStr))
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	tests := []*sourceMapTest{
   179  		{1, 1, "http://the/root/one.js", "", 1, 1},
   180  		{2, 1, "/another/root/two.js", "", 1, 1},
   181  	}
   182  	for _, test := range tests {
   183  		test.assert(t, smap)
   184  	}
   185  }
   186  
   187  func TestJQuerySourceMap(t *testing.T) {
   188  	smap, err := sourcemap.Parse(jqSourceMapURL, jqSourceMapBytes)
   189  	if err != nil {
   190  		t.Fatal(err)
   191  	}
   192  
   193  	tests := []*sourceMapTest{
   194  		{1, 1, "", "", 0, 0},
   195  		{4, 0, "", "", 0, 0},
   196  		{4, 1, "http://code.jquery.com/jquery-2.0.3.js", "", 14, 0},
   197  		{4, 10, "http://code.jquery.com/jquery-2.0.3.js", "window", 14, 11},
   198  		{5, 6789, "http://code.jquery.com/jquery-2.0.3.js", "apply", 4360, 27},
   199  		{5, 10006, "http://code.jquery.com/jquery-2.0.3.js", "apply", 4676, 8},
   200  		{4, 553, "http://code.jquery.com/jquery-2.0.3.js", "ready", 93, 9},
   201  		{999999, 0, "", "", 0, 0},
   202  	}
   203  	for _, test := range tests {
   204  		test.assert(t, smap)
   205  	}
   206  }
   207  
   208  // https://github.com/mozilla/source-map/blob/master/test/util.js
   209  //
   210  // This is a test mapping which maps functions from two different files
   211  // (one.js and two.js) to a minified generated source.
   212  //
   213  // Here is one.js:
   214  //
   215  //     ONE.foo = function (bar) {
   216  //       return baz(bar);
   217  //     };
   218  //
   219  // Here is two.js:
   220  //
   221  //     TWO.inc = function (n) {
   222  //       return n + 1;
   223  //     };
   224  //
   225  // And here is the generated code (min.js):
   226  //
   227  //     ONE.foo=function(a){return baz(a);};
   228  //     TWO.inc=function(a){return a+1;};
   229  
   230  const genCode = `exports.testGeneratedCode = "ONE.foo=function(a){return baz(a);};
   231  TWO.inc=function(a){return a+1;};`
   232  
   233  var oneSourceContent = `ONE.foo = function (bar) {
   234    return baz(bar);
   235  };`
   236  
   237  var twoSourceContent = `TWO.inc = function (n) {
   238    return n + 1;
   239  };`
   240  
   241  var sourceMapJSON = `{
   242    "version": 3,
   243    "file": "min.js",
   244    "sources": ["one.js", "two.js"],
   245    "sourcesContent": ` + j([]string{oneSourceContent, twoSourceContent}) + `,
   246    "sourceRoot": "/the/root",
   247    "names": ["bar", "baz", "n"],
   248    "mappings": "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA"
   249  }`
   250  
   251  func j(v interface{}) string {
   252  	b, _ := json.Marshal(v)
   253  	return string(b)
   254  }
   255  
   256  var indexedSourceMapJSON = `{
   257    "version": 3,
   258    "file": "min.js",
   259    "sections": [{
   260      "offset": {"line": 0, "column": 0},
   261      "map": {
   262        "version": 3,
   263        "file": "min.js",
   264        "sources": ["one.js"],
   265        "sourcesContent": ` + j([]string{oneSourceContent}) + `,
   266        "sourceRoot": "/the/root",
   267        "names": ["bar", "baz"],
   268        "mappings": "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID"
   269      }
   270    }, {
   271      "offset": {"line": 1, "column": 0},
   272      "map": {
   273        "version": 3,
   274        "file": "min.js",
   275        "sources": ["two.js"],
   276        "sourcesContent": ` + j([]string{twoSourceContent}) + `,
   277        "sourceRoot": "/the/root",
   278        "names": ["n"],
   279        "mappings": "CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOA"
   280      }
   281    }]
   282  }`
   283  

View as plain text