growthbook 0.0.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }