как получить golang для проверки совпадений многострочного вывода - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть следующий код, который генерирует некоторые строковые выходные данные:

package formatter

import (
    "bytes"
    "log"
    "text/template"

    "github.com/foo/bar/internal/mapper"
)

// map of template functions that enable us to identify the final item within a
// collection being iterated over.
var fns = template.FuncMap{
    "plus1": func(x int) int {
        return x + 1
    },
}

// Dot renders our results in dot format for use with graphviz
func Dot(results []mapper.Page) string {
    dotTmpl := `digraph sitemap { {{range .}}
  "{{.URL}}"
    -> { {{$n := len .Anchors}}{{range  $i, $v := .Anchors}}
      "{{.}}"{{if eq (plus1 $i) $n}}{{else}},{{end}}{{end}}
    } {{end}}
}`

    tmpl, err := template.New("digraph").Funcs(fns).Parse(dotTmpl)
    if err != nil {
        log.Fatal(err)
    }

    var output bytes.Buffer
    if err := tmpl.Execute(&output, results); err != nil {
        log.Fatal(err)
    }

    return output.String()
}

Он генерирует выходные данные, например:

digraph sitemap {
  "http://www.example.com/"
    -> {
      "http://www.example.com/foo",
      "http://www.example.com/bar",
      "http://www.example.com/baz"
    }
}

Ниже приведен тест для этой функции ...

package formatter

import (
    "testing"

    "github.com/foo/bar/internal/mapper"
)

func TestDot(t *testing.T) {
    input := []mapper.Page{
        mapper.Page{
            URL: "http://www.example.com/",
            Anchors: []string{
                "http://www.example.com/foo",
                "http://www.example.com/bar",
                "http://www.example.com/baz",
            },
            Links: []string{
                "http://www.example.com/foo.css",
                "http://www.example.com/bar.css",
                "http://www.example.com/baz.css",
            },
            Scripts: []string{
                "http://www.example.com/foo.js",
                "http://www.example.com/bar.js",
                "http://www.example.com/baz.js",
            },
        },
    }

    output := `digraph sitemap {
      "http://www.example.com/"
          -> {
              "http://www.example.com/foo",
              "http://www.example.com/bar",
              "http://www.example.com/baz"
      }
    }`

    actual := Dot(input)

    if actual != output {
        t.Errorf("expected: %s\ngot: %s", output, actual)
    }
}

, которая завершается со следующей ошибкой (которая связана с интервалом выходного формата) ...

--- FAIL: TestDot (0.00s)
    format_test.go:43: expected: digraph sitemap {
                  "http://www.example.com/"
                          -> {
                                  "http://www.example.com/foo",
                                  "http://www.example.com/bar",
                                  "http://www.example.com/baz"
              }
                }
        got: digraph sitemap { 
          "http://www.example.com/"
            -> { 
              "http://www.example.com/foo",
              "http://www.example.com/bar",
              "http://www.example.com/baz"
            } 
        }

Я попытался настроить мою тестовую переменную output, чтобы интервал выровнялсяс тем, что на самом деле выводится из реального кода.Это не сработало.

