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