@@ -5,8 +5,11 @@ const helpers = require('../test/helpers')
5
5
6
6
const noop = helpers . noop
7
7
const bindFunc = helpers . bindFunc
8
- const isObject = require ( '../predicates/isObject' )
8
+
9
+ const isArray = require ( '../predicates/isArray' )
9
10
const isFunction = require ( '../predicates/isFunction' )
11
+ const isObject = require ( '../predicates/isObject' )
12
+ const isSameType = require ( '../predicates/isSameType' )
10
13
11
14
const composeB = require ( '../combinators/composeB' )
12
15
const constant = require ( '../combinators/constant' )
@@ -172,6 +175,114 @@ test('Either coalesce', t => {
172
175
t . end ( )
173
176
} )
174
177
178
+ test ( 'Either concat errors' , t => {
179
+ const m = { type : ( ) => 'Either...Not' }
180
+
181
+ const good = Either . Right ( [ ] )
182
+ const bad = Either . Left ( [ ] )
183
+
184
+ const f = bindFunc ( Either . Right ( [ ] ) . concat )
185
+ const nonEitherErr = / E i t h e r .c o n c a t : E i t h e r o f S e m i g r o u p r e q u i r e d /
186
+
187
+ t . throws ( f ( undefined ) , nonEitherErr , 'throws with undefined on Right' )
188
+ t . throws ( f ( null ) , nonEitherErr , 'throws with null on Right' )
189
+ t . throws ( f ( 0 ) , nonEitherErr , 'throws with falsey number on Right' )
190
+ t . throws ( f ( 1 ) , nonEitherErr , 'throws with truthy number on Right' )
191
+ t . throws ( f ( '' ) , nonEitherErr , 'throws with falsey string on Right' )
192
+ t . throws ( f ( 'string' ) , nonEitherErr , 'throws with truthy string on Right' )
193
+ t . throws ( f ( false ) , nonEitherErr , 'throws with false on Right' )
194
+ t . throws ( f ( true ) , nonEitherErr , 'throws with true on Right' )
195
+ t . throws ( f ( [ ] ) , nonEitherErr , 'throws with array on Right' )
196
+ t . throws ( f ( { } ) , nonEitherErr , 'throws with object on Right' )
197
+ t . throws ( f ( m ) , nonEitherErr , 'throws with non-Either on Right' )
198
+
199
+ const g = bindFunc ( Either . Left ( 0 ) . concat )
200
+
201
+ t . throws ( g ( undefined ) , nonEitherErr , 'throws with undefined on Left' )
202
+ t . throws ( g ( null ) , nonEitherErr , 'throws with null on Left' )
203
+ t . throws ( g ( 0 ) , nonEitherErr , 'throws with falsey number on Left' )
204
+ t . throws ( g ( 1 ) , nonEitherErr , 'throws with truthy number on Left' )
205
+ t . throws ( g ( '' ) , nonEitherErr , 'throws with falsey string on Left' )
206
+ t . throws ( g ( 'string' ) , nonEitherErr , 'throws with truthy string on Left' )
207
+ t . throws ( g ( false ) , nonEitherErr , 'throws with false on Left' )
208
+ t . throws ( g ( true ) , nonEitherErr , 'throws with true on Left' )
209
+ t . throws ( g ( [ ] ) , nonEitherErr , 'throws with array on Left' )
210
+ t . throws ( g ( { } ) , nonEitherErr , 'throws with object on Left' )
211
+ t . throws ( g ( m ) , nonEitherErr , 'throws with non-Either on Left' )
212
+
213
+ const innerErr = / E i t h e r .c o n c a t : B o t h c o n t a i n e r s m u s t c o n t a i n S e m i g r o u p s o f t h e s a m e t y p e /
214
+ const notSemiLeft = bindFunc ( x => Either . Right ( x ) . concat ( good ) )
215
+
216
+ t . throws ( notSemiLeft ( undefined ) , innerErr , 'throws with undefined on left' )
217
+ t . throws ( notSemiLeft ( null ) , innerErr , 'throws with null on left' )
218
+ t . throws ( notSemiLeft ( 0 ) , innerErr , 'throws with falsey number on left' )
219
+ t . throws ( notSemiLeft ( 1 ) , innerErr , 'throws with truthy number on left' )
220
+ t . throws ( notSemiLeft ( '' ) , innerErr , 'throws with falsey string on left' )
221
+ t . throws ( notSemiLeft ( 'string' ) , innerErr , 'throws with truthy string on left' )
222
+ t . throws ( notSemiLeft ( false ) , innerErr , 'throws with false on left' )
223
+ t . throws ( notSemiLeft ( true ) , innerErr , 'throws with true on left' )
224
+ t . throws ( notSemiLeft ( { } ) , innerErr , 'throws with object on left' )
225
+
226
+ const notSemiRight = bindFunc ( x => good . concat ( Either . Right ( x ) ) )
227
+
228
+ t . throws ( notSemiRight ( undefined ) , innerErr , 'throws with undefined on right' )
229
+ t . throws ( notSemiRight ( null ) , innerErr , 'throws with null on right' )
230
+ t . throws ( notSemiRight ( 0 ) , innerErr , 'throws with falsey number on right' )
231
+ t . throws ( notSemiRight ( 1 ) , innerErr , 'throws with truthy number on right' )
232
+ t . throws ( notSemiRight ( '' ) , innerErr , 'throws with falsey string on right' )
233
+ t . throws ( notSemiRight ( 'string' ) , innerErr , 'throws with truthy string on right' )
234
+ t . throws ( notSemiRight ( false ) , innerErr , 'throws with false on right' )
235
+ t . throws ( notSemiRight ( true ) , innerErr , 'throws with true on right' )
236
+ t . throws ( notSemiRight ( { } ) , innerErr , 'throws with object on right' )
237
+
238
+ const noMatch = bindFunc ( ( ) => good . concat ( Either . Right ( '' ) ) )
239
+ t . throws ( noMatch ( { } ) , innerErr , 'throws with different semigroups' )
240
+
241
+ t . end ( )
242
+ } )
243
+
244
+ test ( 'Either concat functionality' , t => {
245
+ const extract =
246
+ either ( identity , identity )
247
+
248
+ const left = Either . Left ( 'Left' )
249
+ const a = Either . Right ( [ 1 , 2 ] )
250
+ const b = Either . Right ( [ 4 , 3 ] )
251
+
252
+ const right = a . concat ( b )
253
+ const leftRight = a . concat ( left )
254
+ const leftLeft = left . concat ( a )
255
+
256
+ t . ok ( isSameType ( Either , right ) , 'returns another Either with Right' )
257
+ t . ok ( isSameType ( Either , leftRight ) , 'returns another Either with Left on right side' )
258
+ t . ok ( isSameType ( Either , leftLeft ) , 'returns another Either with Left on left side' )
259
+
260
+ t . same ( extract ( right ) , [ 1 , 2 , 4 , 3 ] , 'concats the inner semigroup with Rights' )
261
+ t . equals ( extract ( leftRight ) , 'Left' , 'returns a Left with a Left on right side' )
262
+ t . equals ( extract ( leftLeft ) , 'Left' , 'returns a Left with a Left on left side' )
263
+
264
+ t . end ( )
265
+ } )
266
+
267
+ test ( 'Either concat properties (Semigoup)' , t => {
268
+ const extract =
269
+ either ( identity , identity )
270
+
271
+ const a = Either . Right ( [ 'a' ] )
272
+ const b = Either . Right ( [ 'b' ] )
273
+ const c = Either . Right ( [ 'c' ] )
274
+
275
+ const left = a . concat ( b ) . concat ( c )
276
+ const right = a . concat ( b . concat ( c ) )
277
+
278
+ t . ok ( isFunction ( a . concat ) , 'provides a concat function' )
279
+
280
+ t . same ( extract ( left ) , extract ( right ) , 'associativity' )
281
+ t . ok ( isArray ( extract ( a . concat ( b ) ) ) , 'returns an Array' )
282
+
283
+ t . end ( )
284
+ } )
285
+
175
286
test ( 'Either equals functionality' , t => {
176
287
const la = Either . Left ( 0 )
177
288
const lb = Either . Left ( 0 )
0 commit comments