Я также пытался использовать strings.Replace() как для моей выходной переменной, так и для фактического выводимого содержимого, и причудливо выводить из моей функции (даже если он был пропущен через strings.Replace, будет все еще быть многострочным (и поэтому тест не пройдёт)?

У кого-нибудь есть идеи, как сделать вывод согласованным для проверки кода?

Спасибо.

ОБНОВЛЕНИЕ

Я попробовал подход, предложенный @icza, и он по-прежнему не проходит тест, хотя вывод в тесте выглядит больше так, как ожидается:

=== RUN   TestDot
--- FAIL: TestDot (0.00s)
    format_test.go:65: expected: digraph sitemap {
          "http://www.example.com/"
            -> {
              "http://www.example.com/foo",
              "http://www.example.com/bar",
              "http://www.example.com/baz"
            }
        }
        got: digraph sitemap { 
          "http://www.example.com/"
            -> { 
              "http://www.example.com/foo",
              "http://www.example.com/bar",
              "http://www.example.com/baz"
            }
        }

Ответы [ 3 ]

0 голосов
/ 18 февраля 2019

проблема в том, что есть дополнительное место.в вашем отформатированном тексте сразу после { это, кажется, ваша проблема.Вы можете исправить это, изменив строку формата на

`digraph sitemap {{{range .}}
  "{{.URL}}"
    -> {{{$n := len .Anchors}}{{range  $i, $v := .Anchors}}
      "{{.}}"{{if eq (plus1 $i) $n}}{{else}},{{end}}{{end}}
    }{{end}}
}`
0 голосов
/ 18 февраля 2019

Если вы хотите игнорировать формат, вы можете использовать strings.Fields.

output := strings.Fields(`digraph sitemap {
  "http://www.example.com/"
      -> {
          "http://www.example.com/foo",
          "http://www.example.com/bar",
          "http://www.example.com/baz"
  }
}`)

actual := strings.Fields(Dot(input))

if !equal(output,actual) {
    // ...
}

, где равный - простая функция, которая сравнивает два слайса.

0 голосов
/ 18 февраля 2019

Самое простое решение - использовать тот же отступ в тесте при указании ожидаемого результата (то же, что вы используете в шаблоне).

У вас есть:

output := `digraph sitemap {
  "http://www.example.com/"
      -> {
          "http://www.example.com/foo",
          "http://www.example.com/bar",
          "http://www.example.com/baz"
  }
}`

Изменитьэто:

    output := `digraph sitemap {
  "http://www.example.com/"
    -> {
      "http://www.example.com/foo",
      "http://www.example.com/bar",
      "http://www.example.com/baz"
    }
}`

Обратите внимание, что, например, последняя строка не имеет отступа.Когда вы используете необработанный строковый литерал, каждый символ, включая символы отступа, является частью литерала как есть.

Шаги для создания правильного необработанного литерала необработанной строки

В конце концов, этоэто проблема, не связанная с кодированием, а скорее проблема автоматического форматирования редактора и определения необработанного строкового литерала.Самый простой способ сделать это правильно - сначала написать пустой необработанный строковый литерал, добавить к нему пустую строку и очистить автоматический отступ, вставленный редактором:

    output := `
`

Если у вас есть это, скопируйтевставьте правильный ввод перед закрывающей обратной косой чертой, например:

    output := `
digraph sitemap {
  "http://www.example.com/"
    -> {
      "http://www.example.com/foo",
      "http://www.example.com/bar",
      "http://www.example.com/baz"
    }
}`

И в качестве последнего шага удалите разрыв строки из первой строки литерала необработанной строки, и вы получите правильный литерал необработанной строки:

    output := `digraph sitemap {
  "http://www.example.com/"
    -> {
      "http://www.example.com/foo",
      "http://www.example.com/bar",
      "http://www.example.com/baz"
    }
}`

Как только вы это сделаете, запуск gofmt или автоматическое форматирование редакторов больше не будет мешать.

ОБНОВЛЕНИЕ:

Iпроверил ваш обновленный результат теста, и в результате вы получите пробел после первой строки: digraph sitemap {, а также пробел после 3-й строки: -> {, но вы не добавите их к ожидаемомувыход.Либо добавьте их в ожидаемый результат, либо удалите эти пробелы из шаблона!При сравнении строк они сравниваются побайтно, каждый символ (включая пробелы) имеет значение.

Чтобы удалить эти лишние пробелы из шаблона:

    dotTmpl := `digraph sitemap { {{- range .}}
  "{{.URL}}"
    -> { {{- $n := len .Anchors}}{{range  $i, $v := .Anchors}}
      "{{.}}"{{if eq (plus1 $i) $n}}{{else}},{{end}}{{end}}
    } {{end}}
}`

Обратите внимание на использование {{-.Это обрезать пробелы вокруг действий шаблона , это было добавлено в Go 1.6 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...