Skip to content

Commit a9dddb5

Browse files
committed
encoding/xml: add more EncodeToken tests.
There are no behavior changes in this CL, only specifying the status quo. A follow-up CL, https://go-review.googlesource.com/#/c/2660/, will change the EncodeToken behavior. Change-Id: I6ecbcfb05ae681de71fa1099d054df2826ed4acb Reviewed-on: https://go-review.googlesource.com/4167 Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 2978ebb commit a9dddb5

1 file changed

Lines changed: 347 additions & 25 deletions

File tree

src/encoding/xml/marshal_test.go

Lines changed: 347 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,41 +1194,363 @@ func TestStructPointerMarshal(t *testing.T) {
11941194
}
11951195

11961196
var encodeTokenTests = []struct {
1197-
tok Token
1197+
desc string
1198+
toks []Token
11981199
want string
1199-
ok bool
1200-
}{
1201-
{StartElement{Name{"space", "local"}, nil}, "<local xmlns=\"space\">", true},
1202-
{StartElement{Name{"space", ""}, nil}, "", false},
1203-
{EndElement{Name{"space", ""}}, "", false},
1204-
{CharData("foo"), "foo", true},
1205-
{Comment("foo"), "<!--foo-->", true},
1206-
{Comment("foo-->"), "", false},
1207-
{ProcInst{"Target", []byte("Instruction")}, "<?Target Instruction?>", true},
1208-
{ProcInst{"", []byte("Instruction")}, "", false},
1209-
{ProcInst{"Target", []byte("Instruction?>")}, "", false},
1210-
{Directive("foo"), "<!foo>", true},
1211-
{Directive("foo>"), "", false},
1212-
}
1200+
err string
1201+
}{{
1202+
desc: "start element with name space",
1203+
toks: []Token{
1204+
StartElement{Name{"space", "local"}, nil},
1205+
},
1206+
want: `<local xmlns="space">`,
1207+
}, {
1208+
desc: "start element with no name",
1209+
toks: []Token{
1210+
StartElement{Name{"space", ""}, nil},
1211+
},
1212+
err: "xml: start tag with no name",
1213+
}, {
1214+
desc: "end element with no name",
1215+
toks: []Token{
1216+
EndElement{Name{"space", ""}},
1217+
},
1218+
err: "xml: end tag with no name",
1219+
}, {
1220+
desc: "char data",
1221+
toks: []Token{
1222+
CharData("foo"),
1223+
},
1224+
want: `foo`,
1225+
}, {
1226+
desc: "char data with escaped chars",
1227+
toks: []Token{
1228+
CharData(" \t\n"),
1229+
},
1230+
want: ` &#x9;&#xA;`,
1231+
}, {
1232+
desc: "comment",
1233+
toks: []Token{
1234+
Comment("foo"),
1235+
},
1236+
want: `<!--foo-->`,
1237+
}, {
1238+
desc: "comment with invalid content",
1239+
toks: []Token{
1240+
Comment("foo-->"),
1241+
},
1242+
err: "xml: EncodeToken of Comment containing --> marker",
1243+
}, {
1244+
desc: "proc instruction",
1245+
toks: []Token{
1246+
ProcInst{"Target", []byte("Instruction")},
1247+
},
1248+
want: `<?Target Instruction?>`,
1249+
}, {
1250+
desc: "proc instruction with empty target",
1251+
toks: []Token{
1252+
ProcInst{"", []byte("Instruction")},
1253+
},
1254+
err: "xml: EncodeToken of ProcInst with invalid Target",
1255+
}, {
1256+
desc: "proc instruction with bad content",
1257+
toks: []Token{
1258+
ProcInst{"", []byte("Instruction?>")},
1259+
},
1260+
err: "xml: EncodeToken of ProcInst with invalid Target",
1261+
}, {
1262+
desc: "directive",
1263+
toks: []Token{
1264+
Directive("foo"),
1265+
},
1266+
want: `<!foo>`,
1267+
}, {
1268+
desc: "directive instruction with bad name",
1269+
toks: []Token{
1270+
Directive("foo>"),
1271+
},
1272+
err: "xml: EncodeToken of Directive containing > marker",
1273+
}, {
1274+
desc: "end tag without start tag",
1275+
toks: []Token{
1276+
EndElement{Name{"foo", "bar"}},
1277+
},
1278+
err: "xml: end tag </bar> without start tag",
1279+
}, {
1280+
desc: "mismatching end tag local name",
1281+
toks: []Token{
1282+
StartElement{Name{"", "foo"}, nil},
1283+
EndElement{Name{"", "bar"}},
1284+
},
1285+
err: "xml: end tag </bar> does not match start tag <foo>",
1286+
want: `<foo>`,
1287+
}, {
1288+
desc: "mismatching end tag namespace",
1289+
toks: []Token{
1290+
StartElement{Name{"space", "foo"}, nil},
1291+
EndElement{Name{"another", "foo"}},
1292+
},
1293+
err: "xml: end tag </foo> in namespace another does not match start tag <foo> in namespace space",
1294+
want: `<foo xmlns="space">`,
1295+
}, {
1296+
desc: "start element with explicit namespace",
1297+
toks: []Token{
1298+
StartElement{Name{"space", "local"}, []Attr{
1299+
{Name{"xmlns", "x"}, "space"},
1300+
{Name{"space", "foo"}, "value"},
1301+
}},
1302+
},
1303+
want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value">`,
1304+
}, {
1305+
desc: "start element with explicit namespace and colliding prefix",
1306+
toks: []Token{
1307+
StartElement{Name{"space", "local"}, []Attr{
1308+
{Name{"xmlns", "x"}, "space"},
1309+
{Name{"space", "foo"}, "value"},
1310+
{Name{"x", "bar"}, "other"},
1311+
}},
1312+
},
1313+
want: `<local xmlns="space" xmlns:_xmlns="xmlns" _xmlns:x="space" xmlns:space="space" space:foo="value" xmlns:x="x" x:bar="other">`,
1314+
}, {
1315+
desc: "start element using previously defined namespace",
1316+
toks: []Token{
1317+
StartElement{Name{"", "local"}, []Attr{
1318+
{Name{"xmlns", "x"}, "space"},
1319+
}},
1320+
StartElement{Name{"space", "foo"}, []Attr{
1321+
{Name{"space", "x"}, "y"},
1322+
}},
1323+
},
1324+
want: `<local xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns:space="space" space:x="y">`,
1325+
}, {
1326+
desc: "nested name space with same prefix",
1327+
toks: []Token{
1328+
StartElement{Name{"", "foo"}, []Attr{
1329+
{Name{"xmlns", "x"}, "space1"},
1330+
}},
1331+
StartElement{Name{"", "foo"}, []Attr{
1332+
{Name{"xmlns", "x"}, "space2"},
1333+
}},
1334+
StartElement{Name{"", "foo"}, []Attr{
1335+
{Name{"space1", "a"}, "space1 value"},
1336+
{Name{"space2", "b"}, "space2 value"},
1337+
}},
1338+
EndElement{Name{"", "foo"}},
1339+
EndElement{Name{"", "foo"}},
1340+
StartElement{Name{"", "foo"}, []Attr{
1341+
{Name{"space1", "a"}, "space1 value"},
1342+
{Name{"space2", "b"}, "space2 value"},
1343+
}},
1344+
},
1345+
want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space1"><foo _xmlns:x="space2"><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value"></foo></foo><foo xmlns:space1="space1" space1:a="space1 value" xmlns:space2="space2" space2:b="space2 value">`,
1346+
}, {
1347+
desc: "start element defining several prefixes for the same name space",
1348+
toks: []Token{
1349+
StartElement{Name{"space", "foo"}, []Attr{
1350+
{Name{"xmlns", "a"}, "space"},
1351+
{Name{"xmlns", "b"}, "space"},
1352+
{Name{"space", "x"}, "value"},
1353+
}},
1354+
},
1355+
want: `<foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:a="space" _xmlns:b="space" xmlns:space="space" space:x="value">`,
1356+
}, {
1357+
desc: "nested element redefines name space",
1358+
toks: []Token{
1359+
StartElement{Name{"", "foo"}, []Attr{
1360+
{Name{"xmlns", "x"}, "space"},
1361+
}},
1362+
StartElement{Name{"space", "foo"}, []Attr{
1363+
{Name{"xmlns", "y"}, "space"},
1364+
{Name{"space", "a"}, "value"},
1365+
}},
1366+
},
1367+
want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" _xmlns:y="space" xmlns:space="space" space:a="value">`,
1368+
}, {
1369+
desc: "nested element creates alias for default name space",
1370+
toks: []Token{
1371+
StartElement{Name{"space", "foo"}, []Attr{
1372+
{Name{"", "xmlns"}, "space"},
1373+
}},
1374+
StartElement{Name{"space", "foo"}, []Attr{
1375+
{Name{"xmlns", "y"}, "space"},
1376+
{Name{"space", "a"}, "value"},
1377+
}},
1378+
},
1379+
want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" xmlns:_xmlns="xmlns" _xmlns:y="space" xmlns:space="space" space:a="value">`,
1380+
}, {
1381+
desc: "nested element defines default name space with existing prefix",
1382+
toks: []Token{
1383+
StartElement{Name{"", "foo"}, []Attr{
1384+
{Name{"xmlns", "x"}, "space"},
1385+
}},
1386+
StartElement{Name{"space", "foo"}, []Attr{
1387+
{Name{"", "xmlns"}, "space"},
1388+
{Name{"space", "a"}, "value"},
1389+
}},
1390+
},
1391+
want: `<foo xmlns:_xmlns="xmlns" _xmlns:x="space"><foo xmlns="space" xmlns="space" xmlns:space="space" space:a="value">`,
1392+
}, {
1393+
desc: "nested element uses empty attribute name space when default ns defined",
1394+
toks: []Token{
1395+
StartElement{Name{"space", "foo"}, []Attr{
1396+
{Name{"", "xmlns"}, "space"},
1397+
}},
1398+
StartElement{Name{"space", "foo"}, []Attr{
1399+
{Name{"", "attr"}, "value"},
1400+
}},
1401+
},
1402+
want: `<foo xmlns="space" xmlns="space"><foo xmlns="space" attr="value">`,
1403+
}, {
1404+
desc: "redefine xmlns",
1405+
toks: []Token{
1406+
StartElement{Name{"", "foo"}, []Attr{
1407+
{Name{"foo", "xmlns"}, "space"},
1408+
}},
1409+
},
1410+
want: `<foo xmlns:foo="foo" foo:xmlns="space">`,
1411+
}, {
1412+
desc: "xmlns with explicit name space #1",
1413+
toks: []Token{
1414+
StartElement{Name{"space", "foo"}, []Attr{
1415+
{Name{"xml", "xmlns"}, "space"},
1416+
}},
1417+
},
1418+
want: `<foo xmlns="space" xmlns:_xml="xml" _xml:xmlns="space">`,
1419+
}, {
1420+
desc: "xmlns with explicit name space #2",
1421+
toks: []Token{
1422+
StartElement{Name{"space", "foo"}, []Attr{
1423+
{Name{xmlURL, "xmlns"}, "space"},
1424+
}},
1425+
},
1426+
want: `<foo xmlns="space" xml:xmlns="space">`,
1427+
}, {
1428+
desc: "empty name space declaration is ignored",
1429+
toks: []Token{
1430+
StartElement{Name{"", "foo"}, []Attr{
1431+
{Name{"xmlns", "foo"}, ""},
1432+
}},
1433+
},
1434+
want: `<foo xmlns:_xmlns="xmlns" _xmlns:foo="">`,
1435+
}, {
1436+
desc: "attribute with no name is ignored",
1437+
toks: []Token{
1438+
StartElement{Name{"", "foo"}, []Attr{
1439+
{Name{"", ""}, "value"},
1440+
}},
1441+
},
1442+
want: `<foo>`,
1443+
}, {
1444+
desc: "namespace URL with non-valid name",
1445+
toks: []Token{
1446+
StartElement{Name{"/34", "foo"}, []Attr{
1447+
{Name{"/34", "x"}, "value"},
1448+
}},
1449+
},
1450+
want: `<foo xmlns="/34" xmlns:_="/34" _:x="value">`,
1451+
}, {
1452+
desc: "nested element resets default namespace to empty",
1453+
toks: []Token{
1454+
StartElement{Name{"space", "foo"}, []Attr{
1455+
{Name{"", "xmlns"}, "space"},
1456+
}},
1457+
StartElement{Name{"", "foo"}, []Attr{
1458+
{Name{"", "xmlns"}, ""},
1459+
{Name{"", "x"}, "value"},
1460+
{Name{"space", "x"}, "value"},
1461+
}},
1462+
},
1463+
want: `<foo xmlns="space" xmlns="space"><foo xmlns="" x="value" xmlns:space="space" space:x="value">`,
1464+
}, {
1465+
desc: "nested element requires empty default name space",
1466+
toks: []Token{
1467+
StartElement{Name{"space", "foo"}, []Attr{
1468+
{Name{"", "xmlns"}, "space"},
1469+
}},
1470+
StartElement{Name{"", "foo"}, nil},
1471+
},
1472+
want: `<foo xmlns="space" xmlns="space"><foo>`,
1473+
}, {
1474+
desc: "attribute uses name space from xmlns",
1475+
toks: []Token{
1476+
StartElement{Name{"some/space", "foo"}, []Attr{
1477+
{Name{"", "attr"}, "value"},
1478+
{Name{"some/space", "other"}, "other value"},
1479+
}},
1480+
},
1481+
want: `<foo xmlns="some/space" attr="value" xmlns:space="some/space" space:other="other value">`,
1482+
}, {
1483+
desc: "default name space should not be used by attributes",
1484+
toks: []Token{
1485+
StartElement{Name{"space", "foo"}, []Attr{
1486+
{Name{"", "xmlns"}, "space"},
1487+
{Name{"xmlns", "bar"}, "space"},
1488+
{Name{"space", "baz"}, "foo"},
1489+
}},
1490+
StartElement{Name{"space", "baz"}, nil},
1491+
EndElement{Name{"space", "baz"}},
1492+
EndElement{Name{"space", "foo"}},
1493+
},
1494+
want: `<foo xmlns="space" xmlns="space" xmlns:_xmlns="xmlns" _xmlns:bar="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
1495+
}, {
1496+
desc: "default name space not used by attributes, not explicitly defined",
1497+
toks: []Token{
1498+
StartElement{Name{"space", "foo"}, []Attr{
1499+
{Name{"", "xmlns"}, "space"},
1500+
{Name{"space", "baz"}, "foo"},
1501+
}},
1502+
StartElement{Name{"space", "baz"}, nil},
1503+
EndElement{Name{"space", "baz"}},
1504+
EndElement{Name{"space", "foo"}},
1505+
},
1506+
want: `<foo xmlns="space" xmlns="space" xmlns:space="space" space:baz="foo"><baz xmlns="space"></baz></foo>`,
1507+
}, {
1508+
desc: "impossible xmlns declaration",
1509+
toks: []Token{
1510+
StartElement{Name{"", "foo"}, []Attr{
1511+
{Name{"", "xmlns"}, "space"},
1512+
}},
1513+
StartElement{Name{"space", "bar"}, []Attr{
1514+
{Name{"space", "attr"}, "value"},
1515+
}},
1516+
},
1517+
want: `<foo xmlns="space"><bar xmlns="space" xmlns:space="space" space:attr="value">`,
1518+
}}
12131519

12141520
func TestEncodeToken(t *testing.T) {
1215-
for _, tt := range encodeTokenTests {
1521+
loop:
1522+
for i, tt := range encodeTokenTests {
12161523
var buf bytes.Buffer
12171524
enc := NewEncoder(&buf)
1218-
err := enc.EncodeToken(tt.tok)
1525+
var err error
1526+
for j, tok := range tt.toks {
1527+
err = enc.EncodeToken(tok)
1528+
if err != nil && j < len(tt.toks)-1 {
1529+
t.Errorf("#%d %s token #%d: %v", i, tt.desc, j, err)
1530+
continue loop
1531+
}
1532+
}
1533+
errorf := func(f string, a ...interface{}) {
1534+
t.Errorf("#%d %s token #%d:%s", i, tt.desc, len(tt.toks)-1, fmt.Sprintf(f, a...))
1535+
}
12191536
switch {
1220-
case !tt.ok && err == nil:
1221-
t.Errorf("enc.EncodeToken(%#v): expected error; got none", tt.tok)
1222-
case tt.ok && err != nil:
1223-
t.Fatalf("enc.EncodeToken: %v", err)
1224-
case !tt.ok && err != nil:
1225-
// expected error, got one
1537+
case tt.err != "" && err == nil:
1538+
errorf(" expected error; got none")
1539+
continue
1540+
case tt.err == "" && err != nil:
1541+
errorf(" got error: %v", err)
1542+
continue
1543+
case tt.err != "" && err != nil && tt.err != err.Error():
1544+
errorf(" error mismatch; got %v, want %v", err, tt.err)
1545+
continue
12261546
}
12271547
if err := enc.Flush(); err != nil {
1228-
t.Fatalf("enc.EncodeToken: %v", err)
1548+
errorf(" %v", err)
1549+
continue
12291550
}
12301551
if got := buf.String(); got != tt.want {
1231-
t.Errorf("enc.EncodeToken = %s; want: %s", got, tt.want)
1552+
errorf("\ngot %v\nwant %v", got, tt.want)
1553+
continue
12321554
}
12331555
}
12341556
}

0 commit comments

Comments
 (0)