test(function() {
    var params = new URLSearchParams();
    params.append('first', 1);
    assert_true(params.has('first'), 'Search params object has name "first"');
    assert_equals(params.get('first'), '1', 'Search params object has name "first" with value "1"');
    params.delete('first');
    assert_false(params.has('first'), 'Search params object has no "first" name');
    params.append('first', 1);
    params.append('first', 10);
    params.delete('first');
    assert_false(params.has('first'), 'Search params object has no "first" name');
}, 'Deleting appended multiple');
test(function() {
    var params = new URLSearchParams();
    params.append('a', 'b\0c');
    assert_equals(params + '', 'a=b%00c');
    params.delete('a');
    params.append('a\0b', 'c');
    assert_equals(params + '', 'a%00b=c');
}, 'Serialize \\0');
test(function() {
    var params = new URLSearchParams('a=b&c=d');
    params.delete('a');
    assert_equals(params + '', 'c=d');
    params = new URLSearchParams('a=a&b=b&a=a&c=c');
    params.delete('a');
    assert_equals(params + '', 'b=b&c=c');
    params = new URLSearchParams('a=a&=&b=b&c=c');
    params.delete('');
    assert_equals(params + '', 'a=a&b=b&c=c');
    params = new URLSearchParams('a=a&null=null&b=b');
    params.delete(null);
    assert_equals(params + '', 'a=a&b=b');
    params = new URLSearchParams('a=a&undefined=undefined&b=b');
    params.delete(undefined);
    assert_equals(params + '', 'a=a&b=b');
}, 'Delete basics');
test(function() {
    var params = new URLSearchParams();
    params.append('a', 'b%c');
    assert_equals(params + '', 'a=b%25c');
    params.delete('a');
    params.append('a%b', 'c');
    assert_equals(params + '', 'a%25b=c');
}, 'Serialize %');
test(function() {
    var params = new URLSearchParams();
    params.append('a', '*-._');
    assert_equals(params + '', 'a=*-._');
    params.delete('a');
    params.append('*-._', 'c');
    assert_equals(params + '', '*-._=c');
}, 'Serialize *-._');
test(function() {
    var params = new URLSearchParams();
    params.append('a', 'b\uD83D\uDCA9c');
    assert_equals(params + '', 'a=b%F0%9F%92%A9c');
    params.delete('a');
    params.append('a\uD83D\uDCA9b', 'c');
    assert_equals(params + '', 'a%F0%9F%92%A9b=c');
}, 'Serialize \uD83D\uDCA9');  // Unicode Character 'PILE OF POO' (U+1F4A9)
test(function() {
    var params = new URLSearchParams('a=b&c=d&&');
    params.append('first', 1);
    params.append('first', 2);
    assert_true(params.has('a'), 'Search params object has name "a"');
    assert_true(params.has('c'), 'Search params object has name "c"');
    assert_true(params.has('first'), 'Search params object has name "first"');
    assert_false(params.has('d'), 'Search params object has no name "d"');
    params.delete('first');
    assert_false(params.has('first'), 'Search params object has no name "first"');
}, 'has() following delete()');
assert.strictEqual(params + '', '=b');
params.append('', 'b');
assert.strictEqual(params + '', '=b&=b');

// Serialize empty name and value
params = new URLSearchParams();
params.append('', '');
assert.strictEqual(params + '', '=');
params.append('', '');
assert.strictEqual(params + '', '=&=');

// Serialize +
params = new URLSearchParams();
params.append('a', 'b+c');
assert.strictEqual(params + '', 'a=b%2Bc');
params.delete('a');
params.append('a+b', 'c');
assert.strictEqual(params + '', 'a%2Bb=c');

// Serialize =
params = new URLSearchParams();
params.append('=', 'a');
assert.strictEqual(params + '', '%3D=a');
params.append('b', '=');
assert.strictEqual(params + '', '%3D=a&b=%3D');

// Serialize &
params = new URLSearchParams();
params.append('&', 'a');
assert.strictEqual(params + '', '%26=a');
params.append('b', '&');