gamifying_formatter 0.0.2
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 +15 -0
- data/.gitignore +18 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +44 -0
- data/Rakefile +1 -0
- data/achievement.png +0 -0
- data/example/example.rb +8 -0
- data/gamifying_formatter.gemspec +19 -0
- data/lib/gamifying_formatter.rb +179 -0
- data/lib/test_info.rb +15 -0
- data/spec/gamifying_formatter_spec.rb +93 -0
- data/spec/spec_helper.rb +3 -0
- metadata +72 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjE1NTRlMDU2YjdiOTdjNjcyOGRlZmMzYTY2ZTg1MDkyMzgzMGM1ZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Njc0N2ZlZWY1OGNiMmVhYjYyMWQyOWU0OTMwZjVmOTY0NTU2ZjQ1MA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YWRmZDY2N2NiZTY4OGRhNzAwMmZhZmRhMWUzNWJlZjc4ZTAwMDA2Y2Q4Mzli
|
10
|
+
ZGVkMzI1YzA5ZWM3ZTMyNzc4YzZjNTU1NDVhY2FlNjkzYzkyMDkyOTNlNDRi
|
11
|
+
MDM4ZTZhYjA0YzE2MzAyYTg2NThkNTBiOGM4NDhlYmYzNzNiOTU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZmJhZTZiYmY5YTVjZjJjMTBkNTlmZDI3MjVlZGY0NzYyY2NkODJhZTQ1MTJk
|
14
|
+
MmI2NzE2MmQ5YzNhNmJlOTIxZTk3ZTQyY2EyYTc2OTc2MThlYzE1YzZiODNk
|
15
|
+
MmI3MTdjNTc0YWFmODY3NmQwZjY1OWVkNzkxNzg0MzkyYmZhNTY=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Chris Belsole
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# GamifyingFormatter
|
2
|
+

