package text_test import ( "testing" "github.com/inkyblackness/hacked/ss1/content/text" "github.com/inkyblackness/hacked/ss1/resource" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) type ElectronicMessageSuite struct { suite.Suite cp text.Codepage } func TestElectronicMessageSuite(t *testing.T) { suite.Run(t, new(ElectronicMessageSuite)) } func (suite *ElectronicMessageSuite) SetupTest() { suite.cp = text.DefaultCodepage() } func (suite *ElectronicMessageSuite) TestEncodeBasicMessage() { message := text.EmptyElectronicMessage() message.Title = "1" message.Sender = "2" message.Subject = "3" message.VerboseText = "4" message.TerseText = "5" encoded := message.Encode(suite.cp) suite.verifyBlock(0, encoded, []byte{0x00}) suite.verifyBlock(1, encoded, []byte{0x31, 0x00}) suite.verifyBlock(2, encoded, []byte{0x32, 0x00}) suite.verifyBlock(3, encoded, []byte{0x33, 0x00}) suite.verifyBlock(4, encoded, []byte{0x34, 0x00}) suite.verifyBlock(5, encoded, []byte{0x00}) suite.verifyBlock(6, encoded, []byte{0x35, 0x00}) suite.verifyBlock(7, encoded, []byte{0x00}) } func (suite *ElectronicMessageSuite) TestEncodeMeta_A() { message := text.EmptyElectronicMessage() message.NextMessage = 0x20 message.ColorIndex = 0x13 message.LeftDisplay = 30 message.RightDisplay = 40 encoded := message.Encode(suite.cp) require.NotNil(suite.T(), encoded) require.Equal(suite.T(), true, len(encoded) > 0) suite.verifyBlock(0, encoded, suite.cp.Encode("i20 c13 30,40")) } func (suite *ElectronicMessageSuite) TestEncodeMeta_B() { message := text.EmptyElectronicMessage() message.IsInterrupt = true message.LeftDisplay = 31 encoded := message.Encode(suite.cp) require.NotNil(suite.T(), encoded) require.Equal(suite.T(), true, len(encoded) > 0) suite.verifyBlock(0, encoded, suite.cp.Encode("t 31")) } func (suite *ElectronicMessageSuite) TestEncodeMeta_C() { message := text.EmptyElectronicMessage() message.IsInterrupt = true encoded := message.Encode(suite.cp) require.NotNil(suite.T(), encoded) require.Equal(suite.T(), true, len(encoded) > 0) suite.verifyBlock(0, encoded, suite.cp.Encode("t")) } func (suite *ElectronicMessageSuite) TestEncodeCreatesNewBlocksPerNewLine() { message := text.EmptyElectronicMessage() message.VerboseText = "line1\n\n\nline2" message.TerseText = "terse1\n\n\nterse2" encoded := message.Encode(suite.cp) require.NotNil(suite.T(), encoded) require.Equal(suite.T(), true, len(encoded) > 0) suite.verifyBlock(4, encoded, suite.cp.Encode("line1\n\n\nline2")) suite.verifyBlock(6, encoded, suite.cp.Encode("terse1\n\n\nterse2")) } func (suite *ElectronicMessageSuite) TestEncodeBreaksUpLinesAfterLimitCharacters() { message := text.EmptyElectronicMessage() message.VerboseText = "aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd eeeeeeeee fffffffff ggggggggg hhhhhhhhh iiiiiiiii jjjjjjjjj kkkkk" encoded := message.Encode(suite.cp) require.NotNil(suite.T(), encoded) require.Equal(suite.T(), true, len(encoded) > 0) suite.verifyBlock(4, encoded, suite.cp.Encode("aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd eeeeeeeee fffffffff ggggggggg hhhhhhhhh ")) suite.verifyBlock(5, encoded, suite.cp.Encode("iiiiiiiii jjjjjjjjj kkkkk")) } func (suite *ElectronicMessageSuite) TestDecodeMeta() { message, err := text.DecodeElectronicMessage(suite.cp, suite.holderWithMeta("i20 c13 30,40")) require.Nil(suite.T(), err) require.NotNil(suite.T(), message) assert.Equal(suite.T(), 0x20, message.NextMessage) assert.Equal(suite.T(), 0x13, message.ColorIndex) assert.Equal(suite.T(), 30, message.LeftDisplay) assert.Equal(suite.T(), 40, message.RightDisplay) } func (suite *ElectronicMessageSuite) TestDecodeMeta_Failure() { _, err := text.DecodeElectronicMessage(suite.cp, suite.holderWithMeta("i20 c 13 30,40")) assert.NotNil(suite.T(), err) } func (suite *ElectronicMessageSuite) TestDecodeMetaColorIs8BitUnsigned() { message, err := text.DecodeElectronicMessage(suite.cp, suite.holderWithMeta("cD1")) require.Nil(suite.T(), err) require.NotNil(suite.T(), message) assert.Equal(suite.T(), 0xD1, message.ColorIndex) } func (suite *ElectronicMessageSuite) TestDecodeMessage() { message, err := text.DecodeElectronicMessage(suite.cp, suite.holderWithMeta("10")) require.Nil(suite.T(), err) require.NotNil(suite.T(), message) assert.Equal(suite.T(), "title", message.Title) assert.Equal(suite.T(), "sender", message.Sender) assert.Equal(suite.T(), "subject", message.Subject) assert.Equal(suite.T(), "verbose", message.VerboseText) assert.Equal(suite.T(), "terse", message.TerseText) } func (suite *ElectronicMessageSuite) TestDecodeMessageIsPossibleForVanillaStubMails() { message, err := text.DecodeElectronicMessage(suite.cp, suite.vanillaStubMail()) require.Nil(suite.T(), err) require.NotNil(suite.T(), message) assert.Equal(suite.T(), "", message.Title) assert.Equal(suite.T(), "", message.Sender) assert.Equal(suite.T(), "", message.Subject) assert.Equal(suite.T(), "stub emailstub email", message.VerboseText) assert.Equal(suite.T(), "", message.TerseText) } func (suite *ElectronicMessageSuite) TestDecodeMessageIsPossibleForMissingTerminatingLine() { message, err := text.DecodeElectronicMessage(suite.cp, suite.holderWithMissingTerminatingLine()) require.Nil(suite.T(), err) require.NotNil(suite.T(), message) assert.Equal(suite.T(), "title", message.Title) assert.Equal(suite.T(), "sender", message.Sender) assert.Equal(suite.T(), "subject", message.Subject) assert.Equal(suite.T(), "verbose text", message.VerboseText) assert.Equal(suite.T(), "terse text", message.TerseText) } func (suite *ElectronicMessageSuite) TestRecodeMessage() { inMessage := text.EmptyElectronicMessage() inMessage.IsInterrupt = true inMessage.NextMessage = 0x10 inMessage.ColorIndex = 0x20 inMessage.LeftDisplay = 40 inMessage.RightDisplay = 50 inMessage.VerboseText = "abcd\nefgh\nsome" inMessage.TerseText = "\n" data := inMessage.Encode(suite.cp) outMessage, err := text.DecodeElectronicMessage(suite.cp, resource.BlocksFrom(data)) require.Nil(suite.T(), err) require.NotNil(suite.T(), outMessage) assert.Equal(suite.T(), inMessage, outMessage) } func (suite *ElectronicMessageSuite) TestRecodeMessageWithMultipleNewLines() { inMessage := text.EmptyElectronicMessage() inMessage.IsInterrupt = true inMessage.NextMessage = 0x10 inMessage.ColorIndex = 0x20 inMessage.LeftDisplay = 40 inMessage.RightDisplay = 50 inMessage.VerboseText = "first\n\n\nsecond" inMessage.TerseText = "terse\n" data := inMessage.Encode(suite.cp) outMessage, err := text.DecodeElectronicMessage(suite.cp, resource.BlocksFrom(data)) require.Nil(suite.T(), err) require.NotNil(suite.T(), outMessage) assert.Equal(suite.T(), inMessage, outMessage) } func (suite *ElectronicMessageSuite) verifyBlock(index int, blocks [][]byte, expected []byte) { require.True(suite.T(), len(blocks) > index, "too few blocks") assert.Equal(suite.T(), expected, blocks[index]) } func (suite *ElectronicMessageSuite) holderWithMeta(meta string) resource.BlockProvider { data := [][]byte{ suite.cp.Encode(meta), suite.cp.Encode("title"), suite.cp.Encode("sender"), suite.cp.Encode("subject"), suite.cp.Encode("verbose"), suite.cp.Encode(""), suite.cp.Encode("terse"), suite.cp.Encode("")} return resource.BlocksFrom(data) } func (suite *ElectronicMessageSuite) vanillaStubMail() resource.BlockProvider { // The string resources contain a few mails which aren't used. // They are missing the terminating line for the verbose text. data := [][]byte{ suite.cp.Encode(""), suite.cp.Encode(""), suite.cp.Encode(""), suite.cp.Encode(""), suite.cp.Encode("stub email"), suite.cp.Encode("stub email"), suite.cp.Encode("")} return resource.BlocksFrom(data) } func (suite *ElectronicMessageSuite) holderWithMissingTerminatingLine() resource.BlockProvider { // This case is encountered once in gerstrng.res data := [][]byte{ suite.cp.Encode(""), suite.cp.Encode("title"), suite.cp.Encode("sender"), suite.cp.Encode("subject"), suite.cp.Encode("verbose "), suite.cp.Encode("text"), suite.cp.Encode(""), suite.cp.Encode("terse "), suite.cp.Encode("text")} return resource.BlocksFrom(data) }