growthbook 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/cases.json ADDED
@@ -0,0 +1,2768 @@
1
+ {
2
+ "evalCondition": [
3
+ [
4
+ "$not - pass",
5
+ {
6
+ "$not": {
7
+ "name": "hello"
8
+ }
9
+ },
10
+ {
11
+ "name": "world"
12
+ },
13
+ true
14
+ ],
15
+ [
16
+ "$not - fail",
17
+ {
18
+ "$not": {
19
+ "name": "hello"
20
+ }
21
+ },
22
+ {
23
+ "name": "hello"
24
+ },
25
+ false
26
+ ],
27
+ [
28
+ "$and/$or - all true",
29
+ {
30
+ "$and": [
31
+ {
32
+ "father.age": {
33
+ "$gt": 65
34
+ }
35
+ },
36
+ {
37
+ "$or": [
38
+ {
39
+ "bday": {
40
+ "$regex": "-12-25$"
41
+ }
42
+ },
43
+ {
44
+ "name": "santa"
45
+ }
46
+ ]
47
+ }
48
+ ]
49
+ },
50
+ {
51
+ "name": "santa",
52
+ "bday": "1980-12-25",
53
+ "father": {
54
+ "age": 70
55
+ }
56
+ },
57
+ true
58
+ ],
59
+ [
60
+ "$and/$or - first or true",
61
+ {
62
+ "$and": [
63
+ {
64
+ "father.age": {
65
+ "$gt": 65
66
+ }
67
+ },
68
+ {
69
+ "$or": [
70
+ {
71
+ "bday": {
72
+ "$regex": "-12-25$"
73
+ }
74
+ },
75
+ {
76
+ "name": "santa"
77
+ }
78
+ ]
79
+ }
80
+ ]
81
+ },
82
+ {
83
+ "name": "santa",
84
+ "bday": "1980-12-20",
85
+ "father": {
86
+ "age": 70
87
+ }
88
+ },
89
+ true
90
+ ],
91
+ [
92
+ "$and/$or - second or true",
93
+ {
94
+ "$and": [
95
+ {
96
+ "father.age": {
97
+ "$gt": 65
98
+ }
99
+ },
100
+ {
101
+ "$or": [
102
+ {
103
+ "bday": {
104
+ "$regex": "-12-25$"
105
+ }
106
+ },
107
+ {
108
+ "name": "santa"
109
+ }
110
+ ]
111
+ }
112
+ ]
113
+ },
114
+ {
115
+ "name": "barbara",
116
+ "bday": "1980-12-25",
117
+ "father": {
118
+ "age": 70
119
+ }
120
+ },
121
+ true
122
+ ],
123
+ [
124
+ "$and/$or - first and false",
125
+ {
126
+ "$and": [
127
+ {
128
+ "father.age": {
129
+ "$gt": 65
130
+ }
131
+ },
132
+ {
133
+ "$or": [
134
+ {
135
+ "bday": {
136
+ "$regex": "-12-25$"
137
+ }
138
+ },
139
+ {
140
+ "name": "santa"
141
+ }
142
+ ]
143
+ }
144
+ ]
145
+ },
146
+ {
147
+ "name": "santa",
148
+ "bday": "1980-12-25",
149
+ "father": {
150
+ "age": 65
151
+ }
152
+ },
153
+ false
154
+ ],
155
+ [
156
+ "$and/$or - both or false",
157
+ {
158
+ "$and": [
159
+ {
160
+ "father.age": {
161
+ "$gt": 65
162
+ }
163
+ },
164
+ {
165
+ "$or": [
166
+ {
167
+ "bday": {
168
+ "$regex": "-12-25$"
169
+ }
170
+ },
171
+ {
172
+ "name": "santa"
173
+ }
174
+ ]
175
+ }
176
+ ]
177
+ },
178
+ {
179
+ "name": "barbara",
180
+ "bday": "1980-11-25",
181
+ "father": {
182
+ "age": 70
183
+ }
184
+ },
185
+ false
186
+ ],
187
+ [
188
+ "$and/$or - both and false",
189
+ {
190
+ "$and": [
191
+ {
192
+ "father.age": {
193
+ "$gt": 65
194
+ }
195
+ },
196
+ {
197
+ "$or": [
198
+ {
199
+ "bday": {
200
+ "$regex": "-12-25$"
201
+ }
202
+ },
203
+ {
204
+ "name": "santa"
205
+ }
206
+ ]
207
+ }
208
+ ]
209
+ },
210
+ {
211
+ "name": "john smith",
212
+ "bday": "1956-12-20",
213
+ "father": {
214
+ "age": 40
215
+ }
216
+ },
217
+ false
218
+ ],
219
+ [
220
+ "$exists - false pass",
221
+ {
222
+ "pets.dog.name": {
223
+ "$exists": false
224
+ }
225
+ },
226
+ {
227
+ "hello": "world"
228
+ },
229
+ true
230
+ ],
231
+ [
232
+ "$exists - false fail",
233
+ {
234
+ "pets.dog.name": {
235
+ "$exists": false
236
+ }
237
+ },
238
+ {
239
+ "pets": {
240
+ "dog": {
241
+ "name": "fido"
242
+ }
243
+ }
244
+ },
245
+ false
246
+ ],
247
+ [
248
+ "$exists - true fail",
249
+ {
250
+ "pets.dog.name": {
251
+ "$exists": true
252
+ }
253
+ },
254
+ {
255
+ "hello": "world"
256
+ },
257
+ false
258
+ ],
259
+ [
260
+ "$exists - true pass",
261
+ {
262
+ "pets.dog.name": {
263
+ "$exists": true
264
+ }
265
+ },
266
+ {
267
+ "pets": {
268
+ "dog": {
269
+ "name": "fido"
270
+ }
271
+ }
272
+ },
273
+ true
274
+ ],
275
+ [
276
+ "equals - multiple datatypes",
277
+ {
278
+ "str": "str",
279
+ "num": 10,
280
+ "flag": false
281
+ },
282
+ {
283
+ "str": "str",
284
+ "num": 10,
285
+ "flag": false
286
+ },
287
+ true
288
+ ],
289
+ [
290
+ "$in - pass",
291
+ {
292
+ "num": {
293
+ "$in": [1, 2, 3]
294
+ }
295
+ },
296
+ {
297
+ "num": 2
298
+ },
299
+ true
300
+ ],
301
+ [
302
+ "$in - fail",
303
+ {
304
+ "num": {
305
+ "$in": [1, 2, 3]
306
+ }
307
+ },
308
+ {
309
+ "num": 4
310
+ },
311
+ false
312
+ ],
313
+ [
314
+ "$nin - pass",
315
+ {
316
+ "num": {
317
+ "$nin": [1, 2, 3]
318
+ }
319
+ },
320
+ {
321
+ "num": 4
322
+ },
323
+ true
324
+ ],
325
+ [
326
+ "$nin - fail",
327
+ {
328
+ "num": {
329
+ "$nin": [1, 2, 3]
330
+ }
331
+ },
332
+ {
333
+ "num": 2
334
+ },
335
+ false
336
+ ],
337
+ [
338
+ "$elemMatch - pass - flat arrays",
339
+ {
340
+ "nums": {
341
+ "$elemMatch": {
342
+ "$gt": 10
343
+ }
344
+ }
345
+ },
346
+ {
347
+ "nums": [0, 5, -20, 15]
348
+ },
349
+ true
350
+ ],
351
+ [
352
+ "$elemMatch - fail - flat arrays",
353
+ {
354
+ "nums": {
355
+ "$elemMatch": {
356
+ "$gt": 10
357
+ }
358
+ }
359
+ },
360
+ {
361
+ "nums": [0, 5, -20, 8]
362
+ },
363
+ false
364
+ ],
365
+ [
366
+ "missing attribute - fail",
367
+ {
368
+ "pets.dog.name": {
369
+ "$in": ["fido"]
370
+ }
371
+ },
372
+ {
373
+ "hello": "world"
374
+ },
375
+ false
376
+ ],
377
+ [
378
+ "empty $or - pass",
379
+ {
380
+ "$or": []
381
+ },
382
+ {
383
+ "hello": "world"
384
+ },
385
+ true
386
+ ],
387
+ [
388
+ "empty $and - pass",
389
+ {
390
+ "$and": []
391
+ },
392
+ {
393
+ "hello": "world"
394
+ },
395
+ true
396
+ ],
397
+ [
398
+ "empty - pass",
399
+ {},
400
+ {
401
+ "hello": "world"
402
+ },
403
+ true
404
+ ],
405
+ [
406
+ "$eq - pass",
407
+ {
408
+ "occupation": {
409
+ "$eq": "engineer"
410
+ }
411
+ },
412
+ {
413
+ "occupation": "engineer"
414
+ },
415
+ true
416
+ ],
417
+ [
418
+ "$eq - fail",
419
+ {
420
+ "occupation": {
421
+ "$eq": "engineer"
422
+ }
423
+ },
424
+ {
425
+ "occupation": "civil engineer"
426
+ },
427
+ false
428
+ ],
429
+ [
430
+ "$ne - pass",
431
+ {
432
+ "level": {
433
+ "$ne": "senior"
434
+ }
435
+ },
436
+ {
437
+ "level": "junior"
438
+ },
439
+ true
440
+ ],
441
+ [
442
+ "$ne - fail",
443
+ {
444
+ "level": {
445
+ "$ne": "senior"
446
+ }
447
+ },
448
+ {
449
+ "level": "senior"
450
+ },
451
+ false
452
+ ],
453
+ [
454
+ "$regex - pass",
455
+ {
456
+ "userAgent": {
457
+ "$regex": "(Mobile|Tablet)"
458
+ }
459
+ },
460
+ {
461
+ "userAgent": "Android Mobile Browser"
462
+ },
463
+ true
464
+ ],
465
+ [
466
+ "$regex - fail",
467
+ {
468
+ "userAgent": {
469
+ "$regex": "(Mobile|Tablet)"
470
+ }
471
+ },
472
+ {
473
+ "userAgent": "Chrome Desktop Browser"
474
+ },
475
+ false
476
+ ],
477
+ [
478
+ "$gt/$lt numbers - pass",
479
+ {
480
+ "age": {
481
+ "$gt": 30,
482
+ "$lt": 60
483
+ }
484
+ },
485
+ {
486
+ "age": 50
487
+ },
488
+ true
489
+ ],
490
+ [
491
+ "$gt/$lt numbers - fail $lt",
492
+ {
493
+ "age": {
494
+ "$gt": 30,
495
+ "$lt": 60
496
+ }
497
+ },
498
+ {
499
+ "age": 60
500
+ },
501
+ false
502
+ ],
503
+ [
504
+ "$gt/$lt numbers - fail $gt",
505
+ {
506
+ "age": {
507
+ "$gt": 30,
508
+ "$lt": 60
509
+ }
510
+ },
511
+ {
512
+ "age": 30
513
+ },
514
+ false
515
+ ],
516
+ [
517
+ "$gte/$lte numbers - pass",
518
+ {
519
+ "age": {
520
+ "$gte": 30,
521
+ "$lte": 60
522
+ }
523
+ },
524
+ {
525
+ "age": 50
526
+ },
527
+ true
528
+ ],
529
+ [
530
+ "$gte/$lte numbers - pass $gte",
531
+ {
532
+ "age": {
533
+ "$gte": 30,
534
+ "$lte": 60
535
+ }
536
+ },
537
+ {
538
+ "age": 30
539
+ },
540
+ true
541
+ ],
542
+ [
543
+ "$gte/$lte numbers - pass $lte",
544
+ {
545
+ "age": {
546
+ "$gte": 30,
547
+ "$lte": 60
548
+ }
549
+ },
550
+ {
551
+ "age": 60
552
+ },
553
+ true
554
+ ],
555
+ [
556
+ "$gte/$lte numbers - fail $lte",
557
+ {
558
+ "age": {
559
+ "$gte": 30,
560
+ "$lte": 60
561
+ }
562
+ },
563
+ {
564
+ "age": 61
565
+ },
566
+ false
567
+ ],
568
+ [
569
+ "$gte/$lte numbers - fail $gte",
570
+ {
571
+ "age": {
572
+ "$gt": 30,
573
+ "$lt": 60
574
+ }
575
+ },
576
+ {
577
+ "age": 29
578
+ },
579
+ false
580
+ ],
581
+ [
582
+ "$gt/$lt strings - fail $gt",
583
+ {
584
+ "word": {
585
+ "$gt": "alphabet",
586
+ "$lt": "zebra"
587
+ }
588
+ },
589
+ {
590
+ "word": "alphabet"
591
+ },
592
+ false
593
+ ],
594
+ [
595
+ "$gt/$lt strings - fail $lt",
596
+ {
597
+ "word": {
598
+ "$gt": "alphabet",
599
+ "$lt": "zebra"
600
+ }
601
+ },
602
+ {
603
+ "word": "zebra"
604
+ },
605
+ false
606
+ ],
607
+ [
608
+ "$gt/$lt strings - pass",
609
+ {
610
+ "word": {
611
+ "$gt": "alphabet",
612
+ "$lt": "zebra"
613
+ }
614
+ },
615
+ {
616
+ "word": "always"
617
+ },
618
+ true
619
+ ],
620
+ [
621
+ "$gt/$lt strings - fail uppercase",
622
+ {
623
+ "word": {
624
+ "$gt": "alphabet",
625
+ "$lt": "zebra"
626
+ }
627
+ },
628
+ {
629
+ "word": "AZL"
630
+ },
631
+ false
632
+ ],
633
+ [
634
+ "nested value is null",
635
+ {
636
+ "address.state": "CA"
637
+ },
638
+ {
639
+ "address": null
640
+ },
641
+ false
642
+ ],
643
+ [
644
+ "nested value is integer",
645
+ {
646
+ "address.state": "CA"
647
+ },
648
+ {
649
+ "address": 123
650
+ },
651
+ false
652
+ ],
653
+ [
654
+ "$type string - pass",
655
+ {
656
+ "a": {
657
+ "$type": "string"
658
+ }
659
+ },
660
+ {
661
+ "a": "a"
662
+ },
663
+ true
664
+ ],
665
+ [
666
+ "$type string - fail",
667
+ {
668
+ "a": {
669
+ "$type": "string"
670
+ }
671
+ },
672
+ {
673
+ "a": 1
674
+ },
675
+ false
676
+ ],
677
+ [
678
+ "$type null - pass",
679
+ {
680
+ "a": {
681
+ "$type": "null"
682
+ }
683
+ },
684
+ {
685
+ "a": null
686
+ },
687
+ true
688
+ ],
689
+ [
690
+ "$type null - fail",
691
+ {
692
+ "a": {
693
+ "$type": "null"
694
+ }
695
+ },
696
+ {
697
+ "a": 1
698
+ },
699
+ false
700
+ ],
701
+ [
702
+ "$type boolean - pass",
703
+ {
704
+ "a": {
705
+ "$type": "boolean"
706
+ }
707
+ },
708
+ {
709
+ "a": false
710
+ },
711
+ true
712
+ ],
713
+ [
714
+ "$type boolean - fail",
715
+ {
716
+ "a": {
717
+ "$type": "boolean"
718
+ }
719
+ },
720
+ {
721
+ "a": 1
722
+ },
723
+ false
724
+ ],
725
+ [
726
+ "$type number - pass",
727
+ {
728
+ "a": {
729
+ "$type": "number"
730
+ }
731
+ },
732
+ {
733
+ "a": 1
734
+ },
735
+ true
736
+ ],
737
+ [
738
+ "$type number - fail",
739
+ {
740
+ "a": {
741
+ "$type": "number"
742
+ }
743
+ },
744
+ {
745
+ "a": "a"
746
+ },
747
+ false
748
+ ],
749
+ [
750
+ "$type object - pass",
751
+ {
752
+ "a": {
753
+ "$type": "object"
754
+ }
755
+ },
756
+ {
757
+ "a": {
758
+ "a": "b"
759
+ }
760
+ },
761
+ true
762
+ ],
763
+ [
764
+ "$type object - fail",
765
+ {
766
+ "a": {
767
+ "$type": "object"
768
+ }
769
+ },
770
+ {
771
+ "a": 1
772
+ },
773
+ false
774
+ ],
775
+ [
776
+ "$type array - pass",
777
+ {
778
+ "a": {
779
+ "$type": "array"
780
+ }
781
+ },
782
+ {
783
+ "a": [1, 2]
784
+ },
785
+ true
786
+ ],
787
+ [
788
+ "$type array - fail",
789
+ {
790
+ "a": {
791
+ "$type": "array"
792
+ }
793
+ },
794
+ {
795
+ "a": 1
796
+ },
797
+ false
798
+ ],
799
+ [
800
+ "unknown operator - pass",
801
+ {
802
+ "name": {
803
+ "$regx": "hello"
804
+ }
805
+ },
806
+ {
807
+ "name": "hello"
808
+ },
809
+ false
810
+ ],
811
+ [
812
+ "$regex invalid - pass",
813
+ {
814
+ "name": {
815
+ "$regex": "/???***[)"
816
+ }
817
+ },
818
+ {
819
+ "name": "hello"
820
+ },
821
+ false
822
+ ],
823
+ [
824
+ "$regex invalid - fail",
825
+ {
826
+ "name": {
827
+ "$regex": "/???***[)"
828
+ }
829
+ },
830
+ {
831
+ "hello": "hello"
832
+ },
833
+ false
834
+ ],
835
+ [
836
+ "$size empty - pass",
837
+ {
838
+ "tags": { "$size": 0 }
839
+ },
840
+ {
841
+ "tags": []
842
+ },
843
+ true
844
+ ],
845
+ [
846
+ "$size empty - fail",
847
+ {
848
+ "tags": { "$size": 0 }
849
+ },
850
+ {
851
+ "tags": [10]
852
+ },
853
+ false
854
+ ],
855
+ [
856
+ "$size number - pass",
857
+ {
858
+ "tags": {
859
+ "$size": 3
860
+ }
861
+ },
862
+ {
863
+ "tags": ["a", "b", "c"]
864
+ },
865
+ true
866
+ ],
867
+ [
868
+ "$size number - fail small",
869
+ {
870
+ "tags": {
871
+ "$size": 3
872
+ }
873
+ },
874
+ {
875
+ "tags": ["a", "b"]
876
+ },
877
+ false
878
+ ],
879
+ [
880
+ "$size number - fail large",
881
+ {
882
+ "tags": {
883
+ "$size": 3
884
+ }
885
+ },
886
+ {
887
+ "tags": ["a", "b", "c", "d"]
888
+ },
889
+ false
890
+ ],
891
+ [
892
+ "$size number - fail not array",
893
+ {
894
+ "tags": {
895
+ "$size": 3
896
+ }
897
+ },
898
+ {
899
+ "tags": "abc"
900
+ },
901
+ false
902
+ ],
903
+ [
904
+ "$size nested - pass",
905
+ {
906
+ "tags": {
907
+ "$size": {
908
+ "$gt": 2
909
+ }
910
+ }
911
+ },
912
+ {
913
+ "tags": [0, 1, 2]
914
+ },
915
+ true
916
+ ],
917
+ [
918
+ "$size nested - fail equal",
919
+ {
920
+ "tags": {
921
+ "$size": {
922
+ "$gt": 2
923
+ }
924
+ }
925
+ },
926
+ {
927
+ "tags": [0, 1]
928
+ },
929
+ false
930
+ ],
931
+ [
932
+ "$size nested - fail less than",
933
+ {
934
+ "tags": {
935
+ "$size": {
936
+ "$gt": 2
937
+ }
938
+ }
939
+ },
940
+ {
941
+ "tags": [0]
942
+ },
943
+ false
944
+ ],
945
+ [
946
+ "$elemMatch contains - pass",
947
+ {
948
+ "tags": {
949
+ "$elemMatch": {
950
+ "$eq": "bar"
951
+ }
952
+ }
953
+ },
954
+ {
955
+ "tags": ["foo", "bar", "baz"]
956
+ },
957
+ true
958
+ ],
959
+ [
960
+ "$elemMatch contains - false",
961
+ {
962
+ "tags": {
963
+ "$elemMatch": {
964
+ "$eq": "bar"
965
+ }
966
+ }
967
+ },
968
+ {
969
+ "tags": ["foo", "baz"]
970
+ },
971
+ false
972
+ ],
973
+ [
974
+ "$elemMatch not contains - pass",
975
+ {
976
+ "tags": {
977
+ "$not": {
978
+ "$elemMatch": {
979
+ "$eq": "bar"
980
+ }
981
+ }
982
+ }
983
+ },
984
+ {
985
+ "tags": ["foo", "baz"]
986
+ },
987
+ true
988
+ ],
989
+ [
990
+ "$elemMatch not contains - fail",
991
+ {
992
+ "tags": {
993
+ "$not": {
994
+ "$elemMatch": {
995
+ "$eq": "bar"
996
+ }
997
+ }
998
+ }
999
+ },
1000
+ {
1001
+ "tags": ["foo", "bar", "baz"]
1002
+ },
1003
+ false
1004
+ ],
1005
+ [
1006
+ "$elemMatch nested - pass",
1007
+ {
1008
+ "hobbies": {
1009
+ "$elemMatch": {
1010
+ "name": {
1011
+ "$regex": "^ping"
1012
+ }
1013
+ }
1014
+ }
1015
+ },
1016
+ {
1017
+ "hobbies": [
1018
+ {
1019
+ "name": "bowling"
1020
+ },
1021
+ {
1022
+ "name": "pingpong"
1023
+ },
1024
+ {
1025
+ "name": "tennis"
1026
+ }
1027
+ ]
1028
+ },
1029
+ true
1030
+ ],
1031
+ [
1032
+ "$elemMatch nested - fail",
1033
+ {
1034
+ "hobbies": {
1035
+ "$elemMatch": {
1036
+ "name": {
1037
+ "$regex": "^ping"
1038
+ }
1039
+ }
1040
+ }
1041
+ },
1042
+ {
1043
+ "hobbies": [
1044
+ {
1045
+ "name": "bowling"
1046
+ },
1047
+ {
1048
+ "name": "tennis"
1049
+ }
1050
+ ]
1051
+ },
1052
+ false
1053
+ ],
1054
+ [
1055
+ "$elemMatch nested - fail not array",
1056
+ {
1057
+ "hobbies": {
1058
+ "$elemMatch": {
1059
+ "name": {
1060
+ "$regex": "^ping"
1061
+ }
1062
+ }
1063
+ }
1064
+ },
1065
+ {
1066
+ "hobbies": "all"
1067
+ },
1068
+ false
1069
+ ],
1070
+ [
1071
+ "$not - pass",
1072
+ {
1073
+ "name": {
1074
+ "$not": {
1075
+ "$regex": "^hello"
1076
+ }
1077
+ }
1078
+ },
1079
+ {
1080
+ "name": "world"
1081
+ },
1082
+ true
1083
+ ],
1084
+ [
1085
+ "$not - fail",
1086
+ {
1087
+ "name": {
1088
+ "$not": {
1089
+ "$regex": "^hello"
1090
+ }
1091
+ }
1092
+ },
1093
+ {
1094
+ "name": "hello world"
1095
+ },
1096
+ false
1097
+ ],
1098
+ [
1099
+ "$all - pass",
1100
+ {
1101
+ "tags": {
1102
+ "$all": ["one", "three"]
1103
+ }
1104
+ },
1105
+ {
1106
+ "tags": ["one", "two", "three"]
1107
+ },
1108
+ true
1109
+ ],
1110
+ [
1111
+ "$all - fail",
1112
+ {
1113
+ "tags": {
1114
+ "$all": ["one", "three"]
1115
+ }
1116
+ },
1117
+ {
1118
+ "tags": ["one", "two", "four"]
1119
+ },
1120
+ false
1121
+ ],
1122
+ [
1123
+ "$all - fail not array",
1124
+ {
1125
+ "tags": {
1126
+ "$all": ["one", "three"]
1127
+ }
1128
+ },
1129
+ {
1130
+ "tags": "hello"
1131
+ },
1132
+ false
1133
+ ],
1134
+ [
1135
+ "$nor - pass",
1136
+ {
1137
+ "$nor": [
1138
+ {
1139
+ "name": "john"
1140
+ },
1141
+ {
1142
+ "age": {
1143
+ "$lt": 30
1144
+ }
1145
+ }
1146
+ ]
1147
+ },
1148
+ {
1149
+ "name": "jim",
1150
+ "age": 40
1151
+ },
1152
+ true
1153
+ ],
1154
+ [
1155
+ "$nor - fail both",
1156
+ {
1157
+ "$nor": [
1158
+ {
1159
+ "name": "john"
1160
+ },
1161
+ {
1162
+ "age": {
1163
+ "$lt": 30
1164
+ }
1165
+ }
1166
+ ]
1167
+ },
1168
+ {
1169
+ "name": "john",
1170
+ "age": 20
1171
+ },
1172
+ false
1173
+ ],
1174
+ [
1175
+ "$nor - fail first",
1176
+ {
1177
+ "$nor": [
1178
+ {
1179
+ "name": "john"
1180
+ },
1181
+ {
1182
+ "age": {
1183
+ "$lt": 30
1184
+ }
1185
+ }
1186
+ ]
1187
+ },
1188
+ {
1189
+ "name": "john",
1190
+ "age": 40
1191
+ },
1192
+ false
1193
+ ],
1194
+ [
1195
+ "$nor - fail second",
1196
+ {
1197
+ "$nor": [
1198
+ {
1199
+ "name": "john"
1200
+ },
1201
+ {
1202
+ "age": {
1203
+ "$lt": 30
1204
+ }
1205
+ }
1206
+ ]
1207
+ },
1208
+ {
1209
+ "name": "jim",
1210
+ "age": 20
1211
+ },
1212
+ false
1213
+ ],
1214
+ [
1215
+ "equals array - pass",
1216
+ {
1217
+ "tags": ["hello", "world"]
1218
+ },
1219
+ {
1220
+ "tags": ["hello", "world"]
1221
+ },
1222
+ true
1223
+ ],
1224
+ [
1225
+ "equals array - fail order",
1226
+ {
1227
+ "tags": ["hello", "world"]
1228
+ },
1229
+ {
1230
+ "tags": ["world", "hello"]
1231
+ },
1232
+ false
1233
+ ],
1234
+ [
1235
+ "equals array - fail missing item",
1236
+ {
1237
+ "tags": ["hello", "world"]
1238
+ },
1239
+ {
1240
+ "tags": ["hello"]
1241
+ },
1242
+ false
1243
+ ],
1244
+ [
1245
+ "equals array - fail extra item",
1246
+ {
1247
+ "tags": ["hello", "world"]
1248
+ },
1249
+ {
1250
+ "tags": ["hello", "world", "foo"]
1251
+ },
1252
+ false
1253
+ ],
1254
+ [
1255
+ "equals array - fail type mismatch",
1256
+ {
1257
+ "tags": ["hello", "world"]
1258
+ },
1259
+ {
1260
+ "tags": "hello world"
1261
+ },
1262
+ false
1263
+ ],
1264
+ [
1265
+ "equals object - pass",
1266
+ {
1267
+ "tags": {
1268
+ "hello": "world"
1269
+ }
1270
+ },
1271
+ {
1272
+ "tags": {
1273
+ "hello": "world"
1274
+ }
1275
+ },
1276
+ true
1277
+ ],
1278
+ [
1279
+ "equals object - fail extra property",
1280
+ {
1281
+ "tags": {
1282
+ "hello": "world"
1283
+ }
1284
+ },
1285
+ {
1286
+ "tags": {
1287
+ "hello": "world",
1288
+ "yes": "please"
1289
+ }
1290
+ },
1291
+ false
1292
+ ],
1293
+ [
1294
+ "equals object - fail missing property",
1295
+ {
1296
+ "tags": {
1297
+ "hello": "world"
1298
+ }
1299
+ },
1300
+ {
1301
+ "tags": {}
1302
+ },
1303
+ false
1304
+ ],
1305
+ [
1306
+ "equals object - fail type mismatch",
1307
+ {
1308
+ "tags": {
1309
+ "hello": "world"
1310
+ }
1311
+ },
1312
+ {
1313
+ "tags": "hello world"
1314
+ },
1315
+ false
1316
+ ]
1317
+ ],
1318
+ "hash": [
1319
+ ["a", 0.22],
1320
+ ["b", 0.077],
1321
+ ["ab", 0.946],
1322
+ ["def", 0.652],
1323
+ ["8952klfjas09ujkasdf", 0.549],
1324
+ ["123", 0.011],
1325
+ ["___)((*\":&", 0.563]
1326
+ ],
1327
+ "getBucketRange": [
1328
+ [
1329
+ "normal 50/50",
1330
+ [2, 1, null],
1331
+ [
1332
+ [0, 0.5],
1333
+ [0.5, 1]
1334
+ ]
1335
+ ],
1336
+ [
1337
+ "reduced coverage",
1338
+ [2, 0.5, null],
1339
+ [
1340
+ [0, 0.25],
1341
+ [0.5, 0.75]
1342
+ ]
1343
+ ],
1344
+ [
1345
+ "zero coverage",
1346
+ [2, 0, null],
1347
+ [
1348
+ [0, 0],
1349
+ [0.5, 0.5]
1350
+ ]
1351
+ ],
1352
+ [
1353
+ "4 variations",
1354
+ [4, 1, null],
1355
+ [
1356
+ [0, 0.25],
1357
+ [0.25, 0.5],
1358
+ [0.5, 0.75],
1359
+ [0.75, 1]
1360
+ ]
1361
+ ],
1362
+ [
1363
+ "uneven weights",
1364
+ [2, 1, [0.4, 0.6]],
1365
+ [
1366
+ [0, 0.4],
1367
+ [0.4, 1]
1368
+ ]
1369
+ ],
1370
+ [
1371
+ "uneven weights, 3 variations",
1372
+ [3, 1, [0.2, 0.3, 0.5]],
1373
+ [
1374
+ [0, 0.2],
1375
+ [0.2, 0.5],
1376
+ [0.5, 1]
1377
+ ]
1378
+ ],
1379
+ [
1380
+ "uneven weights, reduced coverage, 3 variations",
1381
+ [3, 0.2, [0.2, 0.3, 0.5]],
1382
+ [
1383
+ [0, 0.04],
1384
+ [0.2, 0.26],
1385
+ [0.5, 0.6]
1386
+ ]
1387
+ ],
1388
+ [
1389
+ "negative coverage",
1390
+ [2, -0.2, null],
1391
+ [
1392
+ [0, 0],
1393
+ [0.5, 0.5]
1394
+ ]
1395
+ ],
1396
+ [
1397
+ "coverage above 1",
1398
+ [2, 1.5, null],
1399
+ [
1400
+ [0, 0.5],
1401
+ [0.5, 1]
1402
+ ]
1403
+ ],
1404
+ [
1405
+ "weights sum below 1",
1406
+ [2, 1, [0.4, 0.1]],
1407
+ [
1408
+ [0, 0.5],
1409
+ [0.5, 1]
1410
+ ]
1411
+ ],
1412
+ [
1413
+ "weights sum above 1",
1414
+ [2, 1, [0.7, 0.6]],
1415
+ [
1416
+ [0, 0.5],
1417
+ [0.5, 1]
1418
+ ]
1419
+ ],
1420
+ [
1421
+ "weights.length not equal to num variations",
1422
+ [4, 1, [0.4, 0.4, 0.2]],
1423
+ [
1424
+ [0, 0.25],
1425
+ [0.25, 0.5],
1426
+ [0.5, 0.75],
1427
+ [0.75, 1]
1428
+ ]
1429
+ ],
1430
+ [
1431
+ "weights sum almost equals 1",
1432
+ [2, 1, [0.4, 0.5999]],
1433
+ [
1434
+ [0, 0.4],
1435
+ [0.4, 0.9999]
1436
+ ]
1437
+ ]
1438
+ ],
1439
+ "feature": [
1440
+ [
1441
+ "unknown feature key",
1442
+ {},
1443
+ "my-feature",
1444
+ {
1445
+ "value": null,
1446
+ "on": false,
1447
+ "off": true,
1448
+ "source": "unknownFeature"
1449
+ }
1450
+ ],
1451
+ [
1452
+ "defaults when empty",
1453
+ { "features": { "feature": {} } },
1454
+ "feature",
1455
+ {
1456
+ "value": null,
1457
+ "on": false,
1458
+ "off": true,
1459
+ "source": "defaultValue"
1460
+ }
1461
+ ],
1462
+ [
1463
+ "uses defaultValue - number",
1464
+ { "features": { "feature": { "defaultValue": 1 } } },
1465
+ "feature",
1466
+ {
1467
+ "value": 1,
1468
+ "on": true,
1469
+ "off": false,
1470
+ "source": "defaultValue"
1471
+ }
1472
+ ],
1473
+ [
1474
+ "uses custom values - string",
1475
+ { "features": { "feature": { "defaultValue": "yes" } } },
1476
+ "feature",
1477
+ {
1478
+ "value": "yes",
1479
+ "on": true,
1480
+ "off": false,
1481
+ "source": "defaultValue"
1482
+ }
1483
+ ],
1484
+ [
1485
+ "force rules",
1486
+ {
1487
+ "features": {
1488
+ "feature": {
1489
+ "defaultValue": 2,
1490
+ "rules": [
1491
+ {
1492
+ "force": 1
1493
+ }
1494
+ ]
1495
+ }
1496
+ }
1497
+ },
1498
+ "feature",
1499
+ {
1500
+ "value": 1,
1501
+ "on": true,
1502
+ "off": false,
1503
+ "source": "force"
1504
+ }
1505
+ ],
1506
+ [
1507
+ "force rules - force false",
1508
+ {
1509
+ "features": {
1510
+ "feature": {
1511
+ "defaultValue": true,
1512
+ "rules": [
1513
+ {
1514
+ "force": false
1515
+ }
1516
+ ]
1517
+ }
1518
+ }
1519
+ },
1520
+ "feature",
1521
+ {
1522
+ "value": false,
1523
+ "on": false,
1524
+ "off": true,
1525
+ "source": "force"
1526
+ }
1527
+ ],
1528
+ [
1529
+ "force rules - coverage included",
1530
+ {
1531
+ "attributes": {
1532
+ "id": "3"
1533
+ },
1534
+ "features": {
1535
+ "feature": {
1536
+ "defaultValue": 2,
1537
+ "rules": [
1538
+ {
1539
+ "force": 1,
1540
+ "coverage": 0.5
1541
+ }
1542
+ ]
1543
+ }
1544
+ }
1545
+ },
1546
+ "feature",
1547
+ {
1548
+ "value": 1,
1549
+ "on": true,
1550
+ "off": false,
1551
+ "source": "force"
1552
+ }
1553
+ ],
1554
+ [
1555
+ "force rules - coverage excluded",
1556
+ {
1557
+ "attributes": {
1558
+ "id": "1"
1559
+ },
1560
+ "features": {
1561
+ "feature": {
1562
+ "defaultValue": 2,
1563
+ "rules": [
1564
+ {
1565
+ "force": 1,
1566
+ "coverage": 0.5
1567
+ }
1568
+ ]
1569
+ }
1570
+ }
1571
+ },
1572
+ "feature",
1573
+ {
1574
+ "value": 2,
1575
+ "on": true,
1576
+ "off": false,
1577
+ "source": "defaultValue"
1578
+ }
1579
+ ],
1580
+ [
1581
+ "force rules - coverage missing hashAttribute",
1582
+ {
1583
+ "attributes": {},
1584
+ "features": {
1585
+ "feature": {
1586
+ "defaultValue": 2,
1587
+ "rules": [
1588
+ {
1589
+ "force": 1,
1590
+ "coverage": 0.5
1591
+ }
1592
+ ]
1593
+ }
1594
+ }
1595
+ },
1596
+ "feature",
1597
+ {
1598
+ "value": 2,
1599
+ "on": true,
1600
+ "off": false,
1601
+ "source": "defaultValue"
1602
+ }
1603
+ ],
1604
+ [
1605
+ "force rules - condition pass",
1606
+ {
1607
+ "attributes": {
1608
+ "country": "US",
1609
+ "browser": "firefox"
1610
+ },
1611
+ "features": {
1612
+ "feature": {
1613
+ "defaultValue": 2,
1614
+ "rules": [
1615
+ {
1616
+ "force": 1,
1617
+ "condition": {
1618
+ "country": { "$in": ["US", "CA"] },
1619
+ "browser": "firefox"
1620
+ }
1621
+ }
1622
+ ]
1623
+ }
1624
+ }
1625
+ },
1626
+ "feature",
1627
+ {
1628
+ "value": 1,
1629
+ "on": true,
1630
+ "off": false,
1631
+ "source": "force"
1632
+ }
1633
+ ],
1634
+ [
1635
+ "force rules - condition fail",
1636
+ {
1637
+ "attributes": {
1638
+ "country": "US",
1639
+ "browser": "chrome"
1640
+ },
1641
+ "features": {
1642
+ "feature": {
1643
+ "defaultValue": 2,
1644
+ "rules": [
1645
+ {
1646
+ "force": 1,
1647
+ "condition": {
1648
+ "country": { "$in": ["US", "CA"] },
1649
+ "browser": "firefox"
1650
+ }
1651
+ }
1652
+ ]
1653
+ }
1654
+ }
1655
+ },
1656
+ "feature",
1657
+ {
1658
+ "value": 2,
1659
+ "on": true,
1660
+ "off": false,
1661
+ "source": "defaultValue"
1662
+ }
1663
+ ],
1664
+ [
1665
+ "ignores empty rules",
1666
+ {
1667
+ "features": {
1668
+ "feature": {
1669
+ "rules": [{}]
1670
+ }
1671
+ }
1672
+ },
1673
+ "feature",
1674
+ {
1675
+ "value": null,
1676
+ "on": false,
1677
+ "off": true,
1678
+ "source": "defaultValue"
1679
+ }
1680
+ ],
1681
+ [
1682
+ "empty experiment rule - c",
1683
+ {
1684
+ "attributes": {
1685
+ "id": "123"
1686
+ },
1687
+ "features": {
1688
+ "feature": {
1689
+ "rules": [
1690
+ {
1691
+ "variations": ["a", "b", "c"]
1692
+ }
1693
+ ]
1694
+ }
1695
+ }
1696
+ },
1697
+ "feature",
1698
+ {
1699
+ "value": "c",
1700
+ "on": true,
1701
+ "off": false,
1702
+ "experiment": {
1703
+ "key": "feature",
1704
+ "variations": ["a", "b", "c"]
1705
+ },
1706
+ "experimentResult": {
1707
+ "value": "c",
1708
+ "variationId": 2,
1709
+ "inExperiment": true,
1710
+ "hashAttribute": "id",
1711
+ "hashValue": "123"
1712
+ },
1713
+ "source": "experiment"
1714
+ }
1715
+ ],
1716
+ [
1717
+ "empty experiment rule - a",
1718
+ {
1719
+ "attributes": {
1720
+ "id": "456"
1721
+ },
1722
+ "features": {
1723
+ "feature": {
1724
+ "rules": [
1725
+ {
1726
+ "variations": ["a", "b", "c"]
1727
+ }
1728
+ ]
1729
+ }
1730
+ }
1731
+ },
1732
+ "feature",
1733
+ {
1734
+ "value": "a",
1735
+ "on": true,
1736
+ "off": false,
1737
+ "experiment": {
1738
+ "key": "feature",
1739
+ "variations": ["a", "b", "c"]
1740
+ },
1741
+ "experimentResult": {
1742
+ "value": "a",
1743
+ "variationId": 0,
1744
+ "inExperiment": true,
1745
+ "hashAttribute": "id",
1746
+ "hashValue": "456"
1747
+ },
1748
+ "source": "experiment"
1749
+ }
1750
+ ],
1751
+ [
1752
+ "empty experiment rule - b",
1753
+ {
1754
+ "attributes": {
1755
+ "id": "fds"
1756
+ },
1757
+ "features": {
1758
+ "feature": {
1759
+ "rules": [
1760
+ {
1761
+ "variations": ["a", "b", "c"]
1762
+ }
1763
+ ]
1764
+ }
1765
+ }
1766
+ },
1767
+ "feature",
1768
+ {
1769
+ "value": "b",
1770
+ "on": true,
1771
+ "off": false,
1772
+ "experiment": {
1773
+ "key": "feature",
1774
+ "variations": ["a", "b", "c"]
1775
+ },
1776
+ "experimentResult": {
1777
+ "value": "b",
1778
+ "variationId": 1,
1779
+ "inExperiment": true,
1780
+ "hashAttribute": "id",
1781
+ "hashValue": "fds"
1782
+ },
1783
+ "source": "experiment"
1784
+ }
1785
+ ],
1786
+ [
1787
+ "creates experiments properly",
1788
+ {
1789
+ "attributes": {
1790
+ "anonId": "123",
1791
+ "premium": true
1792
+ },
1793
+ "features": {
1794
+ "feature": {
1795
+ "rules": [
1796
+ {
1797
+ "coverage": 0.99,
1798
+ "hashAttribute": "anonId",
1799
+ "namespace": ["pricing", 0, 1],
1800
+ "key": "hello",
1801
+ "variations": [true, false],
1802
+ "weights": [0.1, 0.9],
1803
+ "condition": { "premium": true }
1804
+ }
1805
+ ]
1806
+ }
1807
+ }
1808
+ },
1809
+ "feature",
1810
+ {
1811
+ "value": false,
1812
+ "on": false,
1813
+ "off": true,
1814
+ "source": "experiment",
1815
+ "experiment": {
1816
+ "coverage": 0.99,
1817
+ "hashAttribute": "anonId",
1818
+ "namespace": ["pricing", 0, 1],
1819
+ "key": "hello",
1820
+ "variations": [true, false],
1821
+ "weights": [0.1, 0.9]
1822
+ },
1823
+ "experimentResult": {
1824
+ "value": false,
1825
+ "variationId": 1,
1826
+ "inExperiment": true,
1827
+ "hashAttribute": "anonId",
1828
+ "hashValue": "123"
1829
+ }
1830
+ }
1831
+ ],
1832
+ [
1833
+ "rule orders - skip 1",
1834
+ {
1835
+ "attributes": {
1836
+ "browser": "firefox"
1837
+ },
1838
+ "features": {
1839
+ "feature": {
1840
+ "defaultValue": 0,
1841
+ "rules": [
1842
+ {
1843
+ "force": 1,
1844
+ "condition": { "browser": "chrome" }
1845
+ },
1846
+ {
1847
+ "force": 2,
1848
+ "condition": { "browser": "firefox" }
1849
+ },
1850
+ {
1851
+ "force": 3,
1852
+ "condition": { "browser": "safari" }
1853
+ }
1854
+ ]
1855
+ }
1856
+ }
1857
+ },
1858
+ "feature",
1859
+ {
1860
+ "value": 2,
1861
+ "on": true,
1862
+ "off": false,
1863
+ "source": "force"
1864
+ }
1865
+ ],
1866
+ [
1867
+ "rule orders - skip 1,2",
1868
+ {
1869
+ "attributes": {
1870
+ "browser": "safari"
1871
+ },
1872
+ "features": {
1873
+ "feature": {
1874
+ "defaultValue": 0,
1875
+ "rules": [
1876
+ {
1877
+ "force": 1,
1878
+ "condition": { "browser": "chrome" }
1879
+ },
1880
+ {
1881
+ "force": 2,
1882
+ "condition": { "browser": "firefox" }
1883
+ },
1884
+ {
1885
+ "force": 3,
1886
+ "condition": { "browser": "safari" }
1887
+ }
1888
+ ]
1889
+ }
1890
+ }
1891
+ },
1892
+ "feature",
1893
+ {
1894
+ "value": 3,
1895
+ "on": true,
1896
+ "off": false,
1897
+ "source": "force"
1898
+ }
1899
+ ],
1900
+ [
1901
+ "rule orders - skip all",
1902
+ {
1903
+ "attributes": {
1904
+ "browser": "ie"
1905
+ },
1906
+ "features": {
1907
+ "feature": {
1908
+ "defaultValue": 0,
1909
+ "rules": [
1910
+ {
1911
+ "force": 1,
1912
+ "condition": { "browser": "chrome" }
1913
+ },
1914
+ {
1915
+ "force": 2,
1916
+ "condition": { "browser": "firefox" }
1917
+ },
1918
+ {
1919
+ "force": 3,
1920
+ "condition": { "browser": "safari" }
1921
+ }
1922
+ ]
1923
+ }
1924
+ }
1925
+ },
1926
+ "feature",
1927
+ {
1928
+ "value": 0,
1929
+ "on": false,
1930
+ "off": true,
1931
+ "source": "defaultValue"
1932
+ }
1933
+ ],
1934
+ [
1935
+ "skips experiment on coverage",
1936
+ {
1937
+ "attributes": { "id": "123" },
1938
+ "features": {
1939
+ "feature": {
1940
+ "defaultValue": 0,
1941
+ "rules": [
1942
+ {
1943
+ "variations": [0, 1, 2, 3],
1944
+ "coverage": 0.01
1945
+ },
1946
+ {
1947
+ "force": 3
1948
+ }
1949
+ ]
1950
+ }
1951
+ }
1952
+ },
1953
+ "feature",
1954
+ {
1955
+ "value": 3,
1956
+ "on": true,
1957
+ "off": false,
1958
+ "source": "force"
1959
+ }
1960
+ ],
1961
+ [
1962
+ "skips experiment on namespace",
1963
+ {
1964
+ "attributes": { "id": "123" },
1965
+ "features": {
1966
+ "feature": {
1967
+ "defaultValue": 0,
1968
+ "rules": [
1969
+ {
1970
+ "variations": [0, 1, 2, 3],
1971
+ "namespace": ["pricing", 0, 0.01]
1972
+ },
1973
+ {
1974
+ "force": 3
1975
+ }
1976
+ ]
1977
+ }
1978
+ }
1979
+ },
1980
+ "feature",
1981
+ {
1982
+ "value": 3,
1983
+ "on": true,
1984
+ "off": false,
1985
+ "source": "force"
1986
+ }
1987
+ ],
1988
+ [
1989
+ "skip experiment on missing hashAttribute",
1990
+ {
1991
+ "attributes": { "id": "123" },
1992
+ "features": {
1993
+ "feature": {
1994
+ "defaultValue": 0,
1995
+ "rules": [
1996
+ {
1997
+ "variations": [0, 1, 2, 3],
1998
+ "hashAttribute": "company"
1999
+ },
2000
+ {
2001
+ "force": 3
2002
+ }
2003
+ ]
2004
+ }
2005
+ }
2006
+ },
2007
+ "feature",
2008
+ {
2009
+ "value": 3,
2010
+ "on": true,
2011
+ "off": false,
2012
+ "source": "force"
2013
+ }
2014
+ ]
2015
+ ],
2016
+ "run": [
2017
+ [
2018
+ "default weights - 1",
2019
+ { "attributes": { "id": "1" } },
2020
+ { "key": "my-test", "variations": [0, 1] },
2021
+ 1,
2022
+ true
2023
+ ],
2024
+ [
2025
+ "default weights - 2",
2026
+ { "attributes": { "id": "2" } },
2027
+ { "key": "my-test", "variations": [0, 1] },
2028
+ 0,
2029
+ true
2030
+ ],
2031
+ [
2032
+ "default weights - 3",
2033
+ { "attributes": { "id": "3" } },
2034
+ { "key": "my-test", "variations": [0, 1] },
2035
+ 0,
2036
+ true
2037
+ ],
2038
+ [
2039
+ "default weights - 4",
2040
+ { "attributes": { "id": "4" } },
2041
+ { "key": "my-test", "variations": [0, 1] },
2042
+ 1,
2043
+ true
2044
+ ],
2045
+ [
2046
+ "default weights - 5",
2047
+ { "attributes": { "id": "5" } },
2048
+ { "key": "my-test", "variations": [0, 1] },
2049
+ 1,
2050
+ true
2051
+ ],
2052
+ [
2053
+ "default weights - 6",
2054
+ { "attributes": { "id": "6" } },
2055
+ { "key": "my-test", "variations": [0, 1] },
2056
+ 1,
2057
+ true
2058
+ ],
2059
+ [
2060
+ "default weights - 7",
2061
+ { "attributes": { "id": "7" } },
2062
+ { "key": "my-test", "variations": [0, 1] },
2063
+ 0,
2064
+ true
2065
+ ],
2066
+ [
2067
+ "default weights - 8",
2068
+ { "attributes": { "id": "8" } },
2069
+ { "key": "my-test", "variations": [0, 1] },
2070
+ 1,
2071
+ true
2072
+ ],
2073
+ [
2074
+ "default weights - 9",
2075
+ { "attributes": { "id": "9" } },
2076
+ { "key": "my-test", "variations": [0, 1] },
2077
+ 0,
2078
+ true
2079
+ ],
2080
+ [
2081
+ "uneven weights - 1",
2082
+ { "attributes": { "id": "1" } },
2083
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2084
+ 1,
2085
+ true
2086
+ ],
2087
+ [
2088
+ "uneven weights - 2",
2089
+ { "attributes": { "id": "2" } },
2090
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2091
+ 1,
2092
+ true
2093
+ ],
2094
+ [
2095
+ "uneven weights - 3",
2096
+ { "attributes": { "id": "3" } },
2097
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2098
+ 0,
2099
+ true
2100
+ ],
2101
+ [
2102
+ "uneven weights - 4",
2103
+ { "attributes": { "id": "4" } },
2104
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2105
+ 1,
2106
+ true
2107
+ ],
2108
+ [
2109
+ "uneven weights - 5",
2110
+ { "attributes": { "id": "5" } },
2111
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2112
+ 1,
2113
+ true
2114
+ ],
2115
+ [
2116
+ "uneven weights - 6",
2117
+ { "attributes": { "id": "6" } },
2118
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2119
+ 1,
2120
+ true
2121
+ ],
2122
+ [
2123
+ "uneven weights - 7",
2124
+ { "attributes": { "id": "7" } },
2125
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2126
+ 0,
2127
+ true
2128
+ ],
2129
+ [
2130
+ "uneven weights - 8",
2131
+ { "attributes": { "id": "8" } },
2132
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2133
+ 1,
2134
+ true
2135
+ ],
2136
+ [
2137
+ "uneven weights - 9",
2138
+ { "attributes": { "id": "9" } },
2139
+ { "key": "my-test", "variations": [0, 1], "weights": [0.1, 0.9] },
2140
+ 1,
2141
+ true
2142
+ ],
2143
+ [
2144
+ "coverage - 1",
2145
+ { "attributes": { "id": "1" } },
2146
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2147
+ 0,
2148
+ false
2149
+ ],
2150
+ [
2151
+ "coverage - 2",
2152
+ { "attributes": { "id": "2" } },
2153
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2154
+ 0,
2155
+ true
2156
+ ],
2157
+ [
2158
+ "coverage - 3",
2159
+ { "attributes": { "id": "3" } },
2160
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2161
+ 0,
2162
+ true
2163
+ ],
2164
+ [
2165
+ "coverage - 4",
2166
+ { "attributes": { "id": "4" } },
2167
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2168
+ 0,
2169
+ false
2170
+ ],
2171
+ [
2172
+ "coverage - 5",
2173
+ { "attributes": { "id": "5" } },
2174
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2175
+ 1,
2176
+ true
2177
+ ],
2178
+ [
2179
+ "coverage - 6",
2180
+ { "attributes": { "id": "6" } },
2181
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2182
+ 0,
2183
+ false
2184
+ ],
2185
+ [
2186
+ "coverage - 7",
2187
+ { "attributes": { "id": "7" } },
2188
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2189
+ 0,
2190
+ true
2191
+ ],
2192
+ [
2193
+ "coverage - 8",
2194
+ { "attributes": { "id": "8" } },
2195
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2196
+ 1,
2197
+ true
2198
+ ],
2199
+ [
2200
+ "coverage - 9",
2201
+ { "attributes": { "id": "9" } },
2202
+ { "key": "my-test", "variations": [0, 1], "coverage": 0.4 },
2203
+ 0,
2204
+ false
2205
+ ],
2206
+ [
2207
+ "three way test - 1",
2208
+ { "attributes": { "id": "1" } },
2209
+ { "key": "my-test", "variations": [0, 1, 2] },
2210
+ 2,
2211
+ true
2212
+ ],
2213
+ [
2214
+ "three way test - 2",
2215
+ { "attributes": { "id": "2" } },
2216
+ { "key": "my-test", "variations": [0, 1, 2] },
2217
+ 0,
2218
+ true
2219
+ ],
2220
+ [
2221
+ "three way test - 3",
2222
+ { "attributes": { "id": "3" } },
2223
+ { "key": "my-test", "variations": [0, 1, 2] },
2224
+ 0,
2225
+ true
2226
+ ],
2227
+ [
2228
+ "three way test - 4",
2229
+ { "attributes": { "id": "4" } },
2230
+ { "key": "my-test", "variations": [0, 1, 2] },
2231
+ 2,
2232
+ true
2233
+ ],
2234
+ [
2235
+ "three way test - 5",
2236
+ { "attributes": { "id": "5" } },
2237
+ { "key": "my-test", "variations": [0, 1, 2] },
2238
+ 1,
2239
+ true
2240
+ ],
2241
+ [
2242
+ "three way test - 6",
2243
+ { "attributes": { "id": "6" } },
2244
+ { "key": "my-test", "variations": [0, 1, 2] },
2245
+ 2,
2246
+ true
2247
+ ],
2248
+ [
2249
+ "three way test - 7",
2250
+ { "attributes": { "id": "7" } },
2251
+ { "key": "my-test", "variations": [0, 1, 2] },
2252
+ 0,
2253
+ true
2254
+ ],
2255
+ [
2256
+ "three way test - 8",
2257
+ { "attributes": { "id": "8" } },
2258
+ { "key": "my-test", "variations": [0, 1, 2] },
2259
+ 1,
2260
+ true
2261
+ ],
2262
+ [
2263
+ "three way test - 9",
2264
+ { "attributes": { "id": "9" } },
2265
+ { "key": "my-test", "variations": [0, 1, 2] },
2266
+ 0,
2267
+ true
2268
+ ],
2269
+ [
2270
+ "test name - my-test",
2271
+ { "attributes": { "id": "1" } },
2272
+ { "key": "my-test", "variations": [0, 1] },
2273
+ 1,
2274
+ true
2275
+ ],
2276
+ [
2277
+ "test name - my-test-3",
2278
+ { "attributes": { "id": "1" } },
2279
+ { "key": "my-test-3", "variations": [0, 1] },
2280
+ 0,
2281
+ true
2282
+ ],
2283
+ [
2284
+ "empty id",
2285
+ { "attributes": { "id": "" } },
2286
+ { "key": "my-test", "variations": [0, 1] },
2287
+ 0,
2288
+ false
2289
+ ],
2290
+ [
2291
+ "missing id",
2292
+ { "attributes": {} },
2293
+ { "key": "my-test", "variations": [0, 1] },
2294
+ 0,
2295
+ false
2296
+ ],
2297
+ [
2298
+ "missing attributes",
2299
+ {},
2300
+ { "key": "my-test", "variations": [0, 1] },
2301
+ 0,
2302
+ false
2303
+ ],
2304
+ [
2305
+ "single variation",
2306
+ { "attributes": { "id": "1" } },
2307
+ { "key": "my-test", "variations": [0] },
2308
+ 0,
2309
+ false
2310
+ ],
2311
+ [
2312
+ "negative forced variation",
2313
+ { "attributes": { "id": "1" } },
2314
+ { "key": "my-test", "variations": [0, 1], "force": -8 },
2315
+ 0,
2316
+ false
2317
+ ],
2318
+ [
2319
+ "high forced variation",
2320
+ { "attributes": { "id": "1" } },
2321
+ { "key": "my-test", "variations": [0, 1], "force": 25 },
2322
+ 0,
2323
+ false
2324
+ ],
2325
+ [
2326
+ "evaluates conditions - pass",
2327
+ {
2328
+ "attributes": {
2329
+ "id": "1",
2330
+ "browser": "firefox"
2331
+ }
2332
+ },
2333
+ {
2334
+ "key": "my-test",
2335
+ "variations": [0, 1],
2336
+ "condition": {
2337
+ "browser": "firefox"
2338
+ }
2339
+ },
2340
+ 1,
2341
+ true
2342
+ ],
2343
+ [
2344
+ "evaluates conditions - fail",
2345
+ {
2346
+ "attributes": {
2347
+ "id": "1",
2348
+ "browser": "chrome"
2349
+ }
2350
+ },
2351
+ {
2352
+ "key": "my-test",
2353
+ "variations": [0, 1],
2354
+ "condition": {
2355
+ "browser": "firefox"
2356
+ }
2357
+ },
2358
+ 0,
2359
+ false
2360
+ ],
2361
+ [
2362
+ "custom hashAttribute",
2363
+ {
2364
+ "attributes": {
2365
+ "id": "2",
2366
+ "companyId": "1"
2367
+ }
2368
+ },
2369
+ {
2370
+ "key": "my-test",
2371
+ "variations": [0, 1],
2372
+ "hashAttribute": "companyId"
2373
+ },
2374
+ 1,
2375
+ true
2376
+ ],
2377
+ [
2378
+ "globally disabled",
2379
+ {
2380
+ "attributes": {
2381
+ "id": "1"
2382
+ },
2383
+ "enabled": false
2384
+ },
2385
+ {
2386
+ "key": "my-test",
2387
+ "variations": [0, 1]
2388
+ },
2389
+ 0,
2390
+ false
2391
+ ],
2392
+ [
2393
+ "querystring force",
2394
+ {
2395
+ "attributes": {
2396
+ "id": "1"
2397
+ },
2398
+ "url": "http://example.com?forced-test-qs=1#someanchor"
2399
+ },
2400
+ {
2401
+ "key": "forced-test-qs",
2402
+ "variations": [0, 1]
2403
+ },
2404
+ 1,
2405
+ false
2406
+ ],
2407
+ [
2408
+ "run active experiments",
2409
+ {
2410
+ "attributes": {
2411
+ "id": "1"
2412
+ }
2413
+ },
2414
+ {
2415
+ "key": "my-test",
2416
+ "active": true,
2417
+ "variations": [0, 1]
2418
+ },
2419
+ 1,
2420
+ true
2421
+ ],
2422
+ [
2423
+ "skip inactive experiments",
2424
+ {
2425
+ "attributes": {
2426
+ "id": "1"
2427
+ }
2428
+ },
2429
+ {
2430
+ "key": "my-test",
2431
+ "active": false,
2432
+ "variations": [0, 1]
2433
+ },
2434
+ 0,
2435
+ false
2436
+ ],
2437
+ [
2438
+ "querystring force with inactive",
2439
+ {
2440
+ "attributes": {
2441
+ "id": "1"
2442
+ },
2443
+ "url": "http://example.com/?my-test=1"
2444
+ },
2445
+ {
2446
+ "key": "my-test",
2447
+ "active": false,
2448
+ "variations": [0, 1]
2449
+ },
2450
+ 1,
2451
+ false
2452
+ ],
2453
+ [
2454
+ "coverage take precendence over forced",
2455
+ {
2456
+ "attributes": {
2457
+ "id": "1"
2458
+ }
2459
+ },
2460
+ {
2461
+ "key": "my-test",
2462
+ "force": 1,
2463
+ "coverage": 0.01,
2464
+ "variations": [0, 1]
2465
+ },
2466
+ 0,
2467
+ false
2468
+ ],
2469
+ [
2470
+ "JSON values for experiments",
2471
+ {
2472
+ "attributes": {
2473
+ "id": "1"
2474
+ }
2475
+ },
2476
+ {
2477
+ "key": "my-test",
2478
+ "variations": [
2479
+ {
2480
+ "color": "blue",
2481
+ "size": "small"
2482
+ },
2483
+ {
2484
+ "color": "green",
2485
+ "size": "large"
2486
+ }
2487
+ ]
2488
+ },
2489
+ {
2490
+ "color": "green",
2491
+ "size": "large"
2492
+ },
2493
+ true
2494
+ ],
2495
+ [
2496
+ "Force variation from context",
2497
+ {
2498
+ "attributes": { "id": "1" },
2499
+ "forcedVariations": { "my-test": 0 }
2500
+ },
2501
+ {
2502
+ "key": "my-test",
2503
+ "variations": [0, 1]
2504
+ },
2505
+ 0,
2506
+ false
2507
+ ],
2508
+ [
2509
+ "Skips experiments in QA mode",
2510
+ {
2511
+ "attributes": { "id": "1" },
2512
+ "qaMode": true
2513
+ },
2514
+ {
2515
+ "key": "my-test",
2516
+ "variations": [0, 1]
2517
+ },
2518
+ 0,
2519
+ false
2520
+ ],
2521
+ [
2522
+ "Works in QA mode if forced in context",
2523
+ {
2524
+ "attributes": { "id": "1" },
2525
+ "qaMode": true,
2526
+ "forcedVariations": { "my-test": 1 }
2527
+ },
2528
+ {
2529
+ "key": "my-test",
2530
+ "variations": [0, 1]
2531
+ },
2532
+ 1,
2533
+ false
2534
+ ],
2535
+ [
2536
+ "Works in QA mode if forced in experiment",
2537
+ {
2538
+ "attributes": { "id": "1" },
2539
+ "qaMode": true
2540
+ },
2541
+ {
2542
+ "key": "my-test",
2543
+ "variations": [0, 1],
2544
+ "force": 1
2545
+ },
2546
+ 1,
2547
+ false
2548
+ ],
2549
+ [
2550
+ "Experiment namespace - pass",
2551
+ {
2552
+ "attributes": {
2553
+ "id": "1"
2554
+ }
2555
+ },
2556
+ {
2557
+ "key": "my-test",
2558
+ "variations": [0, 1],
2559
+ "namespace": ["namespace", 0.1, 1]
2560
+ },
2561
+ 1,
2562
+ true
2563
+ ],
2564
+ [
2565
+ "Experiment namespace - fail",
2566
+ {
2567
+ "attributes": {
2568
+ "id": "1"
2569
+ }
2570
+ },
2571
+ {
2572
+ "key": "my-test",
2573
+ "variations": [0, 1],
2574
+ "namespace": ["namespace", 0, 0.1]
2575
+ },
2576
+ 0,
2577
+ false
2578
+ ]
2579
+ ],
2580
+ "chooseVariation": [
2581
+ [
2582
+ "even range, 0.2",
2583
+ 0.2,
2584
+ [
2585
+ [0, 0.5],
2586
+ [0.5, 1]
2587
+ ],
2588
+ 0
2589
+ ],
2590
+ [
2591
+ "even range, 0.4",
2592
+ 0.4,
2593
+ [
2594
+ [0, 0.5],
2595
+ [0.5, 1]
2596
+ ],
2597
+ 0
2598
+ ],
2599
+ [
2600
+ "even range, 0.6",
2601
+ 0.6,
2602
+ [
2603
+ [0, 0.5],
2604
+ [0.5, 1]
2605
+ ],
2606
+ 1
2607
+ ],
2608
+ [
2609
+ "even range, 0.8",
2610
+ 0.8,
2611
+ [
2612
+ [0, 0.5],
2613
+ [0.5, 1]
2614
+ ],
2615
+ 1
2616
+ ],
2617
+ [
2618
+ "even range, 0",
2619
+ 0,
2620
+ [
2621
+ [0, 0.5],
2622
+ [0.5, 1]
2623
+ ],
2624
+ 0
2625
+ ],
2626
+ [
2627
+ "even range, 0.5",
2628
+ 0.5,
2629
+ [
2630
+ [0, 0.5],
2631
+ [0.5, 1]
2632
+ ],
2633
+ 1
2634
+ ],
2635
+ [
2636
+ "reduced range, 0.2",
2637
+ 0.2,
2638
+ [
2639
+ [0, 0.25],
2640
+ [0.5, 0.75]
2641
+ ],
2642
+ 0
2643
+ ],
2644
+ [
2645
+ "reduced range, 0.4",
2646
+ 0.4,
2647
+ [
2648
+ [0, 0.25],
2649
+ [0.5, 0.75]
2650
+ ],
2651
+ -1
2652
+ ],
2653
+ [
2654
+ "reduced range, 0.6",
2655
+ 0.6,
2656
+ [
2657
+ [0, 0.25],
2658
+ [0.5, 0.75]
2659
+ ],
2660
+ 1
2661
+ ],
2662
+ [
2663
+ "reduced range, 0.8",
2664
+ 0.8,
2665
+ [
2666
+ [0, 0.25],
2667
+ [0.5, 0.75]
2668
+ ],
2669
+ -1
2670
+ ],
2671
+ [
2672
+ "reduced range, 0.25",
2673
+ 0.25,
2674
+ [
2675
+ [0, 0.25],
2676
+ [0.5, 0.75]
2677
+ ],
2678
+ -1
2679
+ ],
2680
+ [
2681
+ "reduced range, 0.5",
2682
+ 0.5,
2683
+ [
2684
+ [0, 0.25],
2685
+ [0.5, 0.75]
2686
+ ],
2687
+ 1
2688
+ ],
2689
+ [
2690
+ "zero range",
2691
+ 0.5,
2692
+ [
2693
+ [0, 0.5],
2694
+ [0.5, 0.5],
2695
+ [0.5, 1]
2696
+ ],
2697
+ 2
2698
+ ]
2699
+ ],
2700
+ "getQueryStringOverride": [
2701
+ ["empty url", "my-test", "", 2, null],
2702
+ ["no query string", "my-test", "http://example.com", 2, null],
2703
+ ["empty query string", "my-test", "http://example.com?", 2, null],
2704
+ [
2705
+ "no query string match",
2706
+ "my-test",
2707
+ "http://example.com?somequery",
2708
+ 2,
2709
+ null
2710
+ ],
2711
+ ["invalid query string", "my-test", "http://example.com??&&&?#", 2, null],
2712
+ ["simple match 0", "my-test", "http://example.com?my-test=0", 2, 0],
2713
+ ["simple match 1", "my-test", "http://example.com?my-test=1", 2, 1],
2714
+ ["negative variation", "my-test", "http://example.com?my-test=-1", 2, null],
2715
+ ["float", "my-test", "http://example.com?my-test=2.054", 2, null],
2716
+ ["string", "my-test", "http://example.com?my-test=foo", 2, null],
2717
+ ["variation too high", "my-test", "http://example.com?my-test=5", 2, null],
2718
+ ["high numVariations", "my-test", "http://example.com?my-test=5", 6, 5],
2719
+ [
2720
+ "equal to numVariations",
2721
+ "my-test",
2722
+ "http://example.com?my-test=5",
2723
+ 5,
2724
+ null
2725
+ ],
2726
+ [
2727
+ "other query string before",
2728
+ "my-test",
2729
+ "http://example.com?foo=bar&my-test=1",
2730
+ 2,
2731
+ 1
2732
+ ],
2733
+ [
2734
+ "other query string after",
2735
+ "my-test",
2736
+ "http://example.com?foo=bar&my-test=1&bar=baz",
2737
+ 2,
2738
+ 1
2739
+ ],
2740
+ ["anchor", "my-test", "http://example.com?my-test=1#foo", 2, 1]
2741
+ ],
2742
+ "inNamespace": [
2743
+ ["user 1, namespace1, 1", "1", ["namespace1", 0, 0.4], false],
2744
+ ["user 1, namespace1, 2", "1", ["namespace1", 0.4, 1], true],
2745
+ ["user 1, namespace2, 1", "1", ["namespace2", 0, 0.4], false],
2746
+ ["user 1, namespace2, 2", "1", ["namespace2", 0.4, 1], true],
2747
+ ["user 2, namespace1, 1", "2", ["namespace1", 0, 0.4], false],
2748
+ ["user 2, namespace1, 2", "2", ["namespace1", 0.4, 1], true],
2749
+ ["user 2, namespace2, 1", "2", ["namespace2", 0, 0.4], false],
2750
+ ["user 2, namespace2, 2", "2", ["namespace2", 0.4, 1], true],
2751
+ ["user 3, namespace1, 1", "3", ["namespace1", 0, 0.4], false],
2752
+ ["user 3, namespace1, 2", "3", ["namespace1", 0.4, 1], true],
2753
+ ["user 3, namespace2, 1", "3", ["namespace2", 0, 0.4], true],
2754
+ ["user 3, namespace2, 2", "3", ["namespace2", 0.4, 1], false],
2755
+ ["user 4, namespace1, 1", "4", ["namespace1", 0, 0.4], false],
2756
+ ["user 4, namespace1, 2", "4", ["namespace1", 0.4, 1], true],
2757
+ ["user 4, namespace2, 1", "4", ["namespace2", 0, 0.4], true],
2758
+ ["user 4, namespace2, 2", "4", ["namespace2", 0.4, 1], false]
2759
+ ],
2760
+ "getEqualWeights": [
2761
+ [-1, []],
2762
+ [0, []],
2763
+ [1, [1]],
2764
+ [2, [0.5, 0.5]],
2765
+ [3, [0.33333333, 0.33333333, 0.33333333]],
2766
+ [4, [0.25, 0.25, 0.25, 0.25]]
2767
+ ]
2768
+ }