func TestParseOptPortSpc(t *testing.T) {
	p := NewParseOptPortSpc()

	runTest(t, p, "empty", "", nil, 0)
	runTest(t, p, "no space", "p.1", nil, 0)
	runTest(t, p, "no match 2", "pt. ", nil, 0)
	runTest(t, p, "simple 1", "p ", data.NewPort("p", 0), 0)
	runTest(t, p, "simple 2", "pt.0\t", data.NewIdxPort("pt", 0, 0), 0)
	runTest(t, p, "long port name", "looooongPortName \t ", data.NewPort("looooongPortName", 0), 0)
	runTest(t, p, "name and index", "port.123 \t ", data.NewIdxPort("port", 123, 0), 0)
	runTest(t, p, "too large index", "port.9999999999 ", nil, 1)
}
func TestParsePort(t *testing.T) {
	p := NewParsePort()

	runTest(t, p, "empty", "", nil, 1)
	runTest(t, p, "no match", ".1", nil, 1)
	runTest(t, p, "half match 1", "pt.", data.NewPort("pt", 0), 0)
	runTest(t, p, "half match 2", "pt_1", data.NewPort("pt", 0), 0)
	runTest(t, p, "simple 1", "p", data.NewPort("p", 0), 0)
	runTest(t, p, "simple 2", "pt.0", data.NewIdxPort("pt", 0, 0), 0)
	runTest(t, p, "long port name", "looooongPortName", data.NewPort("looooongPortName", 0), 0)
	runTest(t, p, "name and index", "port.123", data.NewIdxPort("port", 123, 0), 0)
	runTest(t, p, "too large index", "port.9999999999", nil, 1)
}
func TestParseChainEnd(t *testing.T) {
	p := NewParseChainEnd()

	runTest(t, p, "empty", "", nil, 1)
	runTest(t, p, "no match 1", "-", nil, 1)
	runTest(t, p, "no match 3", " /* \n */ \t [Bla]>", nil, 1)
	runTest(t, p, "no ports, no type", "->",
		&data.Connection{FromPort: data.NewPort("", 0), ToPort: data.NewPort("", 2)}, 0)
	runTest(t, p, "no ports but a type", " \t [Bla]-> ",
		&data.Connection{DataType: "Bla", FromPort: data.NewPort("", 0), ToPort: data.NewPort("", 11)}, 0)
	runTest(t, p, "out-port and no type", " \r\n // blu \n \t -> \r\n outX.3",
		&data.Connection{FromPort: data.NewPort("", 0), ToPort: data.NewIdxPort("outX", 3, 21)}, 0)
	runTest(t, p, "out-port and type", "\n \t /* Bla */ [ \t Blu \t ]->  \t outX.7",
		&data.Connection{DataType: "Blu", FromPort: data.NewPort("", 0), ToPort: data.NewIdxPort("outX", 7, 31)}, 0)
}
func (op *SemanticPort) InPort(dat interface{}) {
	md := dat.(*data.MainData)
	pd := md.ParseData
	nameRes := pd.SubResults[0]

	if pd.SubResults[1].Value == nil {
		md.ParseData.Result.Value = data.NewPort(nameRes.Text, nameRes.Pos)
	} else {
		val := pd.SubResults[1].Value
		idx64 := val.([]interface{})[1].(uint64)
		if idx64 > uint64(math.MaxInt32) {
			errPos := pd.SubResults[1].Pos + 1
			gparselib.AddError(errPos, "Ridiculous large port index "+strconv.FormatUint(idx64, 10), nil, pd)
			md.ParseData.Result.ErrPos = -1 // just a semantic error, no syntax error!
			md.ParseData.Result.Value = nil
		} else {
			md.ParseData.Result.Value = data.NewIdxPort(nameRes.Text, int(idx64), nameRes.Pos)
		}
	}
	op.outPort(md)
}