scientist 0.0.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/README.md +16 -12
- data/lib/scientist/experiment.rb +14 -1
- data/lib/scientist/version.rb +1 -1
- data/scientist.gemspec +3 -3
- data/test/scientist/experiment_test.rb +33 -2
- metadata +12 -8
- data/CLA.md +0 -54
- data/CONTRIBUTING.md +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0c4363232ca282aeab9af989a6499a4aaa8eea8
|
4
|
+
data.tar.gz: 781901ba02fe3c35bc0ab79ed9a969998834a92a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d27e2fc8dc16c73253dcf66f22c21c73a589cdfd6f8cbf88337f88f8ae6cd40fa047e701c16440f20eca36aa644ca940fe6f321269a62d5e0808fb3e79bc43f
|
7
|
+
data.tar.gz: 063961175f72b277982ce4eb1bd9060a65a902a75c4a4735689202030534fe0fedeede28e6e67815c8d7e8a69af7bd979c7fcb41758790683045a73da21d90de
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
A Ruby library for carefully refactoring critical paths. [![Build Status](https://travis-ci.org/github/scientist.svg?branch=master)](https://travis-ci.org/github/scientist)
|
4
4
|
|
5
|
-
## How do I
|
5
|
+
## How do I science?
|
6
6
|
|
7
7
|
Let's pretend you're changing the way you handle permissions in a large web app. Tests can help guide your refactoring, but you really want to compare the current and refactored behaviors under load.
|
8
8
|
|
@@ -11,10 +11,9 @@ require "scientist"
|
|
11
11
|
|
12
12
|
class MyWidget
|
13
13
|
def allows?(user)
|
14
|
-
experiment = Scientist::Default.new "widget-permissions"
|
15
|
-
|
16
|
-
|
17
|
-
end
|
14
|
+
experiment = Scientist::Default.new "widget-permissions"
|
15
|
+
experiment.use { model.check_user?(user).valid? } # old way
|
16
|
+
experiment.try { user.can?(:read, model) } # new way
|
18
17
|
|
19
18
|
experiment.run
|
20
19
|
end
|
@@ -58,9 +57,12 @@ The examples above will run, but they're not really *doing* anything. The `try`
|
|
58
57
|
```ruby
|
59
58
|
require "scientist"
|
60
59
|
|
61
|
-
class MyExperiment
|
60
|
+
class MyExperiment
|
61
|
+
include ActiveModel::Model
|
62
62
|
include Scientist::Experiment
|
63
63
|
|
64
|
+
attr_accessor :name
|
65
|
+
|
64
66
|
def enabled?
|
65
67
|
# see "Ramping up experiments" below
|
66
68
|
super
|
@@ -73,8 +75,10 @@ class MyExperiment < ActiveRecord::Base
|
|
73
75
|
end
|
74
76
|
|
75
77
|
# replace `Scientist::Default` as the default implementation
|
76
|
-
|
77
|
-
|
78
|
+
module Scientist::Experiment
|
79
|
+
def self.new(name)
|
80
|
+
MyExperiment.new(name: name)
|
81
|
+
end
|
78
82
|
end
|
79
83
|
```
|
80
84
|
|
@@ -289,8 +293,8 @@ class MyExperiment
|
|
289
293
|
:name => name,
|
290
294
|
:context => context,
|
291
295
|
:control => observation_payload(result.control),
|
292
|
-
:candidate => observation_payload(result.candidates.first)
|
293
|
-
:execution_order => result.observations.map(&:name)
|
296
|
+
:candidate => observation_payload(result.candidates.first),
|
297
|
+
:execution_order => result.observations.map(&:name)
|
294
298
|
}
|
295
299
|
|
296
300
|
key = "science.#{name}.mismatch"
|
@@ -301,8 +305,8 @@ class MyExperiment
|
|
301
305
|
def observation_payload(observation)
|
302
306
|
if observation.raised?
|
303
307
|
{
|
304
|
-
:exception => observation.
|
305
|
-
:message => observation.
|
308
|
+
:exception => observation.exception.class,
|
309
|
+
:message => observation.exception.message,
|
306
310
|
:backtrace => observation.exception.backtrace
|
307
311
|
}
|
308
312
|
else
|
data/lib/scientist/experiment.rb
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
# implements Scientist::Experiment's interface.
|
6
6
|
module Scientist::Experiment
|
7
7
|
|
8
|
+
# Whether to raise when the control and candidate mismatch.
|
9
|
+
# If this is nil, raise_on_mismatches class attribute is used instead.
|
10
|
+
attr_accessor :raise_on_mismatches
|
11
|
+
|
8
12
|
# Create a new instance of a class that implements the Scientist::Experiment
|
9
13
|
# interface.
|
10
14
|
#
|
@@ -218,7 +222,7 @@ module Scientist::Experiment
|
|
218
222
|
raised :publish, ex
|
219
223
|
end
|
220
224
|
|
221
|
-
if
|
225
|
+
if raise_on_mismatches? && result.mismatched?
|
222
226
|
raise MismatchError.new(self.name, result)
|
223
227
|
end
|
224
228
|
|
@@ -269,4 +273,13 @@ module Scientist::Experiment
|
|
269
273
|
def use(&block)
|
270
274
|
try "control", &block
|
271
275
|
end
|
276
|
+
|
277
|
+
# Whether or not to raise a mismatch error when a mismatch occurs.
|
278
|
+
def raise_on_mismatches?
|
279
|
+
if raise_on_mismatches.nil?
|
280
|
+
self.class.raise_on_mismatches?
|
281
|
+
else
|
282
|
+
!!raise_on_mismatches
|
283
|
+
end
|
284
|
+
end
|
272
285
|
end
|
data/lib/scientist/version.rb
CHANGED
data/scientist.gemspec
CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |gem|
|
|
4
4
|
gem.name = "scientist"
|
5
5
|
gem.description = "A Ruby library for carefully refactoring critical paths"
|
6
6
|
gem.version = Scientist::VERSION
|
7
|
-
gem.authors = ["John Barnette", "Rick Bradley"]
|
8
|
-
gem.email = ["jbarnette@github.com", "rick@github.com"]
|
7
|
+
gem.authors = ["GitHub Open Source", "John Barnette", "Rick Bradley", "Jesse Toth", "Nathan Witmer"]
|
8
|
+
gem.email = ["opensource+scientist@github.com", "jbarnette@github.com", "rick@rickbradley.com", "jesseplusplus@github.com","zerowidth@github.com"]
|
9
9
|
gem.summary = "Carefully test, measure, and track refactored code."
|
10
10
|
gem.homepage = "https://github.com/github/scientist"
|
11
11
|
gem.license = "MIT"
|
@@ -15,5 +15,5 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.test_files = gem.files.grep(/^test/)
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
|
18
|
-
gem.add_development_dependency "minitest", "~> 5.
|
18
|
+
gem.add_development_dependency "minitest", "~> 5.8"
|
19
19
|
end
|
@@ -399,8 +399,7 @@ describe Scientist::Experiment do
|
|
399
399
|
Fake.raise_on_mismatches = true
|
400
400
|
@ex.use { raise "control" }
|
401
401
|
@ex.try { "candidate" }
|
402
|
-
|
403
|
-
@ex.run
|
402
|
+
assert_raises(Scientist::Experiment::MismatchError) { @ex.run }
|
404
403
|
end
|
405
404
|
|
406
405
|
it "raises a mismatch error if the candidate raises and the control doesn't" do
|
@@ -410,6 +409,38 @@ describe Scientist::Experiment do
|
|
410
409
|
assert_raises(Scientist::Experiment::MismatchError) { @ex.run }
|
411
410
|
end
|
412
411
|
|
412
|
+
describe "#raise_on_mismatches?" do
|
413
|
+
it "raises when there is a mismatch if the experiment instance's raise on mismatches is enabled" do
|
414
|
+
Fake.raise_on_mismatches = false
|
415
|
+
@ex.raise_on_mismatches = true
|
416
|
+
@ex.use { "fine" }
|
417
|
+
@ex.try { "not fine" }
|
418
|
+
|
419
|
+
assert_raises(Scientist::Experiment::MismatchError) { @ex.run }
|
420
|
+
end
|
421
|
+
|
422
|
+
it "doesn't raise when there is a mismatch if the experiment instance's raise on mismatches is disabled" do
|
423
|
+
Fake.raise_on_mismatches = true
|
424
|
+
@ex.raise_on_mismatches = false
|
425
|
+
@ex.use { "fine" }
|
426
|
+
@ex.try { "not fine" }
|
427
|
+
|
428
|
+
assert_equal "fine", @ex.run
|
429
|
+
end
|
430
|
+
|
431
|
+
it "respects the raise_on_mismatches class attribute by default" do
|
432
|
+
Fake.raise_on_mismatches = false
|
433
|
+
@ex.use { "fine" }
|
434
|
+
@ex.try { "not fine" }
|
435
|
+
|
436
|
+
assert_equal "fine", @ex.run
|
437
|
+
|
438
|
+
Fake.raise_on_mismatches = true
|
439
|
+
|
440
|
+
assert_raises(Scientist::Experiment::MismatchError) { @ex.run }
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
413
444
|
describe "MismatchError" do
|
414
445
|
before do
|
415
446
|
Fake.raise_on_mismatches = true
|
metadata
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scientist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
+
- GitHub Open Source
|
7
8
|
- John Barnette
|
8
9
|
- Rick Bradley
|
10
|
+
- Jesse Toth
|
11
|
+
- Nathan Witmer
|
9
12
|
autorequire:
|
10
13
|
bindir: bin
|
11
14
|
cert_chain: []
|
12
|
-
date:
|
15
|
+
date: 2016-02-03 00:00:00.000000000 Z
|
13
16
|
dependencies:
|
14
17
|
- !ruby/object:Gem::Dependency
|
15
18
|
name: minitest
|
@@ -17,26 +20,27 @@ dependencies:
|
|
17
20
|
requirements:
|
18
21
|
- - "~>"
|
19
22
|
- !ruby/object:Gem::Version
|
20
|
-
version: '5.
|
23
|
+
version: '5.8'
|
21
24
|
type: :development
|
22
25
|
prerelease: false
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
25
28
|
- - "~>"
|
26
29
|
- !ruby/object:Gem::Version
|
27
|
-
version: '5.
|
30
|
+
version: '5.8'
|
28
31
|
description: A Ruby library for carefully refactoring critical paths
|
29
32
|
email:
|
33
|
+
- opensource+scientist@github.com
|
30
34
|
- jbarnette@github.com
|
31
|
-
- rick@
|
35
|
+
- rick@rickbradley.com
|
36
|
+
- jesseplusplus@github.com
|
37
|
+
- zerowidth@github.com
|
32
38
|
executables: []
|
33
39
|
extensions: []
|
34
40
|
extra_rdoc_files: []
|
35
41
|
files:
|
36
42
|
- ".gitignore"
|
37
43
|
- ".travis.yml"
|
38
|
-
- CLA.md
|
39
|
-
- CONTRIBUTING.md
|
40
44
|
- Gemfile
|
41
45
|
- LICENSE.txt
|
42
46
|
- README.md
|
@@ -76,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
80
|
version: '0'
|
77
81
|
requirements: []
|
78
82
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.2.
|
83
|
+
rubygems_version: 2.2.3
|
80
84
|
signing_key:
|
81
85
|
specification_version: 4
|
82
86
|
summary: Carefully test, measure, and track refactored code.
|
data/CLA.md
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
GitHub CLA
|
2
|
-
===============
|
3
|
-
|
4
|
-
## Don't give up - please go ahead and create this PR.
|
5
|
-
|
6
|
-
We welcome you to follow, fork, and work on, our open source projects. If you want to contribute back to this project, or any other GitHub project, we need to ask you to complete the Contributor License Agreement (CLA) below. If you are contributing on behalf of your employer, or as part of your role as an employee, remember that you are signing in the name of your employer and you have to make sure that that's okay before you sign.
|
7
|
-
|
8
|
-
## What is this?
|
9
|
-
|
10
|
-
This is GitHub Inc.'s Contributor License Agreement. If you've worked in the technology space before, contributed or maintained an open source project, there's a good chance that you've run across one or more of these in the past. What CLAs aim to do is make sure the project is able to merge contributions from multiple contributors without getting itself into different types of trouble. This one is no different in that sense.
|
11
|
-
|
12
|
-
## Why is this?
|
13
|
-
|
14
|
-
The answer is that we need to protect the open source projects that we maintain, their users and their contributors (including Hubber contributors, of course, but not just). Why? Just imagine a case when a contributor is making a contribution to a project and that contribution is subsequently merged and becomes an integral part of the project. Now, go on to imagine that our contributor copied the code, or that this contributor works for a company that doesn't want its employees to make contributions to this project or any project. What then? Well, the person the code was copied from or the company can do whatever the hell they like, including to come after the project and its users if using it, make them stop or even sue. If either has patent rights in the code, the project is in even deeper trouble.
|
15
|
-
|
16
|
-
|
17
|
-
## So.
|
18
|
-
|
19
|
-
Please read the following terms, make sure you understand, and that if you agree, that you sign. Then, your pull request would be created and the project and the other contributors would be safe. It's important to us that you remember that except for the license you grant by signing this document - to GitHub, to your fellow contributors and to the project, you reserve all right, title, and interest in your contributions.
|
20
|
-
|
21
|
-
### 1. Definitions.
|
22
|
-
|
23
|
-
*You*, *you* (*Your*, or *your*) means the copyright owner or legal entity authorized by the copyright owner to sign this agreement.
|
24
|
-
|
25
|
-
*Contribution* or *contribution* means any original work of authorship, including any modifications or additions to an existing work, that is submitted to a GitHub project. "Submitted" means via a Pull Request, an issue or any form of electronic, verbal, or written communication sent to GitHub.
|
26
|
-
|
27
|
-
### 2. Grant of Copyright License.
|
28
|
-
|
29
|
-
Subject to the terms and conditions of this agreement, you grant to GitHub, to fellow contributors and to the project a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute your contributions and such derivative works.
|
30
|
-
|
31
|
-
### 3. Grant of Patent License.
|
32
|
-
|
33
|
-
Subject to the terms and conditions of this agreement, You hereby grant to GitHub, to fellow contributors to the project, and to its users a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer your contribution as part of the project, where such license applies only to those patent claims licensable by you that are necessarily infringed by your contribution or by combination of your contribution with the project to which this contribution was submitted. If any entity institutes patent litigation against you or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your contribution, or the project to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this agreement for that contribution shall terminate as of the date such litigation is filed.
|
34
|
-
|
35
|
-
### 4. You Can Grant this License.
|
36
|
-
|
37
|
-
Signing would mean that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your contributions, you have verified and are certain that you have received permission to make your contribution on behalf of that employer, that your employer has waived such rights for your contribution, or that your employer has executed a separate license with GitHub or the project.
|
38
|
-
|
39
|
-
### 5. Your Contribution is Yours.
|
40
|
-
|
41
|
-
Signing doesn't change the fact that your contribution is your original creation (see section 7 for submissions on behalf of others) and that they include complete details of any third-party license or other restriction (including related patents and trademarks) of which you are personally aware and which are associated with any part of your contributions.
|
42
|
-
|
43
|
-
### 6. You Provide Your Contribution "as is".
|
44
|
-
|
45
|
-
Signing this won't mean anybody will argue otherwise. In other words, your contributions are made without warranties or conditions of any kind.
|
46
|
-
|
47
|
-
### 7. If Some or All Your Contributions Is Not Yours.
|
48
|
-
|
49
|
-
That's fine but you need to identify the source or sources of the contribution and any license or other restriction (like related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the contribution as "Submitted on behalf of a third-party or third parties: [named here]". A place where you can do this is in a commit comment to the PR.
|
50
|
-
|
51
|
-
### 8. If Any Circumstances of Your Contribution change.
|
52
|
-
You agree to notify the project and GitHub of any facts or circumstances of which you become aware.
|
53
|
-
|
54
|
-
### 9. That's it!
|
data/CONTRIBUTING.md
DELETED
@@ -1,3 +0,0 @@
|
|
1
|
-
Hi there! We're thrilled that you'd like to contribute to this project. Before you do, would you mind reading [this license agreement](CLA.md)? If you open a PR, we'll assume you agree to it. If you have any hesitation or disagreement, please do open a PR still, but note your concerns as well.
|
2
|
-
|
3
|
-
Thanks!
|