@@ -2,7 +2,7 @@ NimbleCSV.define(ParameterizedTest.TsvParser, separator: "\t", escape: "\"")
22NimbleCSV . define ( ParameterizedTest.CsvParser , separator: "," , escape: "\" " )
33
44defmodule ParameterizedTest do
5- @ moduledoc ~S """
5+ @ moduledoc """
66 A utility for defining eminently readable parameterized (or example-based) tests.
77
88 Parameterized tests look like this:
@@ -14,7 +14,7 @@ defmodule ParameterizedTest do
1414 | %{shoes: 19_99, pants: 29_99} | | false | Spent too little |
1515 | %{shoes: 59_99, pants: 49_99} | | true | Spent $100+ |
1616 | %{socks: 10_99} | | true | Socks ship free |
17- | %{pants: 1_99} | "FREE_SHIP" | true | Correct coupon |
17+ | %{pants: 1_99} | \ " FREE_SHIP\ " | true | Correct coupon |
1818 \" \" \" ,
1919 %{
2020 spending_by_category: spending_by_category,
@@ -82,63 +82,37 @@ defmodule ParameterizedTest do
8282
8383 Use it like:
8484
85- param_test "works as expected", your_parameters, %{value: from_context, expected_result: expected_result} do
86- assert MyModule.process(from_context) == expected_result
85+ param_test \" grants free shipping for spending $99+ or with coupon FREE_SHIP\" ,
86+ \" \" \"
87+ | total_cents | ships_free? | description |
88+ | ----------- | ----------- | --------------------------- |
89+ | 98_99 | false | Spent too little |
90+ | 99_00 | true | Min for free shipping |
91+ | 99_01 | true | Spent more than the minimum |
92+ \" \" \" ,
93+ %{total_cents: total_cents, ships_free?: ships_free?} do
94+ shipping_cost = ShippingCalculator.calculate(total_cents)
95+
96+ if ships_free? do
97+ assert shipping_cost == 0
98+ else
99+ assert shipping_cost > 0
100+ end
87101 end
102+
88103 """
89104 defmacro param_test ( test_name , examples , context_ast \\ % { } , blocks ) do
90105 context = Macro.Env . location ( __ENV__ )
91-
92- escaped_examples =
93- case examples do
94- str when is_binary ( str ) ->
95- file_extension =
96- str
97- |> Path . extname ( )
98- |> String . downcase ( )
99-
100- case file_extension do
101- ext when ext in [ ".md" , ".markdown" , ".csv" ] ->
102- str
103- |> Parser . parse_file_path_examples ( context )
104- |> Macro . escape ( )
105-
106- _ ->
107- str
108- |> Parser . parse_examples ( context )
109- |> Macro . escape ( )
110- end
111-
112- list when is_list ( list ) ->
113- list
114- |> Parser . parse_examples ( context )
115- |> Macro . escape ( )
116-
117- already_escaped when is_tuple ( already_escaped ) ->
118- already_escaped
119- end
106+ escaped_examples = escape_examples ( examples , context )
120107
121108 quote location: :keep do
122109 for { example , index } <- Enum . with_index ( unquote ( escaped_examples ) ) do
123110 for { key , val } <- example do
124111 @ tag [ { key , val } ]
125112 end
126113
127- custom_description =
128- example [ :test_desc ] || example [ :test_description ] || example [ :description ] || example [ :Description ]
129-
130- un_truncated_name =
131- case custom_description do
132- nil -> "#{ unquote ( test_name ) } (#{ inspect ( example ) } )"
133- test_name -> "#{ unquote ( test_name ) } - #{ test_name } "
134- end
135-
136- full_test_name =
137- cond do
138- String . length ( un_truncated_name ) <= 212 -> un_truncated_name
139- is_nil ( custom_description ) -> "#{ unquote ( test_name ) } row #{ index } "
140- true -> String . slice ( un_truncated_name , 0 , 212 )
141- end
114+ unquoted_test_name = unquote ( test_name )
115+ full_test_name = ParameterizedTest.Parser . full_test_name ( unquoted_test_name , example , index , 212 )
142116
143117 @ tag param_test: true
144118 test "#{ full_test_name } " , unquote ( context_ast ) do
@@ -147,4 +121,77 @@ defmodule ParameterizedTest do
147121 end
148122 end
149123 end
124+
125+ if Code . ensure_loaded? ( Wallaby ) do
126+ @ doc """
127+ Defines Wallaby feature tests that use your parameters or example data.
128+
129+ This is to the Wallaby `feature` macro as `param_test` is to `test`.
130+
131+ Use it like this:
132+
133+ param_feature \" supports Wallaby tests\" ,
134+ \" \" \"
135+ | text | url |
136+ |----------|----------------------|
137+ | \" GitHub\" | \" https://github.com\" |
138+ | \" Google\" | \" https://google.com\" |
139+ \" \" \" ,
140+ %{session: session, text: text, url: url} do
141+ session
142+ |> visit(url)
143+ |> assert_has(Wallaby.Query.text(text, minimum: 1))
144+ end
145+ """
146+ defmacro param_feature ( test_name , examples , context_ast \\ % { } , blocks ) do
147+ context = Macro.Env . location ( __ENV__ )
148+ escaped_examples = escape_examples ( examples , context )
149+
150+ quote location: :keep do
151+ for { example , index } <- Enum . with_index ( unquote ( escaped_examples ) ) do
152+ for { key , val } <- example do
153+ @ tag [ { key , val } ]
154+ end
155+
156+ unquoted_test_name = unquote ( test_name )
157+ @ full_test_name ParameterizedTest.Parser . full_test_name ( unquoted_test_name , example , index , 212 )
158+
159+ @ tag param_test: true
160+ feature "#{ @ full_test_name } " , unquote ( context_ast ) do
161+ unquote ( blocks )
162+ end
163+ end
164+ end
165+ end
166+ end
167+
168+ defp escape_examples ( examples , context ) do
169+ case examples do
170+ str when is_binary ( str ) ->
171+ file_extension =
172+ str
173+ |> Path . extname ( )
174+ |> String . downcase ( )
175+
176+ case file_extension do
177+ ext when ext in [ ".md" , ".markdown" , ".csv" ] ->
178+ str
179+ |> Parser . parse_file_path_examples ( context )
180+ |> Macro . escape ( )
181+
182+ _ ->
183+ str
184+ |> Parser . parse_examples ( context )
185+ |> Macro . escape ( )
186+ end
187+
188+ list when is_list ( list ) ->
189+ list
190+ |> Parser . parse_examples ( context )
191+ |> Macro . escape ( )
192+
193+ already_escaped when is_tuple ( already_escaped ) ->
194+ already_escaped
195+ end
196+ end
150197end
0 commit comments