contracts in clojure
play

Contracts in Clojure: Settling Types vs Tests @jessitron What do - PowerPoint PPT Presentation

Contracts in Clojure: Settling Types vs Tests @jessitron What do we know? How do we know it? Informal Reasoning Formal Experimental Proofs Evidence // Scala def formatReport(data: ReportData): ExcelSheet types (defn format-report


  1. Contracts in Clojure: Settling Types vs Tests @jessitron

  2. What do we know? How do we know it?

  3. Informal Reasoning Formal Experimental Proofs Evidence

  4. // Scala def formatReport(data: ReportData): ExcelSheet

  5. types

  6. (defn format-report [report-data] format-report …)

  7. (function-name arg1 arg2) function application

  8. function definition (defn function-name [param1 param2] (println "Hello QCon") (do-something-with (and param1 param2))) last expression is the result (function-name arg1 arg2)

  9. square braces make a vector (defn function-name [param1 param2] (println "Hello QCon") (do-something-with (and param1 param2)))

  10. (defn format-report [report-data] format-report …)

  11. (defn ad-performance-report [params] (-> (fetch-events params) (analyze-ad-performance params) format-report)) format-report

  12. (defn ad-performance-report [params] fetch-events (-> (fetch-events params) (analyze-ad-performance params) format-report))

  13. (defn fetch-events fetch-events [params] …)

  14. curly braces make a map {:when 12:34:56 7/8/90 :what "show" :who "abc123"} keyword

  15. give a thing a name (def Event {:when org.joda.time.DateTime :what java.lang.String ) :who java.lang.String}

  16. (:require [schema.core :as s]) dependency (def Event {:when DateTime :what s/Str ) :who s/Str}

  17. (def Incident s/Str) (def Customer s/Str) (def Event {:when DateTime Event :what Incident ) :who Customer}

  18. (def Event {:when DateTime :what Incident ) :who Customer} [Event]

  19. (defn fetch-events [params] …) [Event]

  20. (:require [schema.core :as s]) :- [Event] (s/defn fetch-events [params] …) [Event]

  21. (deftest fetch-events-test … (= (expected (fetch-events input))))

  22. (use-fixtures schema.test/validate-schemas) (deftest fetch-events-test … (= (expected (fetch-events input))))

  23. (defn ad-performance-report [params] (-> (fetch-events params) (d (analyze-ad-performance params) analyze-ad-performance format-report)) ) [Event]

  24. analyze-ad-performance (defn analyze-ad-performance [events params] (-> events (group-up params) summarize add-total-row (add-headers params)))

  25. (defn analyze-ad-performance [events params] (-> events (group-up params) summarize add-total-row (add-headers params))) [Event]

  26. (defn analyze-ad-performance [events params] (-> events (group-up params) summarize add-total-row (add-headers params))) [Event] [[Event]]

  27. (defn analyze-ad-performance [events params] (-> events (group-up params) summarize add-total-row (add-headers params))) [Event] [[Event]]

  28. [[Event] ]

  29. [[Event] Summation]

  30. [( one [Event] ) ( one Summation )]

  31. [(s/one [Event] "event list") (s/one Summation "group sum")]

  32. {:groups [[(s/one [Event] "event list") (s/one Summation "group sum")]]}

  33. {:groups [[(s/one [Event] "event list") (s/one Summation "group sum")]] :total Totals}

  34. {:header Headers :groups [[(s/one [Event] "event list") (s/one Summation "group sum")]] :total Totals})

  35. (def ReportData {:header Headers :groups [[(s/one [Event] "event list") (s/one Summation "group sum")]] :total Totals})

  36. (s/defn analyze-ad-performance :- ReportData [events :- [Event] params :- Params] (-> events (group-up params) summarize add-total-row (add-headers params)))

  37. (s/defn analyze-ad-performance :- ReportData …)

  38. (s/defn analyze-ad-performance :- (at-least ReportData) …)

  39. (defn at-least [map-schema] (merge map-schema {s/Any s/Any})) (s/defn analyze-ad-performance :- ( at-least ReportData) …)

  40. What do we know?

  41. What do we know? data shape

  42. What do we know? data shape value boundaries

  43. Headers :title - string - not empty - capitalized

  44. (def Headers {:title (s/constrained s/Str (s/pred (complement empty?) "nonempty") (s/pred capitalized? "Title Caps")) …})

  45. What do we know? data shape data value boundaries relationships within values

  46. What do we know? data shape data value boundaries relationships within values What could we know?

  47. What do we know? data shape data value boundaries relationships within values What could we know? produced types

  48. Seq[Event] (s/defn fetch-events :- [Event] [params] …)

  49. (s/defn fetch-events :- [Event] [params] …)

  50. what if? (st/defn fetch-events :+ (st/LazySeq Event) [params] …) check this later

  51. (:require [schematron.core :as st]) (st/defn fetch-events :+ (st/LazySeq Event) [params] …)

  52. (s/defn a-higher-order-function [predicate :- (s/=> Bool Event) …] …)

  53. what if? (st/defn a-higher-order-function [predicate :+ (st/=> Bool Event) …] …) check this later

  54. (s/defn a-higher-order-function :- Event [predicate :- (st/=> Bool Event) …] …)

  55. what if? (st/defn [ A ] a-higher-order-function :- A [predicate :+ (st/=> Bool A) …] …) (a-higher-order-function Event is-happy …)

  56. What do we know? data shape data value boundaries relationships within values What could we know? produced types relationships between types relationships between values

  57. What do we know? data shape data value boundaries relationships within values What could we know? produced types relationships between types relationships between values

  58. (defn group-up [events params] {:post [(as-lazy-as events %)] …)) postcondition

  59. data shape data value boundaries relationships within values produced types relationships between types relationships between values

  60. How do we know it?

  61. (deftest analyze-ad-performance-test (testing "grouping of rows" (let [… result (analyze-ad-performance events {}) (is (= expected (:groups result))))))

  62. (use-fixtures schema.test/validate-schemas) (deftest analyze-ad-performance-test (testing "grouping of rows" (let [… result (analyze-ad-performance events {}) (is (= expected (:groups result))))))

  63. (let [… result (analyze-ad-performance events {}) (is (= expected (:groups result)))))) Input does not match schema Params Missing required key :title Missing required key :start Missing required key :end

  64. (let [… result (analyze-ad-performance events (sc/complete {} Params) (is (= expected (:groups result)))))) "Fill in everything else with something random until it meets this schema"

  65. any string {:title "YhKEzII", :start "-217863493-11-21T00:54:39.872Z"], :end "-256417656-09-30T01:08:11.904Z"]} any date before any date the start before now

  66. (use-fixtures schema.test/validate-schemas) (deftest analyze-ad-performance-test (testing "grouping of rows" (let [… result (analyze-ad-performance [events] (sample-one param-gen)) (is (= expected (:groups result))))))

  67. 1 test is an anecdote generative tests are evidence

  68. ?

  69. ?

  70. Experimental ? Evidence

  71. (use-fixtures schema.test/validate-schemas) (defspec analyze-ad-performance-spec 100 (for-all [events events-gen params param-gen] (analyze-ad-performance events params)))) (s/defn analyze-ad-performance :- ReportData …)

  72. What do we know? Schemas How do we know it? Generative Tests

  73. B A Contract

  74. B A

  75. A A

  76. B A

  77. B A

  78. tests implementation generators schemas

  79. tests client libs implementation gen testkit schemas

  80. B A

  81. Clojure prismatic/schema test.check Science!

  82. … your language … types and contracts generative tests Science!

  83. … your services … client libraries testkits Science!

  84. Informal Reasoning Formal Experimental Proofs Evidence

  85. examples https://github.com/jessitron/contracts-as-types-examples https://github.com/jessitron/schematron resources https://github.com/Prismatic/schema http://hintjens.com/blog:85 The End of Software Versions http://david-mcneil.com/post/114783282473/extending- prismatic-schema-to-higher-order Static typing and productivity: Stefik & Hanenberg 2014 http://dl.acm.org/citation.cfm?id=2661156 @jessitron blog.jessitron.com

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend