hit_counter 0.1.1 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +23 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- data/.github/ISSUE_TEMPLATE/task.md +21 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +31 -0
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/test.yml +42 -0
- data/.gitignore +8 -0
- data/.simplecov +15 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +34 -0
- data/Gemfile +12 -12
- data/LICENSE.txt +17 -11
- data/README.md +120 -0
- data/Rakefile +15 -40
- data/SECURITY.md +16 -0
- data/certs/ivanoblomov.pem +25 -0
- data/config/initializers/mime_types.rb +3 -1
- data/config/mongoid.yml +6 -0
- data/hit_counter.gemspec +20 -87
- data/lib/hit_counter.rb +91 -85
- data/lib/tasks/install.rake +6 -0
- data/lib/version.rb +7 -0
- data/public/images/digits/celtic/0.png +0 -0
- data/public/images/digits/celtic/1.png +0 -0
- data/public/images/digits/celtic/2.png +0 -0
- data/public/images/digits/celtic/3.png +0 -0
- data/public/images/digits/celtic/4.png +0 -0
- data/public/images/digits/celtic/5.png +0 -0
- data/public/images/digits/celtic/6.png +0 -0
- data/public/images/digits/celtic/7.png +0 -0
- data/public/images/digits/celtic/8.png +0 -0
- data/public/images/digits/celtic/9.png +0 -0
- data/public/images/digits/odometer/0.png +0 -0
- data/public/images/digits/odometer/1.png +0 -0
- data/public/images/digits/odometer/2.png +0 -0
- data/public/images/digits/odometer/3.png +0 -0
- data/public/images/digits/odometer/4.png +0 -0
- data/public/images/digits/odometer/5.png +0 -0
- data/public/images/digits/odometer/6.png +0 -0
- data/public/images/digits/odometer/7.png +0 -0
- data/public/images/digits/odometer/8.png +0 -0
- data/public/images/digits/odometer/9.png +0 -0
- data/public/images/digits/scout/0.png +0 -0
- data/public/images/digits/scout/1.png +0 -0
- data/public/images/digits/scout/2.png +0 -0
- data/public/images/digits/scout/3.png +0 -0
- data/public/images/digits/scout/4.png +0 -0
- data/public/images/digits/scout/5.png +0 -0
- data/public/images/digits/scout/6.png +0 -0
- data/public/images/digits/scout/7.png +0 -0
- data/public/images/digits/scout/8.png +0 -0
- data/public/images/digits/scout/9.png +0 -0
- data/spec/lib/hit_counter_spec.rb +110 -69
- data/spec/spec_helper.rb +52 -3
- data.tar.gz.sig +0 -0
- metadata +157 -148
- metadata.gz.sig +0 -0
- data/README.rdoc +0 -82
- data/VERSION +0 -1
- data/public/images/digits/celtic/0.gif +0 -0
- data/public/images/digits/celtic/1.gif +0 -0
- data/public/images/digits/celtic/2.gif +0 -0
- data/public/images/digits/celtic/3.gif +0 -0
- data/public/images/digits/celtic/4.gif +0 -0
- data/public/images/digits/celtic/5.gif +0 -0
- data/public/images/digits/celtic/6.gif +0 -0
- data/public/images/digits/celtic/7.gif +0 -0
- data/public/images/digits/celtic/8.gif +0 -0
- data/public/images/digits/celtic/9.gif +0 -0
- data/public/images/digits/odometer/0.gif +0 -0
- data/public/images/digits/odometer/1.gif +0 -0
- data/public/images/digits/odometer/2.gif +0 -0
- data/public/images/digits/odometer/3.gif +0 -0
- data/public/images/digits/odometer/4.gif +0 -0
- data/public/images/digits/odometer/5.gif +0 -0
- data/public/images/digits/odometer/6.gif +0 -0
- data/public/images/digits/odometer/7.gif +0 -0
- data/public/images/digits/odometer/8.gif +0 -0
- data/public/images/digits/odometer/9.gif +0 -0
- data/public/images/digits/scout/0.gif +0 -0
- data/public/images/digits/scout/1.gif +0 -0
- data/public/images/digits/scout/2.gif +0 -0
- data/public/images/digits/scout/3.gif +0 -0
- data/public/images/digits/scout/4.gif +0 -0
- data/public/images/digits/scout/5.gif +0 -0
- data/public/images/digits/scout/6.gif +0 -0
- data/public/images/digits/scout/7.gif +0 -0
- data/public/images/digits/scout/8.gif +0 -0
- data/public/images/digits/scout/9.gif +0 -0
data/lib/hit_counter.rb
CHANGED
@@ -1,138 +1,144 @@
|
|
1
|
-
# Copyright
|
2
|
-
#
|
3
|
-
#
|
4
|
-
|
5
|
-
# the Free Software Foundation, either version 3 of the License, or
|
6
|
-
# (at your option) any later version.
|
7
|
-
#
|
8
|
-
# This program is distributed in the hope that it will be useful,
|
9
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
-
# GNU General Public License for more details.
|
12
|
-
#
|
13
|
-
# You should have received a copy of the GNU General Public License
|
14
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
1
|
+
# Copyright the HitCounter contributors.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
15
5
|
require 'rubygems'
|
16
6
|
require 'bundler/setup'
|
17
7
|
Bundler.require :default
|
18
8
|
|
9
|
+
# Self-hosted Ruby version of that old 90s chestnut, <BLINK>the web-site hit counter</BLINK>
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# hc = HitCounter.get 'cnn.com'
|
13
|
+
# hc.increment
|
19
14
|
class HitCounter
|
20
15
|
include Mongoid::Document
|
21
16
|
include Mongoid::Timestamps
|
22
17
|
|
23
|
-
# Mongo Config
|
18
|
+
# Mongo Config ===============================================================
|
19
|
+
field :hits, type: Integer, default: 0
|
24
20
|
field :url
|
25
|
-
field :hits, :type => Integer, :default => 0
|
26
21
|
|
27
22
|
# Validates the <code>HitCounter</code>'s URL.
|
28
23
|
#
|
29
|
-
# If the URI library can parse the value and the scheme is valid, then we
|
24
|
+
# If the URI library can parse the value and the scheme is valid, then we
|
25
|
+
# assume the url is valid.
|
30
26
|
class UrlValidator < ActiveModel::EachValidator
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
27
|
+
private
|
28
|
+
|
29
|
+
def validate_each(record, attribute, value)
|
30
|
+
uri = Addressable::URI.parse value
|
31
|
+
raise Addressable::URI::InvalidURIError unless %w[http https].include?(
|
32
|
+
uri.scheme
|
33
|
+
)
|
34
|
+
rescue Addressable::URI::InvalidURIError
|
35
|
+
record.errors.add attribute, 'Invalid URL'
|
41
36
|
end
|
42
37
|
end
|
43
38
|
|
44
|
-
validates :
|
39
|
+
validates :hits, numericality: { only_integer: true }
|
40
|
+
validates :url, presence: true, url: true, uniqueness: true
|
45
41
|
|
46
|
-
# Class methods
|
42
|
+
# Class methods ==============================================================
|
47
43
|
|
48
|
-
# Returns a <code>HitCounter</code> matching the specified URL. The HitCounter
|
49
|
-
# matching one is found. In the latter case, the hits
|
44
|
+
# Returns a <code>HitCounter</code> matching the specified URL. The HitCounter
|
45
|
+
# is created if no matching one is found. In the latter case, the hits
|
46
|
+
# argument specifies the starting count.
|
50
47
|
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
args
|
59
|
-
|
48
|
+
# @param url [String] the URL for the site being counted
|
49
|
+
# @param hits [Integer] the number of hits to start with
|
50
|
+
# @return [HitCounter] the site's HitCounter
|
51
|
+
# @example
|
52
|
+
# hc = HitCounter.get 'cnn.com'
|
53
|
+
# hc = HitCounter.get 'cnn.com', 100
|
54
|
+
def self.get(url, hits = 0)
|
55
|
+
args = { url: normalize_url(url) }
|
56
|
+
args[:hits] = hits unless where(conditions: args).exists?
|
57
|
+
find_or_create_by args
|
60
58
|
end
|
61
59
|
|
62
|
-
#
|
60
|
+
# Installs the required Mongoid configuration and image files.
|
61
|
+
#
|
62
|
+
# @return true
|
63
|
+
# @example
|
64
|
+
# HitCounter.install
|
65
|
+
def self.install
|
66
|
+
puts 'Configuring Mongoid and installing image files...'
|
67
|
+
full_gem_path = Gem::Specification.find_by_name('hit_counter').full_gem_path
|
68
|
+
system "rsync -ruv #{full_gem_path}/config ."
|
69
|
+
system "rsync -ruv #{full_gem_path}/public ."
|
70
|
+
end
|
71
|
+
|
72
|
+
# Instance methods: Overrides ================================================
|
73
|
+
|
74
|
+
# Sets the number of hits.
|
75
|
+
#
|
76
|
+
# @param value [Integer] the initial number of hits
|
77
|
+
# @return [Integer] the number of hits
|
78
|
+
# @example
|
79
|
+
# hc.hits = 100
|
80
|
+
def hits=(value)
|
81
|
+
self[:hits] = value.to_i
|
82
|
+
end
|
63
83
|
|
64
84
|
# Sets the URL to be tracked. The http prefix is optional.
|
65
85
|
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
def url=
|
71
|
-
self[:url] = HitCounter.normalize_url value
|
86
|
+
# @param value [String] the URL for the site being counted
|
87
|
+
# @return [String] the normalized URL
|
88
|
+
# @example
|
89
|
+
# hc.url = 'cnn.com'
|
90
|
+
def url=(value)
|
91
|
+
self[:url] = HitCounter.send(:normalize_url, value)
|
72
92
|
end
|
73
93
|
|
74
|
-
# Instance methods
|
94
|
+
# Instance methods ===========================================================
|
75
95
|
|
76
96
|
# Returns the hit count as a PNG image, using the specified style:
|
77
97
|
# 1 odometer
|
78
98
|
# 2 scout
|
79
99
|
# 3 Celtic
|
80
100
|
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
def image
|
86
|
-
image = HitCounter.cat_image
|
101
|
+
# @param style_number [String] the image style
|
102
|
+
# @return [Magick::Image] the current hit count as a PNG image
|
103
|
+
# @example
|
104
|
+
# hc.image = 1
|
105
|
+
def image(style_number)
|
106
|
+
image = HitCounter.send(:cat_image, hits.to_s, HitCounter.send(:normalize_style_number, style_number))
|
87
107
|
image.format = 'png'
|
88
108
|
image
|
89
109
|
end
|
90
110
|
|
91
111
|
# Increments the hit count and saves the HitCounter.
|
92
112
|
#
|
93
|
-
#
|
94
|
-
#
|
113
|
+
# @return [true] if the save was successful
|
114
|
+
# @example
|
115
|
+
# hc.increment
|
95
116
|
def increment
|
96
117
|
self.hits += 1
|
97
|
-
|
118
|
+
save
|
98
119
|
end
|
99
120
|
|
100
|
-
|
101
|
-
|
102
|
-
STYLES = ['odometer', 'scout', 'celtic']
|
121
|
+
# Defines the available image styles as an array. Add yours to the end.
|
122
|
+
STYLES = %w[odometer scout celtic].freeze
|
103
123
|
|
104
|
-
def self.cat_image
|
124
|
+
private_class_method def self.cat_image(number, style_index, images = Magick::ImageList.new)
|
105
125
|
return images.append(false) if number.blank?
|
106
|
-
|
126
|
+
|
127
|
+
cat_image(number[1..-1], style_index, images <<
|
128
|
+
Magick::Image.read("#{Rails.root}/public/images/digits/"\
|
129
|
+
"#{STYLES[style_index]}/#{number[0..0]}.png").first)
|
107
130
|
end
|
108
131
|
|
109
|
-
def self.normalize_style_number
|
132
|
+
private_class_method def self.normalize_style_number(value)
|
110
133
|
value = value.to_i
|
111
|
-
value -= 1 if value
|
134
|
+
value -= 1 if value.positive?
|
112
135
|
|
113
|
-
if value >= 0 && value < STYLES.size
|
114
|
-
|
115
|
-
|
116
|
-
value % 3
|
117
|
-
end
|
136
|
+
return value if value >= 0 && value < STYLES.size
|
137
|
+
|
138
|
+
value % 3
|
118
139
|
end
|
119
140
|
|
120
|
-
def self.normalize_url
|
141
|
+
private_class_method def self.normalize_url(value)
|
121
142
|
value !~ %r{^http://} ? "http://#{value}" : value
|
122
143
|
end
|
123
144
|
end
|
124
|
-
|
125
|
-
if defined? Rails
|
126
|
-
class Railtie < Rails::Railtie
|
127
|
-
rake_tasks do
|
128
|
-
namespace :hit_counter do
|
129
|
-
desc 'Install HitCounter into your app.'
|
130
|
-
task :install do
|
131
|
-
puts 'Installing required image files...'
|
132
|
-
system "rsync -ruv #{Gem.searcher.find('hit_counter').full_gem_path}/config ."
|
133
|
-
system "rsync -ruv #{Gem.searcher.find('hit_counter').full_gem_path}/public ."
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
data/lib/version.rb
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,109 +1,150 @@
|
|
1
|
-
|
1
|
+
# Copyright the HitCounter contributors.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
# frozen_string_literal: true
|
2
4
|
|
5
|
+
require "#{File.dirname(__FILE__)}/../spec_helper"
|
6
|
+
|
7
|
+
JAVASCRIPT_HACK = %q(eval("console.log('All your base belong to us!')"))
|
8
|
+
# rubocop:disable Metrics/BlockLength
|
3
9
|
describe HitCounter do
|
4
|
-
before
|
5
|
-
|
6
|
-
|
7
|
-
end
|
10
|
+
before(:all) { described_class.delete_all }
|
11
|
+
|
12
|
+
subject { described_class.get 'www.google.com' }
|
8
13
|
|
9
|
-
describe '
|
10
|
-
context '
|
11
|
-
|
12
|
-
|
14
|
+
describe '.get' do
|
15
|
+
context 'with existing URL' do
|
16
|
+
let!(:hit_counter2) { described_class.get subject.url, 10 }
|
17
|
+
|
18
|
+
describe '.count' do
|
19
|
+
it { expect(described_class.count).to eq 1 }
|
13
20
|
end
|
14
21
|
|
15
22
|
context 'with starting count 10' do
|
16
|
-
describe 'hits' do
|
17
|
-
|
23
|
+
describe '#hits' do
|
24
|
+
it { expect(hit_counter2.hits).to eq 10 }
|
18
25
|
end
|
19
26
|
end
|
20
27
|
end
|
28
|
+
context 'with new URL' do
|
29
|
+
before { described_class.get 'www.cnn.com' }
|
21
30
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
describe 'document count' do
|
26
|
-
specify { HitCounter.count.should == 2 }
|
31
|
+
describe '.count' do
|
32
|
+
it { expect(described_class.count).to eq 2 }
|
27
33
|
end
|
28
34
|
|
35
|
+
context 'with blank starting count' do
|
36
|
+
describe '#hits' do
|
37
|
+
it do
|
38
|
+
expect(described_class.get('www.nytimes.com', nil).hits).to eq 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
29
42
|
context 'with starting count 10' do
|
30
|
-
describe 'hits' do
|
31
|
-
|
43
|
+
describe '#hits' do
|
44
|
+
it { expect(described_class.get('online.wsj.com', 10).hits).to eq 10 }
|
32
45
|
end
|
33
46
|
end
|
34
47
|
end
|
48
|
+
context 'with JavaScript' do
|
49
|
+
before { described_class.delete_all }
|
50
|
+
|
51
|
+
subject { described_class.get(JAVASCRIPT_HACK) }
|
52
|
+
|
53
|
+
it do
|
54
|
+
subject.save
|
55
|
+
expect(subject).to be_invalid
|
56
|
+
end
|
57
|
+
end
|
35
58
|
end
|
59
|
+
describe '.install' do
|
60
|
+
before do
|
61
|
+
expect_any_instance_of(Object).to receive(:system).twice.with match(/config|public/)
|
62
|
+
end
|
36
63
|
|
64
|
+
it('copies configuration files and images') { described_class.install }
|
65
|
+
end
|
37
66
|
describe '#hits' do
|
38
|
-
|
39
|
-
|
40
|
-
it { should == 0 }
|
67
|
+
it { expect(subject.hits).to eq 0 }
|
41
68
|
|
42
69
|
context 'when incremented' do
|
43
|
-
before {
|
70
|
+
before { subject.increment }
|
44
71
|
|
45
|
-
|
72
|
+
it { expect(subject.hits).to eq 1 }
|
46
73
|
end
|
47
74
|
end
|
75
|
+
describe '#hits=' do
|
76
|
+
context 'with JavaScript' do
|
77
|
+
before { subject.hits = JAVASCRIPT_HACK }
|
48
78
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
it { should be_a Magick::Image }
|
53
|
-
pending 'should reflect hits'
|
79
|
+
it { expect(subject.hits).to eq 0 }
|
80
|
+
end
|
54
81
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
it 'should return 0' do
|
59
|
-
HitCounter.normalize_style_number(nil).should == 0
|
60
|
-
end
|
82
|
+
describe '#image' do
|
83
|
+
context 'with a valid :style_number' do
|
84
|
+
it { expect(subject.image('1').filename).to eq "./public/images/digits/odometer/#{subject.hits}.png" }
|
61
85
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
86
|
+
context 'with JavaScript' do
|
87
|
+
it {
|
88
|
+
expect(subject.image(JAVASCRIPT_HACK).filename).to eq "./public/images/digits/odometer/#{subject.hits}.png"
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
describe '#url=' do
|
93
|
+
context 'with JavaScript' do
|
94
|
+
before do
|
95
|
+
subject.url = JAVASCRIPT_HACK
|
96
|
+
subject.save
|
66
97
|
end
|
67
98
|
|
68
|
-
it
|
69
|
-
HitCounter.normalize_style_number('3').should == 2
|
70
|
-
end
|
99
|
+
it { expect(subject).to be_invalid }
|
71
100
|
end
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
101
|
+
end
|
102
|
+
describe '.normalize_style_number' do
|
103
|
+
context 'with nil' do
|
104
|
+
it { expect(described_class.send(:normalize_style_number, nil)).to be_zero }
|
105
|
+
end
|
106
|
+
context 'with empty string' do
|
107
|
+
it { expect(described_class.send(:normalize_style_number, '')).to be_zero }
|
108
|
+
end
|
109
|
+
context 'with JavaScript' do
|
110
|
+
it { expect(described_class.send(:normalize_style_number, JAVASCRIPT_HACK)).to be_zero }
|
111
|
+
end
|
112
|
+
context 'with number in range' do
|
113
|
+
{
|
114
|
+
'1' => 0,
|
115
|
+
'3' => 2
|
116
|
+
}.each do |input, output|
|
117
|
+
context "with '#{input}'" do
|
118
|
+
it do
|
119
|
+
expect(described_class.send(:normalize_style_number, input)).to eq output
|
82
120
|
end
|
83
121
|
end
|
84
122
|
end
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
123
|
+
end
|
124
|
+
context 'with number outside range' do
|
125
|
+
{
|
126
|
+
'-31' => 2,
|
127
|
+
'-1' => 2,
|
128
|
+
'4' => 0,
|
129
|
+
'34' => 0
|
130
|
+
}.each do |input, output|
|
131
|
+
context "with '#{input}'" do
|
132
|
+
it do
|
133
|
+
expect(described_class.send(:normalize_style_number, input)).to eq output
|
94
134
|
end
|
95
135
|
end
|
96
136
|
end
|
97
137
|
end
|
98
138
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
139
|
+
describe '.normalize_url' do
|
140
|
+
{
|
141
|
+
'cnn.com' => 'http://cnn.com',
|
142
|
+
'http://www.nytimes.com' => 'http://www.nytimes.com'
|
143
|
+
}.each do |input, output|
|
144
|
+
context "with '#{input}'" do
|
145
|
+
it { expect(described_class.send(:normalize_url, input)).to eq output }
|
146
|
+
end
|
107
147
|
end
|
108
148
|
end
|
109
|
-
end
|
149
|
+
end
|
150
|
+
# rubocop:enable Metrics/BlockLength
|
data/spec/spec_helper.rb
CHANGED
@@ -1,14 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'simplecov'
|
1
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
5
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
+
require 'addressable/uri'
|
7
|
+
require 'mongoid'
|
8
|
+
require 'RMagick'
|
3
9
|
require 'rspec'
|
10
|
+
|
4
11
|
require 'hit_counter'
|
5
12
|
|
6
|
-
Mongoid
|
7
|
-
|
13
|
+
Mongoid.load! 'config/mongoid.yml', :test
|
14
|
+
Mongo::Logger.logger.level = ::Logger::WARN
|
8
15
|
|
9
16
|
# Stub Rails root during tests.
|
10
17
|
module Rails
|
11
18
|
def self.root
|
12
19
|
'.'
|
13
20
|
end
|
14
|
-
end
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake'
|
24
|
+
|
25
|
+
# load rake tasks
|
26
|
+
# https://dev.to/cassidycodes/how-to-test-rake-tasks-with-rspec-without-rails-3mhb
|
27
|
+
module TaskFormat
|
28
|
+
extend ActiveSupport::Concern
|
29
|
+
included do
|
30
|
+
let(:task_name) { self.class.top_level_description.sub(/\Arake /, '') }
|
31
|
+
let(:tasks) { Rake::Task }
|
32
|
+
# Make the Rake task available as `task` in your examples:
|
33
|
+
subject(:task) { tasks[task_name] }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
RSpec.configure do |config|
|
38
|
+
config.before(:suite) do
|
39
|
+
Dir.glob('lib/tasks/*.rake').each { |r| Rake::DefaultLoader.new.load r }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Tag Rake specs with `:task` metadata or put them in the spec/tasks dir
|
43
|
+
config.define_derived_metadata(file_path: %r{/spec/tasks/}) do |metadata|
|
44
|
+
metadata[:type] = :task
|
45
|
+
end
|
46
|
+
|
47
|
+
config.include TaskFormat, type: :task
|
48
|
+
end
|
49
|
+
|
50
|
+
# silence output
|
51
|
+
RSpec.configure do |config|
|
52
|
+
original_stderr = $stderr
|
53
|
+
original_stdout = $stdout
|
54
|
+
config.before(:all) do
|
55
|
+
# Redirect stderr and stdout
|
56
|
+
$stderr = File.open(File::NULL, 'w')
|
57
|
+
$stdout = File.open(File::NULL, 'w')
|
58
|
+
end
|
59
|
+
config.after(:all) do
|
60
|
+
$stderr = original_stderr
|
61
|
+
$stdout = original_stdout
|
62
|
+
end
|
63
|
+
end
|
data.tar.gz.sig
ADDED
Binary file
|