public void MutableString_GetHashCode() {
int h1, h2, h3;
MutableString s;
// invalid byte sequence:
s = MutableString.CreateBinary(new byte[] { 0xce }, RubyEncoding.UTF8);
h1 = s.GetHashCode();
Assert(s.GetCharacterCount() == 1);
h2 = s.GetHashCode();
Assert(h1 == h2);
// binary -> string:
s = MutableString.CreateBinary(new byte[] { 0xce, 0xa3 }, RubyEncoding.UTF8);
h1 = s.GetHashCode();
Assert(s.GetCharCount() == 1);
h2 = s.GetHashCode();
Assert(s.GetCharacterCount() == 1);
h3 = s.GetHashCode();
Assert(h1 == h2);
Assert(h1 == h3);
// string -> binary:
s = MutableString.Create("Σ", RubyEncoding.UTF8);
h1 = s.GetHashCode();
Assert(s.GetByteCount() == 2);
h2 = s.GetHashCode();
Assert(h1 == h2);
// string vs. char[] vs CLR string:
s = MutableString.CreateMutable("Σ", RubyEncoding.UTF8);
h2 = s.GetHashCode();
Assert(h1 == h2);
Assert(h2 == "Σ".GetHashCode());
// hash(binary) == hash(string):
s = MutableString.CreateBinary(new byte[] { 0xce, 0xa3 }, RubyEncoding.UTF8);
h1 = s.GetHashCode();
s = MutableString.Create("Σ", RubyEncoding.UTF8);
h2 = s.GetHashCode();
Assert(h1 == h2);
// same content, different capacities:
var a = MutableString.CreateMutable(10, RubyEncoding.UTF8).Append("hello");
var b = MutableString.CreateMutable(20, RubyEncoding.UTF8).Append("hello");
var c = MutableString.Create("hello", RubyEncoding.UTF8);
Assert(a.GetHashCode() == b.GetHashCode());
Assert(a.GetHashCode() == c.GetHashCode());
// same content, different encodings:
// ASCII characters only:
a = MutableString.Create("hello", RubyEncoding.UTF8);
b = MutableString.Create("hello", RubyEncoding.SJIS);
c = MutableString.CreateAscii("hello");
Assert(a.GetHashCode() == b.GetHashCode());
Assert(a.GetHashCode() == c.GetHashCode());
Assert(b.GetHashCode() == c.GetHashCode());
// TODO: do we need this property?
// non-ASCII characters:
// a = MutableString.Create("α", RubyEncoding.UTF8);
// b = MutableString.Create("α", RubyEncoding.SJIS);
// c = MutableString.CreateBinary(Encoding.UTF8.GetBytes("α"), RubyEncoding.Binary);
// Assert(a.GetHashCode() != b.GetHashCode());
// Assert(a.GetHashCode() != c.GetHashCode());
// Assert(b.GetHashCode() != c.GetHashCode());
}