Skip to content

Instantly share code, notes, and snippets.

@awostenberg
Created May 10, 2022 22:44
Show Gist options
  • Save awostenberg/f68d5805544e12a999cc3f0a699d02e0 to your computer and use it in GitHub Desktop.
Save awostenberg/f68d5805544e12a999cc3f0a699d02e0 to your computer and use it in GitHub Desktop.
sql where expressions for Eric sql where for Eric sql where emitter for eric
module Tests
(*
Problem:
Given an expression tree, model the data and write a method that takes
the tree as an input and
generate a string that represents this expression.
Expected output:
key1 = 'value1' AND key2 = 'value2' AND (key3 < '3' OR key4 = '99')
initial test list, for example
emiting stuff form expression tree
given expect
() ""
(OperatorEq 'key4' '99') "key4 = 99" DONE
(OperatorLt 'key3', '3') "key3 < 3" DONE
OperatorAnd DONE
OperatorOR DONE
raw json to expression tree
given expect
{ (OperatorEQ 'key4' '99')
key: 'key4',
operator: '=',
value: 'value9'
},
input | toExpressionTree | toString
red-green-refactor TDD mantra:
red. write a little test that doesn't work, and perhaps doesn't even compile at first
green. make the test work quickly, committing whatever sins necessary in the process
refactor. eliminate all of the duplication created in merely getting the test to work
definition of done:
all tests pass?
reveals intention?
no duplication?
fewest elements?
*)
open Xunit
open FsUnit.Xunit
// F# syntax in 60 seconds: https://fsharpforfunandprofit.com/posts/fsharp-in-60-seconds/
type Expr =
| OperatorEq of string * string
| OperatorLt of string * string
| OperatorAnd of Expr * Expr
| OperatorOr of Expr * Expr
let rec expressionToString operator =
match operator with
| OperatorEq (lh,rh) -> $"%s{lh} = %s{rh}"
| OperatorLt (lh,rh) -> $"%s{lh} < %s{rh}"
| OperatorAnd (lh,rh) -> $"%s{expressionToString lh} and %s{expressionToString rh}"
| OperatorOr (lh,rh) -> $"%s{expressionToString lh} or %s{expressionToString rh}"
[<Fact>]
let ``equality`` () =
let result = expressionToString (OperatorEq ("key4","99"))
result |> should equal "key4 = 99"
[<Fact>]
let ``less than`` () =
let result = expressionToString (OperatorLt ("key3","3"))
result |> should equal "key3 < 3"
[<Fact>]
let ``and`` () =
let expr = (OperatorAnd ((OperatorEq ("key4","99")),
(OperatorLt ("key3","3"))) )
let result = expressionToString expr
result |> should equal "key4 = 99 and key3 < 3"
[<Fact>]
let ``or`` () =
let expr = (OperatorOr ((OperatorEq ("key4","99")),
(OperatorLt ("key3","3"))) )
let result = expressionToString expr
result |> should equal "key4 = 99 or key3 < 3"
[<Fact>]
let ``and or`` () =
let andExpr = (OperatorAnd
((OperatorEq ("key5","55")),
(OperatorOr
((OperatorEq ("key4","99")),
(OperatorLt ("key3","3"))) ) ))
let result = expressionToString andExpr
result |> should equal "key5 = 55 and key4 = 99 or key3 < 3"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment