From 82a7fb131a9ff7f2525b41b06473fcc1dbebf142 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 14 Apr 2024 01:57:23 +0500 Subject: [PATCH] Go: support `asserts[i].exception` key and generate expr_to_i_trailing test --- spec/go/expr_to_i_trailing_test.go | 51 ++++++++++++++ .../testtranslator/specgenerators/GoSG.scala | 69 ++++++++++++++----- 2 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 spec/go/expr_to_i_trailing_test.go diff --git a/spec/go/expr_to_i_trailing_test.go b/spec/go/expr_to_i_trailing_test.go new file mode 100644 index 000000000..c5beefa2d --- /dev/null +++ b/spec/go/expr_to_i_trailing_test.go @@ -0,0 +1,51 @@ +// Autogenerated from KST: please remove this line if doing any edits by hand! + +package spec + +import ( + "runtime/debug" + "os" + "testing" + "github.com/kaitai-io/kaitai_struct_go_runtime/kaitai" + . "test_formats" + "github.com/stretchr/testify/assert" +) + +func TestExprToITrailing(t *testing.T) { + defer func() { + if r := recover(); r != nil { + debug.PrintStack() + t.Fatal("unexpected panic:", r) + } + }() + f, err := os.Open("../../src/term_strz.bin") + if err != nil { + t.Fatal(err) + } + s := kaitai.NewStream(f) + var r ExprToITrailing + err = r.Read(s, &r, &r) + if err != nil { + t.Fatal(err) + } + + { + tmp1, err := r.ToIR10() + assert.Error(t, err) + var wantErr strconv.NumError + assert.ErrorAs(t, err, &wantErr) + assert.EqualValues(t, 0, tmp1) + } + tmp2, err := r.ToIR16() + if err != nil { + t.Fatal(err) + } + assert.EqualValues(t, 152517308, tmp2) + { + tmp3, err := r.ToIGarbage() + assert.Error(t, err) + var wantErr strconv.NumError + assert.ErrorAs(t, err, &wantErr) + assert.EqualValues(t, 0, tmp3) + } +} diff --git a/translator/src/main/scala/io/kaitai/struct/testtranslator/specgenerators/GoSG.scala b/translator/src/main/scala/io/kaitai/struct/testtranslator/specgenerators/GoSG.scala index 43f2f84b0..865666998 100644 --- a/translator/src/main/scala/io/kaitai/struct/testtranslator/specgenerators/GoSG.scala +++ b/translator/src/main/scala/io/kaitai/struct/testtranslator/specgenerators/GoSG.scala @@ -1,6 +1,7 @@ package io.kaitai.struct.testtranslator.specgenerators import _root_.io.kaitai.struct.datatype.{DataType, EndOfStreamError, KSError} +import _root_.io.kaitai.struct.datatype.DataType._ import _root_.io.kaitai.struct.exprlang.Ast import _root_.io.kaitai.struct.languages.GoCompiler import _root_.io.kaitai.struct.testtranslator.{Main, TestAssert, TestEquals, TestSpec} @@ -13,15 +14,19 @@ class GoSG(spec: TestSpec, provider: ClassTypeProvider) extends BaseGenerator(sp * to access "this.INIT_OBJ_NAME" and replaces it with "r." */ class GoTestOutputWriter(indentStr: String) extends GoOutputWriter(indentStr) { + var doErrCheck = true + override def puts(s: String): Unit = { super.puts(s.replace(REPLACER, "r.")) } override def putsErrCheck(result: Option[String]): Unit = { - puts("if err != nil {") - inc - puts("t.Fatal(err)") - dec - puts("}") + if (doErrCheck) { + puts("if err != nil {") + inc + puts("t.Fatal(err)") + dec + puts("}") + } } } @@ -64,17 +69,7 @@ class GoSG(spec: TestSpec, provider: ClassTypeProvider) extends BaseGenerator(sp override def runParseExpectError(exception: KSError): Unit = { out.puts("err = r.Read(s, &r, &r)") - importList.add("\"github.com/stretchr/testify/assert\"") - out.puts("assert.Error(t, err)") - exception match { - case EndOfStreamError => - importList.add("\"io\"") - out.puts("assert.ErrorIs(t, err, io.ErrUnexpectedEOF)") - case _ => - val errorName = GoCompiler.ksErrorName(exception) - out.puts(s"var wantErr ${errorName}") - out.puts("assert.ErrorAs(t, err, &wantErr)") - } + checkErr(exception) } override def footer() = { @@ -105,6 +100,33 @@ class GoSG(spec: TestSpec, provider: ClassTypeProvider) extends BaseGenerator(sp def trueArrayEquality(check: TestEquals, elType: DataType, elts: Seq[Ast.expr]): Unit = simpleEquality(check) + override def testException(actual: Ast.expr, exception: KSError): Unit = { + // We need a scope otherwise we got redeclaration error from Go in case of + // several assertions, because we use the same name for expected exception + out.puts("{") + out.inc + + // We do not want error check because we expect an error + out.doErrCheck = false + val actStr = translateAct(actual) + out.doErrCheck = true + + checkErr(exception) + + // translateAct generates unused variable which not allowed in Go, + // so we use it by checking its value + translator.detectType(actual) match { + case _: FloatType => out.puts(s"assert.InDelta(t, 0, $actStr, $FLOAT_DELTA)") + case _: NumericType => out.puts(s"assert.EqualValues(t, 0, $actStr)") + case _: BooleanType => out.puts(s"assert.EqualValues(t, false, $actStr)") + case _: StrType => out.puts(s"assert.EqualValues(t, \"\", $actStr)") + case _ => out.puts(s"assert.Nil(t, $actStr)") + } + + out.dec + out.puts("}") + } + override def indentStr: String = "\t" override def results: String = { @@ -127,4 +149,19 @@ class GoSG(spec: TestSpec, provider: ClassTypeProvider) extends BaseGenerator(sp def translateAct(x: Ast.expr) = translator.translate(x).replace(REPLACER, "r.") + + /** Generates code to check returned Go error to match of specified `exception`. */ + def checkErr(exception: KSError): Unit = { + importList.add("\"github.com/stretchr/testify/assert\"") + out.puts("assert.Error(t, err)") + exception match { + case EndOfStreamError => + importList.add("\"io\"") + out.puts("assert.ErrorIs(t, err, io.ErrUnexpectedEOF)") + case _ => + val errorName = GoCompiler.ksErrorName(exception) + out.puts(s"var wantErr ${errorName}") + out.puts("assert.ErrorAs(t, err, &wantErr)") + } + } }