nps 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/README.md +119 -0
- data/Rakefile +1 -0
- data/lib/nps.rb +28 -0
- data/lib/nps/ballot.rb +46 -0
- data/lib/nps/calculator.rb +48 -0
- data/lib/nps/configuration.rb +13 -0
- data/lib/nps/survey.rb +54 -0
- data/lib/nps/version.rb +3 -0
- data/nps.gemspec +24 -0
- data/spec/ballot_spec.rb +111 -0
- data/spec/calculator_spec.rb +135 -0
- data/spec/configuration_spec.rb +25 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/survey_spec.rb +39 -0
- metadata +116 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# Nps
|
2
|
+
|
3
|
+
A Net Promoter Score (NPS) calculator; does exactly as it says on the tin.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'nps'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install nps
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Introduction
|
22
|
+
Firstly, create a new survey:
|
23
|
+
```
|
24
|
+
require 'nps'
|
25
|
+
|
26
|
+
survey = Nps::Survey.new
|
27
|
+
```
|
28
|
+
|
29
|
+
### Voting
|
30
|
+
Voting is simply achieved by:
|
31
|
+
```
|
32
|
+
# Promoter vote
|
33
|
+
survey.vote!(10)
|
34
|
+
|
35
|
+
# Passive vote
|
36
|
+
survey.vote!(8)
|
37
|
+
|
38
|
+
# Detractor vote
|
39
|
+
survey.vote!(6)
|
40
|
+
```
|
41
|
+
|
42
|
+
### NPS Calculation
|
43
|
+
The NPS score can be calculated by:
|
44
|
+
```
|
45
|
+
# Calculate the NPS score
|
46
|
+
survey.score
|
47
|
+
```
|
48
|
+
|
49
|
+
It is also useful to know the percentage of votes in each category:
|
50
|
+
```
|
51
|
+
# Show the percentage of promoters, passives and detractors
|
52
|
+
survey.percentage_of_promoters
|
53
|
+
survey.percentage_of_passives
|
54
|
+
survey.percentage_of_detractors
|
55
|
+
```
|
56
|
+
|
57
|
+
### Ballot Adaptor
|
58
|
+
|
59
|
+
By default NPS comes with an in-memory adapter `NPS::Ballot` for storing NPS votes. You can also optionally configure NPS to use a different adapter to store your votes in a database or another persistance store:
|
60
|
+
|
61
|
+
```
|
62
|
+
Nps.configure do |config|
|
63
|
+
config.ballot_adaptor = YourBallotAdapter
|
64
|
+
end
|
65
|
+
```
|
66
|
+
To use a different adapter you must implement the same API as `NPS::Ballot`.
|
67
|
+
|
68
|
+
```
|
69
|
+
class YourBallotAdaptor
|
70
|
+
|
71
|
+
# Public: Initialize a Net Promoter Score ballot to store votes cast
|
72
|
+
# on a survey.
|
73
|
+
def initialize
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
# Public: Cast a vote with a given NPS value.
|
78
|
+
#
|
79
|
+
# value - The value of the vote on the NPS scale.
|
80
|
+
# opts - A hash of meta data associated with the vote (default: {})
|
81
|
+
def vote!(value, opts = {})
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
# Public: Whether any votes have been cast.
|
86
|
+
def any_votes?
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
# Public: The total number of votes that have been cast.
|
91
|
+
def total_votes
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
# Public: Find the votes that have been cast with a
|
96
|
+
# NPS value in the range.
|
97
|
+
#
|
98
|
+
# range - The range of NPS values.
|
99
|
+
def find_votes(range)
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
# Public: Count the votes that have been cast with a
|
104
|
+
# NPS value in the range.
|
105
|
+
#
|
106
|
+
# range - The range of NPS values.
|
107
|
+
def count_votes(range)
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
113
|
+
## Contributing
|
114
|
+
|
115
|
+
1. Fork it
|
116
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
117
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
118
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
119
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/nps.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
require "nps/version"
|
4
|
+
require "nps/calculator"
|
5
|
+
require "nps/survey"
|
6
|
+
require "nps/ballot"
|
7
|
+
require "nps/configuration"
|
8
|
+
|
9
|
+
module Nps
|
10
|
+
extend self
|
11
|
+
|
12
|
+
attr_accessor :configuration
|
13
|
+
|
14
|
+
# Public: Set custom configuration options
|
15
|
+
# such as how to store the NPS votes.
|
16
|
+
#
|
17
|
+
# Examples:
|
18
|
+
# Nps.configure do |config|
|
19
|
+
# config.ballot_adaptor = YourBallotAdaptor
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
def configure
|
23
|
+
self.configuration ||= Nps::Configuration.new
|
24
|
+
yield(configuration) if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
Nps.configure
|
28
|
+
end
|
data/lib/nps/ballot.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Nps
|
2
|
+
class Ballot
|
3
|
+
|
4
|
+
# Public: Initialize a Net Promoter Score ballot to store votes cast
|
5
|
+
# on a survey.
|
6
|
+
def initialize
|
7
|
+
@votes = []
|
8
|
+
end
|
9
|
+
|
10
|
+
# Public: Cast a vote with a given NPS value.
|
11
|
+
#
|
12
|
+
# value - The value of the vote on the NPS scale.
|
13
|
+
# opts - A hash of meta data associated with the vote (default: {})
|
14
|
+
def vote!(value, opts = {})
|
15
|
+
vote = OpenStruct.new(:value => value.to_f, :options => opts)
|
16
|
+
@votes << vote
|
17
|
+
vote
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: Whether any votes have been cast.
|
21
|
+
def any_votes?
|
22
|
+
total_votes != 0
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: The total number of votes that have been cast.
|
26
|
+
def total_votes
|
27
|
+
@votes.count
|
28
|
+
end
|
29
|
+
|
30
|
+
# Public: Find the votes that have been cast with a
|
31
|
+
# NPS value in the range.
|
32
|
+
#
|
33
|
+
# range - The range of NPS values.
|
34
|
+
def find_votes(range)
|
35
|
+
@votes.select { |vote| range.include?(vote.value) }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Public: Count the votes that have been cast with a
|
39
|
+
# NPS value in the range.
|
40
|
+
#
|
41
|
+
# range - The range of NPS values.
|
42
|
+
def count_votes(range)
|
43
|
+
find_votes(range).count
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Nps
|
2
|
+
class Calculator
|
3
|
+
|
4
|
+
# Internal: Initialize a Net Promoter Score (NPS) calculator
|
5
|
+
#
|
6
|
+
# ballot - a ballot of votes in the NPS survey.
|
7
|
+
def initialize(ballot)
|
8
|
+
@ballot = ballot
|
9
|
+
end
|
10
|
+
|
11
|
+
# Internal: The Net Promoter Score (NPS) calculated from the ballot.
|
12
|
+
def score
|
13
|
+
percentage_of_promoters - percentage_of_detractors
|
14
|
+
end
|
15
|
+
|
16
|
+
# Internal: The percentage of promoter votes in the ballot.
|
17
|
+
def percentage_of_promoters
|
18
|
+
@ballot.any_votes? ? ((promoters.to_f / @ballot.total_votes.to_f) * 100.0).round(2) : 0.0
|
19
|
+
end
|
20
|
+
|
21
|
+
# Internal: The percentage of passive votes in the ballot.
|
22
|
+
def percentage_of_passives
|
23
|
+
@ballot.any_votes? ? ((passives.to_f / @ballot.total_votes.to_f) * 100.0).round(2) : 0.0
|
24
|
+
end
|
25
|
+
|
26
|
+
# Internal: The percentage of detractor votes in the ballot.
|
27
|
+
def percentage_of_detractors
|
28
|
+
@ballot.any_votes? ? ((detractors.to_f / @ballot.total_votes.to_f) * 100.0).round(2) : 0.0
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Internal: The number of promoters in the ballot.
|
34
|
+
def promoters
|
35
|
+
@ballot.count_votes(9..10)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Internal: The number of passives in the ballot.
|
39
|
+
def passives
|
40
|
+
@ballot.count_votes(7..8)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Internal: The number of detractors in the ballot.
|
44
|
+
def detractors
|
45
|
+
@ballot.count_votes(0..6)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Nps
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
# Public: Retrieve or assign a ballot adaptor to store the NPS votes.
|
5
|
+
attr_accessor :ballot_adaptor
|
6
|
+
|
7
|
+
# Public: Initialize a new configuration for the library
|
8
|
+
# with the default behaviour.
|
9
|
+
def initialize
|
10
|
+
@ballot_adaptor = Nps::Ballot
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/nps/survey.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Nps
|
2
|
+
class Survey
|
3
|
+
|
4
|
+
attr_reader :ballot
|
5
|
+
|
6
|
+
# Public: Initialize a Net Promoter Score (NPS) survey
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# survey = Nps::Survey.new
|
10
|
+
# survey.vote!(10)
|
11
|
+
# survey.score
|
12
|
+
#
|
13
|
+
def initialize
|
14
|
+
@ballot = Nps.configuration.ballot_adaptor.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# Public: The Net Promoter Score (NPS) for the survey.
|
18
|
+
def score
|
19
|
+
calculator.score
|
20
|
+
end
|
21
|
+
|
22
|
+
# Public: The percentage of promoter votes in the survey.
|
23
|
+
def percentage_of_promoters
|
24
|
+
calculator.percentage_of_promoters
|
25
|
+
end
|
26
|
+
|
27
|
+
# Public: The percentage of passive votes in the survey.
|
28
|
+
def percentage_of_passives
|
29
|
+
calculator.percentage_of_passives
|
30
|
+
end
|
31
|
+
|
32
|
+
# Public: The percentage of detractor votes in the survey.
|
33
|
+
def percentage_of_detractors
|
34
|
+
calculator.percentage_of_detractors
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: Add a vote to the survey with the given value
|
38
|
+
#
|
39
|
+
# value - The value of the vote on the NPS scale (0..10)
|
40
|
+
# opts - A hash of meta data associated with the vote (default: {})
|
41
|
+
def vote!(value, opts = {})
|
42
|
+
ballot.vote!(value, opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Internal: The Net Promoter Score Calculator
|
48
|
+
def calculator
|
49
|
+
Nps::Calculator.new(ballot)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
data/lib/nps/version.rb
ADDED
data/nps.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'nps/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "nps"
|
8
|
+
spec.version = Nps::VERSION
|
9
|
+
spec.authors = ["Murray Summers"]
|
10
|
+
spec.email = ["murray.sum@gmail.com"]
|
11
|
+
spec.description = %q{Net Promoter Score (NPS) is a customer loyalty metric allowing customer satisfaction to be compared over time and business sector.}
|
12
|
+
spec.summary = %q{A Net Promoter Score (NPS) calculator}
|
13
|
+
spec.homepage = "https://github.com/murraysum/nps"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency 'rspec'
|
24
|
+
end
|
data/spec/ballot_spec.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nps::Ballot do
|
4
|
+
|
5
|
+
describe 'initialize' do
|
6
|
+
before :each do
|
7
|
+
@ballot = Nps::Ballot.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'have no promoter votes' do
|
11
|
+
@ballot.count_votes(9..10).should == 0
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'have no passive votes' do
|
15
|
+
@ballot.count_votes(7..8).should == 0
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'have no detractor votes' do
|
19
|
+
@ballot.count_votes(0..6).should == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'have no votes' do
|
23
|
+
@ballot.any_votes?.should be_false
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'have no votes in all categories' do
|
27
|
+
@ballot.total_votes.should == 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'promoter vote' do
|
32
|
+
before :each do
|
33
|
+
@ballot = Nps::Ballot.new
|
34
|
+
@ballot.vote!(10)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'have a promoters vote' do
|
38
|
+
@ballot.count_votes(9..10).should == 1
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'have no passive votes' do
|
42
|
+
@ballot.count_votes(7..8).should == 0
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'have no detractor votes' do
|
46
|
+
@ballot.count_votes(0..6).should == 0
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'have votes' do
|
50
|
+
@ballot.any_votes?.should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'have one vote' do
|
54
|
+
@ballot.total_votes.should == 1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'passive vote' do
|
59
|
+
before :each do
|
60
|
+
@ballot = Nps::Ballot.new
|
61
|
+
@ballot.vote!(8)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'have no promoter votes' do
|
65
|
+
@ballot.count_votes(9..10).should == 0
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'have a passive vote' do
|
69
|
+
@ballot.count_votes(7..8).should == 1
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'have no detractor votes' do
|
73
|
+
@ballot.count_votes(0..6).should == 0
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'have votes' do
|
77
|
+
@ballot.any_votes?.should be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'have one vote' do
|
81
|
+
@ballot.total_votes.should == 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'detractor vote' do
|
86
|
+
before :each do
|
87
|
+
@ballot = Nps::Ballot.new
|
88
|
+
@ballot.vote!(6)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'have no promoter votes' do
|
92
|
+
@ballot.count_votes(9..10).should == 0
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'have no passive votes' do
|
96
|
+
@ballot.count_votes(7..8).should == 0
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'have a detractor vote' do
|
100
|
+
@ballot.count_votes(0..6).should == 1
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'have votes' do
|
104
|
+
@ballot.any_votes?.should be_true
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'have one vote' do
|
108
|
+
@ballot.total_votes.should == 1
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nps::Calculator do
|
4
|
+
describe 'with an empty ballot' do
|
5
|
+
before :each do
|
6
|
+
@ballot = Nps::Ballot.new
|
7
|
+
@calculator = Nps::Calculator.new(@ballot)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'have a zero score' do
|
11
|
+
@calculator.score.should == 0
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'have zero percentage of promoters' do
|
15
|
+
@calculator.percentage_of_promoters.should == 0
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'have zero percentage of passives' do
|
19
|
+
@calculator.percentage_of_passives.should == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'have zero percentage of detractors' do
|
23
|
+
@calculator.percentage_of_detractors.should == 0
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'with a promoter ballot' do
|
28
|
+
before :each do
|
29
|
+
@ballot = Nps::Ballot.new
|
30
|
+
@calculator = Nps::Calculator.new(@ballot)
|
31
|
+
@ballot.vote!(10)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'have a score' do
|
35
|
+
@calculator.score.should == 100
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'have percentage of promoters' do
|
39
|
+
@calculator.percentage_of_promoters.should == 100
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'have zero percentage of passives' do
|
43
|
+
@calculator.percentage_of_passives.should == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'have zero percentage of detractors' do
|
47
|
+
@calculator.percentage_of_detractors.should == 0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'with a passive ballot' do
|
52
|
+
before :each do
|
53
|
+
@ballot = Nps::Ballot.new
|
54
|
+
@calculator = Nps::Calculator.new(@ballot)
|
55
|
+
@ballot.vote!(7)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'have a score' do
|
59
|
+
@calculator.score.should == 0
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'have zero percentage of promoters' do
|
63
|
+
@calculator.percentage_of_promoters.should == 0
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'have a percentage of passives' do
|
67
|
+
@calculator.percentage_of_passives.should == 100
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'have zero percentage of detractors' do
|
71
|
+
@calculator.percentage_of_detractors.should == 0
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'with a detractor ballot' do
|
76
|
+
before :each do
|
77
|
+
@ballot = Nps::Ballot.new
|
78
|
+
@calculator = Nps::Calculator.new(@ballot)
|
79
|
+
@ballot.vote!(0)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'have a score' do
|
83
|
+
@calculator.score.should == -100
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'have zero percentage of promoters' do
|
87
|
+
@calculator.percentage_of_promoters.should == 0
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'have zero percentage of passives' do
|
91
|
+
@calculator.percentage_of_passives.should == 0
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'have a percentage of detractors' do
|
95
|
+
@calculator.percentage_of_detractors.should == 100
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'with a mixed ballot' do
|
100
|
+
before :each do
|
101
|
+
@ballot = Nps::Ballot.new
|
102
|
+
@calculator = Nps::Calculator.new(@ballot)
|
103
|
+
# Promoters
|
104
|
+
@ballot.vote!(10)
|
105
|
+
@ballot.vote!(9)
|
106
|
+
# Passives
|
107
|
+
@ballot.vote!(8)
|
108
|
+
@ballot.vote!(7)
|
109
|
+
# Detractors
|
110
|
+
@ballot.vote!(6)
|
111
|
+
@ballot.vote!(5)
|
112
|
+
@ballot.vote!(4)
|
113
|
+
@ballot.vote!(3)
|
114
|
+
@ballot.vote!(2)
|
115
|
+
@ballot.vote!(1)
|
116
|
+
@ballot.vote!(0)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'have a score' do
|
120
|
+
@calculator.score.should == -45.46
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'have a percentage of promoters' do
|
124
|
+
@calculator.percentage_of_promoters.should == 18.18
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'have a percentage of passives' do
|
128
|
+
@calculator.percentage_of_passives.should == 18.18
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'have a percentage of detractors' do
|
132
|
+
@calculator.percentage_of_detractors.should == 63.64
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nps::Configuration do
|
4
|
+
|
5
|
+
describe 'with default options' do
|
6
|
+
before :each do
|
7
|
+
@configuration = Nps::Configuration.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should set the default ballot adaptor' do
|
11
|
+
@configuration.ballot_adaptor == Nps::Ballot
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'with custom options' do
|
16
|
+
before :each do
|
17
|
+
@configuration = Nps::Configuration.new
|
18
|
+
@configuration.ballot_adaptor = Struct
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should set a custom ballot adaptor' do
|
22
|
+
@configuration.ballot_adaptor == Struct
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/survey_spec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nps::Survey do
|
4
|
+
describe 'with a survey' do
|
5
|
+
before :each do
|
6
|
+
@survey = Nps::Survey.new
|
7
|
+
# Promoters
|
8
|
+
@survey.vote!(10)
|
9
|
+
@survey.vote!(9)
|
10
|
+
# Passives
|
11
|
+
@survey.vote!(8)
|
12
|
+
@survey.vote!(7)
|
13
|
+
# Detractors
|
14
|
+
@survey.vote!(6)
|
15
|
+
@survey.vote!(5)
|
16
|
+
@survey.vote!(4)
|
17
|
+
@survey.vote!(3)
|
18
|
+
@survey.vote!(2)
|
19
|
+
@survey.vote!(1)
|
20
|
+
@survey.vote!(0)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'have a score' do
|
24
|
+
@survey.score.should == -45.46
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'have a percentage of promoters' do
|
28
|
+
@survey.percentage_of_promoters.should == 18.18
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'have a percentage of passives' do
|
32
|
+
@survey.percentage_of_passives.should == 18.18
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'have a percentage of detractors' do
|
36
|
+
@survey.percentage_of_detractors.should == 63.64
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nps
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Murray Summers
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-02-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Net Promoter Score (NPS) is a customer loyalty metric allowing customer
|
63
|
+
satisfaction to be compared over time and business sector.
|
64
|
+
email:
|
65
|
+
- murray.sum@gmail.com
|
66
|
+
executables: []
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- Gemfile
|
72
|
+
- README.md
|
73
|
+
- Rakefile
|
74
|
+
- lib/nps.rb
|
75
|
+
- lib/nps/ballot.rb
|
76
|
+
- lib/nps/calculator.rb
|
77
|
+
- lib/nps/configuration.rb
|
78
|
+
- lib/nps/survey.rb
|
79
|
+
- lib/nps/version.rb
|
80
|
+
- nps.gemspec
|
81
|
+
- spec/ballot_spec.rb
|
82
|
+
- spec/calculator_spec.rb
|
83
|
+
- spec/configuration_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
- spec/survey_spec.rb
|
86
|
+
homepage: https://github.com/murraysum/nps
|
87
|
+
licenses:
|
88
|
+
- MIT
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 1.8.23
|
108
|
+
signing_key:
|
109
|
+
specification_version: 3
|
110
|
+
summary: A Net Promoter Score (NPS) calculator
|
111
|
+
test_files:
|
112
|
+
- spec/ballot_spec.rb
|
113
|
+
- spec/calculator_spec.rb
|
114
|
+
- spec/configuration_spec.rb
|
115
|
+
- spec/spec_helper.rb
|
116
|
+
- spec/survey_spec.rb
|