scientist 1.4.0 → 1.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49ab4f74d43836220fbadd4692445a3cc61a13387cf87f533f39db9c58ba8544
4
- data.tar.gz: d1648b2e74411130e36ddcac2f9e9bece7c7db3d65ca37deb1d7d6cf7a28096e
3
+ metadata.gz: c2831c4fc4f76eb1e8e822a21e613a07e33229bdfe47528cd4555b72ecb05a7c
4
+ data.tar.gz: e0e003dbbe7ecb82749c41aff85ff6b4174e6169dce34081d20f325f62959f8d
5
5
  SHA512:
6
- metadata.gz: 67f99e2906499d736c4ab002273d0bf9dbea07a3413b387c12a239afbdc65a542d658f7f1d087cdf482a261698e02c439ecb673a73a6497ca2ce4e07940e1a25
7
- data.tar.gz: 60479759bc916ae2b0d1c1b9bf575de872fbb5adfda098ee6fea4802384ceeed30caee4973583e751de9c5b3dce686acc1602aa7f6fade034d22b4f3ae5e7180
6
+ metadata.gz: 07f99bcd0d9619205f42f15f16cc00b31fff3fab127344ca70360c51eea28d3eb15bc21e9471edbccfb06ddf2f07bc93ac0024af3899371486757fb53dbb5710
7
+ data.tar.gz: cb7a3cf609e501a5d4a7894cf62400dacde1dc654ec7caf5d9beb8d115bb4f0c1e217cdeddd7c72863385459bfd7bb929221df74725312c3dfe21af315598486
data/README.md CHANGED
@@ -26,7 +26,7 @@ Wrap a `use` block around the code's original behavior, and wrap `try` around th
26
26
  * Randomizes the order in which `use` and `try` blocks are run,
27
27
  * Measures the durations of all behaviors,
28
28
  * Compares the result of `try` to the result of `use`,
29
- * Swallows (but records) any exceptions raised in the `try` block, and
29
+ * Swallow and record exceptions raised in the `try` block when overriding `raised`, and
30
30
  * Publishes all this information.
31
31
 
32
32
  The `use` block is called the **control**. The `try` block is called the **candidate**.
@@ -62,7 +62,7 @@ class MyExperiment
62
62
 
63
63
  attr_accessor :name
64
64
 
65
- def initialize(name:)
65
+ def initialize(name)
66
66
  @name = name
67
67
  end
68
68
 
@@ -71,18 +71,17 @@ class MyExperiment
71
71
  true
72
72
  end
73
73
 
74
+ def raised(operation, error)
75
+ # see "In a Scientist callback" below
76
+ p "Operation '#{operation}' failed with error '#{error.inspect}'"
77
+ super # will re-raise
78
+ end
79
+
74
80
  def publish(result)
75
81
  # see "Publishing results" below
76
82
  p result
77
83
  end
78
84
  end
