github.com/cilki/sh@v2.6.4+incompatible/_js/testmain.js (about)

     1  const assert = require('assert').strict
     2  const stream = require('stream')
     3  
     4  const sh = require('./index')
     5  
     6  const syntax = sh.syntax
     7  const parser = syntax.NewParser()
     8  const printer = syntax.NewPrinter()
     9  
    10  {
    11  	// parsing a simple program
    12  	const src = "echo 'foo'"
    13  	var f = parser.Parse(src, "src")
    14  
    15  	var stmts = f.StmtList.Stmts
    16  	assert.equal(stmts.length, 1)
    17  
    18  	var args = stmts[0].Cmd.Args
    19  	assert.equal(args.length, 2)
    20  	assert.equal(args[0].Parts.length, 1)
    21  	assert.equal(args[0].Parts[0].Value, "echo")
    22  }
    23  
    24  {
    25  	// accessing fields or methods creates separate objects
    26  	const src = "echo 'foo'"
    27  	var f = parser.Parse(src, "src")
    28  
    29  	assert.equal(f.StmtList.Stmts == f.StmtList.Stmts, false)
    30  	assert.equal(f.StmtList.Stmts === f.StmtList.Stmts, false)
    31  	var stmts = f.StmtList.Stmts
    32  	assert.equal(stmts == stmts, true)
    33  	assert.equal(stmts === stmts, true)
    34  }
    35  
    36  {
    37  	// parse errors
    38  	const src = "echo ${"
    39  	try {
    40  		parser.Parse(src, "src")
    41  		assert.fail("did not error")
    42  	} catch (err) {
    43  	}
    44  }
    45  
    46  {
    47  	// node types, operators, and positions
    48  	const src = "foo || bar"
    49  	var f = parser.Parse(src, "src")
    50  
    51  	var cmd = f.StmtList.Stmts[0].Cmd
    52  	assert.equal(syntax.NodeType(cmd), "BinaryCmd")
    53  
    54  	// TODO: see https://github.com/myitcv/gopherjs/issues/26
    55  	// assert.equal(syntax.String(cmd.Op), "||")
    56  
    57  	assert.equal(cmd.Pos().String(), "1:1")
    58  	assert.equal(cmd.OpPos.String(), "1:5")
    59  	assert.equal(cmd.OpPos.Line(), 1)
    60  	assert.equal(cmd.OpPos.Col(), 5)
    61  	assert.equal(cmd.OpPos.Offset(), 4)
    62  }
    63  
    64  {
    65  	// running Walk
    66  	const src = "foo bar"
    67  	var f = parser.Parse(src, "src")
    68  
    69  	var nilCount = 0
    70  	var nonNilCount = 0
    71  	var seenBar = false
    72  	var seenCall = false
    73  	syntax.Walk(f, function(node) {
    74  		var typ = syntax.NodeType(node)
    75  		if (node == null) {
    76  			nilCount++
    77  			assert.equal(typ, "nil")
    78  		} else {
    79  			nonNilCount++
    80  			if (node.Value == "bar") {
    81  				seenBar = true
    82  			}
    83  			assert.notEqual(typ, "nil")
    84  		}
    85  		if (typ == "CallExpr") {
    86  			seenCall = true
    87  		}
    88  		return true
    89  	})
    90  	assert.equal(nonNilCount, 7)
    91  	assert.equal(nilCount, 7)
    92  	assert.equal(seenBar, true)
    93  	assert.equal(seenCall, true)
    94  }
    95  
    96  {
    97  	// printing
    98  	const src = "echo      'foo'"
    99  	var f = parser.Parse(src, "src")
   100  
   101  	var out = printer.Print(f)
   102  	assert.equal(out, "echo 'foo'\n")
   103  }
   104  
   105  {
   106  	// parser options
   107  	const parser = syntax.NewParser(
   108  		syntax.KeepComments,
   109  		syntax.Variant(syntax.LangMirBSDKorn),
   110  		syntax.StopAt("$$")
   111  	)
   112  	const src = "echo ${|stmts;} # bar\n$$"
   113  	var f = parser.Parse(src, "src")
   114  
   115  	var out = printer.Print(f)
   116  	assert.equal(out, "echo ${|stmts;} # bar\n")
   117  }
   118  
   119  {
   120  	// parsing a readable stream
   121  	const src = new stream.Readable
   122  	src.push("echo foo")
   123  	src.push(null)
   124  
   125  	var f = parser.Parse(src, "src")
   126  
   127  	var cmd = f.StmtList.Stmts[0].Cmd
   128  	assert.equal(cmd.Args.length, 2)
   129  }
   130  
   131  {
   132  	// using the parser interactively
   133  	const inputs = [
   134  		"foo\n",
   135  		"bar; baz\n",
   136  		"\n",
   137  		"'incom\n",
   138  		"plete'\n",
   139  	]
   140  	const wantCallbacks = [
   141  		{"count": 1, "incomplete": false},
   142  		{"count": 2, "incomplete": false},
   143  		{"count": 0, "incomplete": false},
   144  		{"count": 0, "incomplete": true},
   145  		{"count": 1, "incomplete": false},
   146  	]
   147  	var gotCallbacks = []
   148  
   149  	const src = {"read": function(size) {
   150  		if (inputs.length == 0) {
   151  			if (gotCallbacks.length == 0) {
   152  				throw "did not see any callbacks before EOF"
   153  			}
   154  			return null // EOF
   155  		}
   156  		s = inputs[0]
   157  		inputs.shift()
   158  		return s
   159  	}}
   160  
   161  	parser.Interactive(src, function(stmts) {
   162  		gotCallbacks.push({
   163  			"count":      stmts.length,
   164  			"incomplete": parser.Incomplete(),
   165  		})
   166  		return true
   167  	})
   168  	assert.deepEqual(gotCallbacks, wantCallbacks)
   169  }