|
3
|
+
|
4
|
+
GameifyingFormatter is here to solve your testing woes. With trophies and achievements it makes running tests fun. This project was created so that you could use it as a stand alone test runner or extend it and add achievements to your own test runner.
|
5
|
+
|
6
|
+
These are the achievements you can get points for right now:
|
7
|
+
Fixing failed tests
|
8
|
+
Improving test speed
|
9
|
+
Adding tests
|
10
|
+
|
11
|
+
You receive the trophies based on the amount of points you get which start out small and get bigger.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
gem 'gamifying_formatter'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install gamifying_formatter
|
26
|
+
|
27
|
+
If you want to use the Gamifying Formatter as your default formatter just put this option in your .rspec file:
|
28
|
+
|
29
|
+
--format GamifyingFormatter
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
To use the GamifyingFormatter all you need to do is add this option when you are running your spect tests if you did not already edit your .rspec file:
|
34
|
+
|
35
|
+
--format GamifyingFormatter
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
1. Fork it
|
40
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
41
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
42
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
43
|
+
5. Create new Pull Request
|
44
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/achievement.png
ADDED
Binary file
|
data/example/example.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "gamifying_formatter"
|
7
|
+
gem.version = '0.0.2'
|
8
|
+
gem.authors = ["Chris Belsole"]
|
9
|
+
gem.email = ["cbelsole@gmail.com"]
|
10
|
+
gem.description = %q{The Gamifying Formatter}
|
11
|
+
gem.summary = %q{An rspec formatter for making testing fun.}
|
12
|
+
gem.homepage = ""
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/)
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
gem.add_dependency 'rspec'
|
19
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require "rspec/core/formatters/base_text_formatter"
|
2
|
+
require 'test_info'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
class GamifyingFormatter < RSpec::Core::Formatters::BaseTextFormatter
|
6
|
+
def initialize(output)
|
7
|
+
super(output)
|
8
|
+
|
9
|
+
if File.exists?('.past_results.yml')
|
10
|
+
@test_info = YAML::load(File.new('.past_results.yml', 'r'))
|
11
|
+
else
|
12
|
+
@test_info = TestInfo.new
|
13
|
+
@test_info.level = 1
|
14
|
+
@test_info.xp = 0
|
15
|
+
@test_info.number_of_tests = 0
|
16
|
+
@test_info.number_of_failed_tests = 0
|
17
|
+
@test_info.total_time = 0.0
|
18
|
+
end
|
19
|
+
|
20
|
+
@got_achievement = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def close
|
24
|
+
super
|
25
|
+
|
26
|
+
@test_info.number_of_tests = example_count
|
27
|
+
@test_info.total_time = duration
|
28
|
+
@test_info.number_of_failed_tests = failure_count
|
29
|
+
|
30
|
+
File.open('.past_results.yml', 'w') { |file| file.puts @test_info.to_yaml }
|
31
|
+
end
|
32
|
+
|
33
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
34
|
+
|
35
|
+
super(duration, example_count, failure_count, pending_count)
|
36
|
+
|
37
|
+
calculate_achevements(example_count, failure_count, duration)
|
38
|
+
|
39
|
+
output_achievements
|
40
|
+
|
41
|
+
output_xp_bar
|
42
|
+
end
|
43
|
+
|
44
|
+
def calculate_achevements(example_count, failure_count, duration)
|
45
|
+
number_of_tests_achievement(@test_info.number_of_tests, example_count)
|
46
|
+
|
47
|
+
number_of_fixed_tests_achievement(@test_info.number_of_failed_tests, failure_count)
|
48
|
+
|
49
|
+
decreased_test_time_achievement(@test_info.total_time, duration)
|
50
|
+
end
|
51
|
+
|
52
|
+
def output_achievements
|
53
|
+
return unless @got_achievement
|
54
|
+
output.puts "\n!!!!!!!!Achievements!!!!!!!!"
|
55
|
+
output.puts get_trophie(@test_info.level)
|
56
|
+
output.puts '-' * (@test_info.achievements.uniq.join(" | ").size + 4)
|
57
|
+
output.puts "| #{@test_info.achievements.uniq.join(" | ")} |"
|
58
|
+
output.puts '-' * (@test_info.achievements.uniq.join(" | ").size + 4)
|
59
|
+
end
|
60
|
+
|
61
|
+
def output_xp_bar
|
62
|
+
case @test_info.level
|
63
|
+
when 1
|
64
|
+
goal_xp = 10
|
65
|
+
when 2
|
66
|
+
goal_xp = 25
|
67
|
+
when 3
|
68
|
+
goal_xp = 50
|
69
|
+
when 4
|
70
|
+
goal_xp = 100
|
71
|
+
else
|
72
|
+
goal_xp = 1000
|
73
|
+
end
|
74
|
+
|
75
|
+
least_common_multiple = goal_xp.lcm(25)
|
76
|
+
numerator = least_common_multiple / goal_xp
|
77
|
+
denominator = least_common_multiple / 25
|
78
|
+
|
79
|
+
xp_chars = '=' * ((@test_info.xp * numerator) / denominator).ceil
|
80
|
+
xp_filler = ' ' * (25 - xp_chars.size)
|
81
|
+
|
82
|
+
output.puts "Level #{@test_info.level}: #{@test_info.xp}/#{goal_xp} [#{xp_chars}#{xp_filler}]"
|
83
|
+
end
|
84
|
+
|
85
|
+
def number_of_tests_achievement(old_total_tests, new_total_tests)
|
86
|
+
[100, 50, 25, 10, 5, 1].each do |number|
|
87
|
+
if new_total_tests - old_total_tests >= number
|
88
|
+
@test_info.achievements.push("Added #{number} test(s)!")
|
89
|
+
@test_info.xp += 1
|
90
|
+
@got_achievement = true
|
91
|
+
check_level_up(@test_info.xp)
|
92
|
+
break
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def decreased_test_time_achievement(old_total_time, new_total_time)
|
98
|
+
[100, 50, 25, 10, 5, 1, 0.5, 0.2].each do |number|
|
99
|
+
if (old_total_time * 100 - new_total_time * 100).round / 100.0 >= number
|
100
|
+
@test_info.achievements.push("Reduced testing time by #{number} second(s)!")
|
101
|
+
@test_info.xp += 1
|
102
|
+
@got_achievement = true
|
103
|
+
check_level_up(@test_info.xp)
|
104
|
+
break
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def number_of_fixed_tests_achievement(old_failed_tests, new_failed_tests)
|
110
|
+
[100, 50, 25, 10, 5, 1].each do |number|
|
111
|
+
if old_failed_tests - new_failed_tests >= number
|
112
|
+
@test_info.achievements.push("Fixed #{number} test(s)!")
|
113
|
+
@test_info.xp += 1
|
114
|
+
@got_achievement = true
|
115
|
+
check_level_up(@test_info.xp)
|
116
|
+
break
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def check_level_up(xp)
|
122
|
+
if xp == 10 || xp == 25 || xp == 50 || xp == 100
|
123
|
+
@test_info.level += 1
|
124
|
+
@test_info.xp = 0
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_trophie(level)
|
129
|
+
case level
|
130
|
+
when 3
|
131
|
+
<<-EOS
|
132
|
+
___________
|
133
|
+
'._==_==_=_.'
|
134
|
+
.-\\: /-.
|
135
|
+
| (|:. |) |
|
136
|
+
'-|:. |-'
|
137
|
+
\\::. /
|
138
|
+
'::. .'
|
139
|
+
) (
|
140
|
+
_.' '._
|
141
|
+
`"""""""`"
|
142
|
+
EOS
|
143
|
+
when 2
|
144
|
+
<<-EOS
|
145
|
+
{}
|
146
|
+
/__\\
|
147
|
+
/| |\\
|
148
|
+
(_| |_)
|
149
|
+
\\ /
|
150
|
+
)(
|
151
|
+
_|__|_
|
152
|
+
_|______|_
|
153
|
+
|__________|
|
154
|
+
EOS
|
155
|
+
when 4
|
156
|
+
<<-EOS
|
157
|
+
.-=========-.
|
158
|
+
\\'-=======-'/
|
159
|
+
_| .=. |_
|
160
|
+
((| {{1}} |))
|
161
|
+
\\| /|\\ |/
|
162
|
+
\\__ '`' __/
|
163
|
+
_`) (`_
|
164
|
+
_/_______\\_
|
165
|
+
/___________\\
|
166
|
+
EOS
|
167
|
+
when 1
|
168
|
+
<<-EOS
|
169
|
+
.__.
|
170
|
+
(| |)
|
171
|
+
( )
|
172
|
+
_)(_
|
173
|
+
EOS
|
174
|
+
else
|
175
|
+
''
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
data/lib/test_info.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class TestInfo
|
2
|
+
attr_accessor :number_of_tests, :total_time, :number_of_failed_tests, :xp, :level
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@achievements = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def achievements=(value)
|
9
|
+
@achievements = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def achievements
|
13
|
+
@achievements
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
describe GamifyingFormatter do
|
5
|
+
before do
|
6
|
+
@output = StringIO.new
|
7
|
+
@formatter = GamifyingFormatter.new(@output)
|
8
|
+
@formatter.start(2)
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'achievements' do
|
12
|
+
describe '.number_of_tests_achievement' do
|
13
|
+
it 'should set an achievment for adding 1 test' do
|
14
|
+
@formatter.number_of_tests_achievement(3, 4)
|
15
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(1)
|
16
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements[0]).to eq('Added 1 test(s)!')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should set and achievement for adding 100 tests' do
|
20
|
+
@formatter.number_of_tests_achievement(1, 1000)
|
21
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(1)
|
22
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements[0]).to eq('Added 100 test(s)!')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should not set an achievement for adding tests' do
|
26
|
+
@formatter.number_of_tests_achievement(4, 3)
|
27
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(0)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.decreased_test_time_achievement' do
|
32
|
+
it 'should set an achievment for improving tests time by .2 seconds' do
|
33
|
+
@formatter.decreased_test_time_achievement(0.3, 0.1)
|
34
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(1)
|
35
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements[0]).to eq('Reduced testing time by 0.2 second(s)!')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should set and achievement for improving tests time by 100 seconds' do
|
39
|
+
@formatter.decreased_test_time_achievement(1000, 1)
|
40
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(1)
|
41
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements[0]).to eq('Reduced testing time by 100 second(s)!')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should not set an achievement for improving test time' do
|
45
|
+
@formatter.decreased_test_time_achievement(3, 4)
|
46
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(0)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.number_of_fixed_tests_achievement' do
|
51
|
+
it 'should set an achievment for fixing 1 test' do
|
52
|
+
@formatter.number_of_fixed_tests_achievement(4, 3)
|
53
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(1)
|
54
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements[0]).to eq('Fixed 1 test(s)!')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should set and achievement for fixing 100 tests' do
|
58
|
+
@formatter.number_of_fixed_tests_achievement(10000, 1)
|
59
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(1)
|
60
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements[0]).to eq('Fixed 100 test(s)!')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should not set an achievement for fixing tests' do
|
64
|
+
@formatter.number_of_fixed_tests_achievement(3, 4)
|
65
|
+
expect(@formatter.instance_variable_get(:@test_info).achievements.size).to eq(0)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'output' do
|
71
|
+
describe '.output_achievements' do
|
72
|
+
it 'outputs all achievemnts in the list' do
|
73
|
+
achievement_array = Array.new(5) { |i| "Achievement #{i}"}
|
74
|
+
@formatter.instance_variable_get(:@test_info).achievements = achievement_array
|
75
|
+
|
76
|
+
@output.should_receive(:puts).exactly(5).times
|
77
|
+
|
78
|
+
@formatter.output_achievements
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '.get_trophies' do
|
83
|
+
it 'returns the correct trophie based on the number' do
|
84
|
+
expect(@formatter.get_trophie(1)).to eq([
|
85
|
+
" .__.",
|
86
|
+
" (| |)",
|
87
|
+
" ( )",
|
88
|
+
" _)(_"
|
89
|
+
].join("\n"))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gamifying_formatter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Belsole
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: The Gamifying Formatter
|
28
|
+
email:
|
29
|
+
- cbelsole@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- Gemfile
|
36
|
+
- LICENSE.txt
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- achievement.png
|
40
|
+
- example/example.rb
|
41
|
+
- gamifying_formatter.gemspec
|
42
|
+
- lib/gamifying_formatter.rb
|
43
|
+
- lib/test_info.rb
|
44
|
+
- spec/gamifying_formatter_spec.rb
|
45
|
+
- spec/spec_helper.rb
|
46
|
+
homepage: ''
|
47
|
+
licenses: []
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.0.3
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: An rspec formatter for making testing fun.
|
69
|
+
test_files:
|
70
|
+
- spec/gamifying_formatter_spec.rb
|
71
|
+
- spec/spec_helper.rb
|
72
|
+
has_rdoc:
|