79
-
80
- # replace `Scientist::Default` as the default implementation
81
- module Scientist::Experiment
82
- def self.new(name)
83
- MyExperiment.new(name: name)
84
- end
85
- end
86
85
  ```
87
86
 
88
87
  Now calls to the `science` helper will load instances of `MyExperiment`.
@@ -256,7 +255,7 @@ class MyExperiment
256
255
 
257
256
  attr_accessor :name, :percent_enabled
258
257
 
259
- def initialize(name:)
258
+ def initialize(name)
260
259
  @name = name
261
260
  @percent_enabled = 100
262
261
  end
@@ -537,6 +536,8 @@ Be on a Unixy box. Make sure a modern Bundler is available. `script/test` runs t
537
536
  - [tomiaijo/scientist](https://github.com/tomiaijo/scientist) (C++)
538
537
  - [trello/scientist](https://github.com/trello/scientist) (node.js)
539
538
  - [ziyasal/scientist.js](https://github.com/ziyasal/scientist.js) (node.js, ES6)
539
+ - [TrueWill/tzientist](https://github.com/TrueWill/tzientist) (node.js, TypeScript)
540
+ - [TrueWill/paleontologist](https://github.com/TrueWill/paleontologist) (Deno, TypeScript)
540
541
  - [yeller/laboratory](https://github.com/yeller/laboratory) (Clojure)
541
542
  - [lancew/Scientist](https://github.com/lancew/Scientist) (Perl 5)
542
543
  - [lancew/ScientistP6](https://github.com/lancew/ScientistP6) (Perl 6)
@@ -546,6 +547,7 @@ Be on a Unixy box. Make sure a modern Bundler is available. `script/test` runs t
546
547
  - [jelmersnoeck/experiment](https://github.com/jelmersnoeck/experiment) (Go)
547
548
  - [spoptchev/scientist](https://github.com/spoptchev/scientist) (Kotlin / Java)
548
549
  - [junkpiano/scientist](https://github.com/junkpiano/scientist) (Swift)
550
+ - [serverless scientist](http://serverlessscientist.com/) (AWS Lambda)
549
551
 
550
552
  ## Maintainers
551
553
 
@@ -9,12 +9,22 @@ module Scientist::Experiment
9
9
  # If this is nil, raise_on_mismatches class attribute is used instead.
10
10
  attr_accessor :raise_on_mismatches
11
11
 
12
- # Create a new instance of a class that implements the Scientist::Experiment
13
- # interface.
14
- #
15
- # Override this method directly to change the default implementation.
12
+ def self.included(base)
13
+ self.set_default(base)
14
+ base.extend RaiseOnMismatch
15
+ end
16
+
17
+ # Instantiate a new experiment (using the class given to the .set_default method).
16
18
  def self.new(name)
17
- Scientist::Default.new(name)
19
+ (@experiment_klass || Scientist::Default).new(name)
20
+ end
21
+
22
+ # Configure Scientist to use the given class for all future experiments
23
+ # (must implement the Scientist::Experiment interface).
24
+ #
25
+ # Called automatically when new experiments are defined.
26
+ def self.set_default(klass)
27
+ @experiment_klass = klass
18
28
  end
19
29
 
20
30
  # A mismatch, raised when raise_on_mismatches is enabled.
@@ -67,10 +77,6 @@ module Scientist::Experiment
67
77
  end
68
78
  end
69
79
 
70
- def self.included(base)
71
- base.extend RaiseOnMismatch
72
- end
73
-
74
80
  # Define a block of code to run before an experiment begins, if the experiment
75
81
  # is enabled.
76
82
  #
@@ -216,17 +222,7 @@ module Scientist::Experiment
216
222
  @_scientist_before_run.call
217
223
  end
218
224
 
219
- observations = []
220
-
221
- behaviors.keys.shuffle.each do |key|
222
- block = behaviors[key]
223
- fabricated_duration = @_scientist_fabricated_durations && @_scientist_fabricated_durations[key]
224
- observations << Scientist::Observation.new(key, self, fabricated_duration: fabricated_duration, &block)
225
- end
226
-
227
- control = observations.detect { |o| o.name == name }
228
-
229
- result = Scientist::Result.new self, observations, control
225
+ result = generate_result(name)
230
226
 
231
227
  begin
232
228
  publish(result)
@@ -242,11 +238,9 @@ module Scientist::Experiment
242
238
  end
243
239
  end
244
240
 
245
- if control.raised?
246
- raise control.exception
247
- else
248
- control.value
249
- end
241
+ control = result.control
242
+ raise control.exception if control.raised?
243
+ control.value
250
244
  end
251
245
 
252
246
  # Define a block that determines whether or not the experiment should run.
@@ -304,4 +298,18 @@ module Scientist::Experiment
304
298
  def fabricate_durations_for_testing_purposes(fabricated_durations = {})
305
299
  @_scientist_fabricated_durations = fabricated_durations
306
300
  end
301
+
302
+ # Internal: Generate the observations and create the result from those and the control.
303
+ def generate_result(name)
304
+ observations = []
305
+
306
+ behaviors.keys.shuffle.each do |key|
307
+ block = behaviors[key]
308
+ fabricated_duration = @_scientist_fabricated_durations && @_scientist_fabricated_durations[key]
309
+ observations << Scientist::Observation.new(key, self, fabricated_duration: fabricated_duration, &block)
310
+ end
311
+
312
+ control = observations.detect { |o| o.name == name }
313
+ Scientist::Result.new(self, observations, control)
314
+ end
307
315
  end
@@ -8,9 +8,6 @@ class Scientist::Observation
8
8
  # The experiment this observation is for
9
9
  attr_reader :experiment
10
10
 
11
- # The instant observation began.
12
- attr_reader :now
13
-
14
11
  # The String name of the behavior.
15
12
  attr_reader :name
16
13
 
@@ -26,7 +23,6 @@ class Scientist::Observation
26
23
  def initialize(name, experiment, fabricated_duration: nil, &block)
27
24
  @name = name
28
25
  @experiment = experiment
29
- @now = Time.now
30
26
 
31
27
  starting = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second) unless fabricated_duration
32
28
  begin
@@ -1,3 +1,3 @@
1
1
  module Scientist
2
- VERSION = "1.4.0"
2
+ VERSION = "1.5.0"
3
3
  end
@@ -2,6 +2,9 @@ describe Scientist::Experiment do
2
2
  class Fake
3
3
  include Scientist::Experiment
4
4
 
5
+ # Undo auto-config magic / preserve default behavior of Scientist::Experiment.new
6
+ Scientist::Experiment.set_default(nil)
7
+
5
8
  def initialize(*args)
6
9
  end
7
10
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scientist
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
@@ -9,10 +9,10 @@ authors:
9
9
  - Rick Bradley
10
10
  - Jesse Toth
11
11
  - Nathan Witmer
12
- autorequire:
12
+ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2019-09-20 00:00:00.000000000 Z
15
+ date: 2020-09-08 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: minitest
@@ -80,7 +80,7 @@ homepage: https://github.com/github/scientist
80
80
  licenses:
81
81
  - MIT
82
82
  metadata: {}
83
- post_install_message:
83
+ post_install_message:
84
84
  rdoc_options: []
85
85
  require_paths:
86
86
  - lib
@@ -95,8 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  requirements: []
98
- rubygems_version: 3.0.3
99
- signing_key:
98
+ rubygems_version: 3.1.2
99
+ signing_key:
100
100
  specification_version: 4
101
101
  summary: Carefully test, measure, and track refactored code.
102
102
  test_files: