Сравнение дискриминационных союзов

Я новичок в F# и играю с FParsec. Я бы использовал FParsec для генерации AST. Я хотел бы использовать FsUnit для написания некоторых тестов вокруг различных частей синтаксического анализатора, чтобы гарантировать правильную работу.

У меня возникли небольшие проблемы с синтаксисом (извините, точный код работает, я могу опубликовать конкретный пример позже), так как именно можно сравнить два различающихся объединения (одно ожидаемое, а другое фактический результат)? Может ли кто-нибудь представить небольшой пример кода с использованием FsUnit (или NUnit), пожалуйста?

Пример дискриминируемого союза (очень простой)

type AST = 
    | Variable of string
    | Class of string
    | Number of int

2 ответа

Решение

Так как, как отметил Брайан, у профсоюзов F# есть структурное равенство, это легко с помощью любой системы модульного тестирования, которая вам нравится.

FsUnit - это библиотека F#, созданная поверх NUnit. Моя личная любимая библиотека модульного тестирования для F# - Unquote,;), которая не зависит от фреймворка, очень хорошо работает с NUnit, xUnit.net, MbUnit, ... или даже внутри FSI. Вас может заинтересовать это сравнение с FsUnit.

Итак, как бы вы сделали это с NUnit + Unquote? Вот полный рабочий пример:

module UnitTests

open NUnit.Framework
open Swensen.Unquote

type AST = 
    | Variable of string
    | Class of string
    | Number of int

let mockFParsec_parseVariable input = Variable(input)

[<Test>]
let ``test variable parse, passing example`` () =
    test <@ mockFParsec_parseVariable "x" = Variable("x") @>

[<Test>]
let ``test variable parse, failing example`` () =
    test <@ mockFParsec_parseVariable "y" = Variable("x") @>

Затем, запустив тесты с использованием TestDriven.NET, вы получите следующий вывод:

------ Test started: Assembly: xxx.exe ------

Test 'UnitTests.test variable parse, failing example' failed: 

UnitTests.mockFParsec_parseVariable "y" = Variable("x")
Variable "y" = Variable("x")
false
    C:\xxx\UnitTests.fs(19,0): at UnitTests.test variable parse, failing example()

1 passed, 1 failed, 0 skipped, took 0.80 seconds (NUnit 2.5.10).

Пример - если вы хотите проверить тип, но не содержимое

let matched x= 
    match x with
    |Variable(_) -> true
    | _ -> false

Обратите внимание, что вам нужна отдельная функция для каждого элемента различаемого объединения.

Если вы хотите сравнить равенство, вы можете просто сделать это стандартным способом, как

Assert.AreEqual(Variable("hello"),result)

или же

if result = Variable("hello") then stuff()
Другие вопросы по тегам