(ns clojure-sql.dsl-test (:refer-clojure :exclude [sort-by]) (:require [clojure-sql.dsl :refer :all] [midje.sweet :refer :all])) (fact "Table creates basic queries on tables" (table ..name..) => {:tables {..name.. ..name..}} ;(provided (keyword? ..name..) => true) (table {..name.. ..alias..}) => {:tables {..alias.. ..name..}} (table {..name.. ..alias.., ..name2.. ..alias2..}) => {:tables {..alias.. ..name.., ..alias2.. ..name2..}}) (fact "Project restricts (and/or adds) fields of a query" (prerequisites (keyword? ..table-alias..) => true (keyword? ..table..) => true (keyword? ..field..) => true (keyword? ..field-alias..) => true (keyword? ..field2..) => true (keyword? ..field2-alias..) => true) (fact "projecting onto a single field from one table" (-> (table {..table.. ..table-alias..}) (project [..field..])) => {:tables {..table-alias.. ..table..} :fields {..field.. [..table-alias.. ..field..]}} (-> (table {..table.. ..table-alias..}) (project {..field.. ..field-alias..})) => {:tables {..table-alias.. ..table..} :fields {..field-alias.. [..table-alias.. ..field..]}}) (fact "projecting onto multiple fields from one table" (-> (table {..table.. ..table-alias..}) (project [..field.. ..field2..])) => {:tables {..table-alias.. ..table..} :fields {..field.. [..table-alias.. ..field..] ..field2.. [..table-alias.. ..field2..]}} (-> (table {..table.. ..table-alias..}) (project {..field.. ..field-alias.., ..field2.. ..field2-alias..})) => {:tables {..table-alias.. ..table..} :fields {..field-alias.. [..table-alias.. ..field..] ..field2-alias.. [..table-alias.. ..field2..]}}) (fact "projecting one a field from multiple tables" (prerequisites ..tables.. =contains=> {:tables {..table.. ..table.., ..table2.. ..table2..}}) (project ..tables.. [..field..]) => (throws clojure.lang.ExceptionInfo) (project ..tables.. {..field.. ..field-alias..}) => (throws clojure.lang.ExceptionInfo)) (fact "projecting a subset of the current projection from one table" ;; Note that these two facts are retaining the ..table.. in the ;; fields rather than using the ..table-alias.. they would have ;; used otherwise. This shows they are filtering the existing ;; fields rather than removing and re-adding the fields. (project {:tables {..table-alias.. ..table..} :fields {..field.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}} [..field..]) => {:tables {..table-alias.. ..table..} :fields {..field.. [..table.. ..field..]}} (project {:tables {..table-alias.. ..table..} :fields {..field.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}} {..field.. ..field-alias..}) => {:tables {..table-alias.. ..table..} :fields {..field-alias.. [..table.. ..field..]}}) (fact "projecting a disjoint set from the current projection from one table" (project {:tables {..table-alias.. ..table..} :fields {[..table.. ..field..] ..field..}} [..field2..]) => {:tables {..table-alias.. ..table..} :fields {..field2.. [..table-alias.. ..field2..]}}) (fact "projecting a superset from the current projection from one table" (project {:tables {..table.. ..table..} :fields {..field.. [..table.. ..field..]}} [..field.. ..field2..]) => {:tables {..table.. ..table..} :fields {..field.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}} ;; once again - note the table aliases (project {:tables {..table-alias.. ..table..} :fields {..field.. [..table.. ..field..]}} [..field.. ..field2..]) => {:tables {..table-alias.. ..table..} :fields {..field.. [..table.. ..field..] ..field2.. [..table-alias.. ..field2..]}}) (fact "projecting a subset of the current projection from two table" (prerequisites ..tables.. =contains=> {:tables {..table.. ..table.., ..table2.. ..table2..}}) (project {:tables ..tables.. :fields {..field.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}} [..field..]) => {:tables ..tables.. :fields {..field.. [..table.. ..field..]}} (project {:tables ..tables.. :fields {..field.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}} {..field.. ..field-alias..}) => {:tables ..tables.. :fields {..field-alias.. [..table.. ..field..]}}) (fact "projecting a disjoint set from the current projection from two tables" (project {:tables {..table-alias.. ..table.., ..table2-alias.. ..table2..} :fields {[..table.. ..field..] ..field..}} [..field2..]) => (throws clojure.lang.ExceptionInfo)) (fact "projecting a superset from the current projection from two tables" (project {:tables {..table-alias.. ..table.., ..table2-alias.. ..table2..} :fields {[..table.. ..field..] ..field..}} [..field.. ..field2..]) => (throws clojure.lang.ExceptionInfo))) (fact "renaming fields does what you'd expect (renames them, removes the old alias)" (prerequisites (keyword? ..table..) => true (keyword? ..field..) => true (keyword? ..field2..) => true (keyword? ..field-alias..) => true) (-> (table ..table..) (project [..field..]) (rename {..field.. ..field-alias..})) => {:tables {..table.. ..table..} :fields {..field-alias.. [..table.. ..field..]}} (-> (table ..table..) (project [..field.. ..field2..]) (rename {..field.. ..field-alias..})) => {:tables {..table.. ..table..} :fields {..field-alias.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}} (-> {:tables {..table.. ..table.., ..table2.. ..table2..} :fields {..field.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}} (rename {..field.. ..field-alias..})) => {:tables {..table.. ..table.., ..table2.. ..table2..} :fields {..field-alias.. [..table.. ..field..] ..field2.. [..table.. ..field2..]}}) (fact "joining tables merges tables and fields" )