gem_velocity 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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDhhODBiMzNlZWIzMjcyODdmMmYwZWI5NjdkM2M2YWYwZmIyZDQ1OA==
5
+ data.tar.gz: !binary |-
6
+ ZjZkNmI0MzgzNDU4ZDkxMzBlZWQ2YzMyZTIyYmY5ZWM3Zjg5ZWUwYg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MTFkY2Q5YmU2YTk1OTliMDAyMTU5MTdjY2I4MmE4YzU1OWE2NmNiY2QyNDYz
10
+ MWFlZDU5ODg3NzI4MTAyMTI1ZDMyMzc4ZDIxNTllODM5ODE1MjNmYmQ5MzUy
11
+ Y2EyODMyMzk3YTRkZDkyN2VlZjRmYmYyMjY3MWM1NTFjZTQyZmU=
12
+ data.tar.gz: !binary |-
13
+ ZTE2M2I5Mzk3NGUzMGI5ZWY3YWE1ODJmY2ExY2I4NjVkOGZkMmE2NzQ3Nzk5
14
+ NWNkMTllMzJjMzBkZGE1NzQ1ZmI3MzdmYjczNjQ3YTJkZjk4ZDE4MmQ5NWVh
15
+ M2ZkYjUzZTczNDNjMTUwM2FhNmVlZGMyMGM2Njk5MDJjMzE2YWE=
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ spec/tmp
19
+ public/
20
+ images/
21
+ spec/fixtures/vcr_cassettes
22
+ spec/fixtures/vcr_cassettes/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gem_velocity.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Shai Rosenfeld
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,41 @@
1
+ # GemVelocity
2
+
3
+ A way to see gem velocity. Right now it's just aggregated totals.
4
+
5
+ So, not a number of downloads each day, but rather just the general timeline of total downloads.
6
+
7
+ # Example
8
+
9
+ This spec below:
10
+
11
+ <pre>
12
+ it "has a shortcut graph method #1" do
13
+ VCR.use_cassette('velocitator-rails-multiple-graph-shortcut-3') do
14
+ velocitator = Velocitator.new("rails", ["4.0.0","3.2.14","2.3.5"])
15
+ file = velocitator.graph("/tmp")
16
+ File.exist?(file).should be_true
17
+ end
18
+ end
19
+ </pre>
20
+
21
+ Produces:
22
+
23
+ ![here](examples/rails-4.0.0-3.2.14-2.3.5.png)
24
+
25
+ This spec below (notice the date range):
26
+
27
+ <pre>
28
+ it "has a shortcut graph method #2" do
29
+ VCR.use_cassette('velocitator-rails-multiple-graph-shortcut-4') do
30
+ velocitator = Velocitator.new("rails", ["4.0.0","3.2.14","0.9.1"])
31
+ file = velocitator.graph("/tmp", [3.months.ago, Time.now])
32
+ File.exist?(file).should be_true
33
+ end
34
+ end
35
+ </pre>
36
+
37
+ Produces:
38
+
39
+ ![here](examples/rails-4.0.0-3.2.14-0.9.1.png)
40
+
41
+ Also, you should be able to pass in max,min values to size the graph. See `spec/` for more info.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+
9
+ # time (rm -rf spec/fixtures/vcr_cassettes && b rake)
data/TODO ADDED
@@ -0,0 +1,17 @@
1
+ move VCR to an :around spec
2
+ wtf? does a time period actually work?
3
+
4
+ ## Collection
5
+
6
+ Have a grapher class that takes a collection on singular and builds the corresponding gruff? Graph.buid(coolextion) vs collection.graph
7
+
8
+ All of them have same date range max min, same line_data size
9
+
10
+ Make sure to pad 0's
11
+
12
+ Earliest date, latest date
13
+
14
+ Most max of all
15
+
16
+ Have a date-calc abstraction that does all the padding calculation aggregation?
17
+
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gem_velocity/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gem_velocity"
8
+ spec.version = GemVelocity::VERSION
9
+ spec.authors = ["Shai Rosenfeld"]
10
+ spec.email = ["srosenfeld@engineyard.com"]
11
+ spec.description = %q{generate gem velocity images}
12
+ spec.summary = %q{generate gem velocity images}
13
+ spec.homepage = "https://github.com/shaiguitar/gem_velocities"
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_dependency "gruff"
22
+ spec.add_dependency "activesupport"
23
+ spec.add_dependency "gems"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "vcr"
30
+ spec.add_development_dependency "webmock", "= 1.13" # vcr requirement?
31
+ spec.add_development_dependency "timecop"
32
+
33
+ end
@@ -0,0 +1,10 @@
1
+ require "gem_velocity/version"
2
+ require "gem_velocity/helpers"
3
+ require "gem_velocity/gem_data"
4
+ require "gem_velocity/gruff_builder"
5
+ require "gem_velocity/velocitator"
6
+
7
+ require 'date'
8
+
9
+ module GemVelocity
10
+ end
@@ -0,0 +1,51 @@
1
+ require 'gems'
2
+
3
+ class GemData
4
+ def initialize(name)
5
+ @name = name
6
+ end
7
+
8
+ def versions
9
+ versions_metadata.map{|v| v["number"]}
10
+ end
11
+
12
+ def versions_built_at
13
+ h = {}
14
+ versions_metadata.map{|v| h.merge!(v["number"] => v["built_at"] )}
15
+ h
16
+ end
17
+
18
+ def downloads_day(version)
19
+ # todo rename method? aggregated downloads per day
20
+ total_so_far = 0
21
+ # start day 0 as first download day.
22
+ found_first_download = false
23
+ ret = downloads_metadata(version).map do |day,downloads_that_day|
24
+ if found_first_download
25
+ total_so_far += downloads_that_day
26
+ [day, total_so_far]
27
+ else
28
+ if !downloads_that_day.zero?
29
+ found_first_download = true
30
+ nil
31
+ end
32
+ end
33
+ end.compact
34
+ end
35
+
36
+ private
37
+
38
+ def versions_metadata
39
+ # cache api call.
40
+ @versions_metadata ||= Gems.versions(@name)
41
+ end
42
+
43
+ def downloads_metadata(version)
44
+ # cache api call.
45
+ @downloads_metadata ||= {}
46
+ return @downloads_metadata[version] if @downloads_metadata[version]
47
+ @downloads_metadata[version] ||= Gems.downloads(@name, version).to_a
48
+ end
49
+
50
+
51
+ end
@@ -0,0 +1,75 @@
1
+ require 'fileutils'
2
+ begin
3
+ require 'gruff'
4
+ rescue LoadError
5
+ puts "You may need to install imagemagick, if rmagick isn't around..."
6
+ end
7
+
8
+ class GruffBuilder
9
+
10
+ class NoData < StandardError; end
11
+
12
+ MIN_VALUE = 0
13
+ MAX_VALUE = 300
14
+
15
+ attr_accessor :root, :relative_path, :versions, :gem_name
16
+ attr_accessor :title, :labels, :line_datas, :min_value, :max_value
17
+
18
+ def initialize(root, relative_path, versions, gem_name, gruff_options = {})
19
+ @root = root || raise("you must set a root. default is root/public/images")
20
+ @relative_path = relative_path || "public/images/"
21
+ @versions = versions.is_a?(Array) ? versions : raise("versions must be an array")
22
+ @gem_name = gem_name
23
+ @title = gruff_options[:title] || ""
24
+ @labels = gruff_options[:labels] || {}
25
+ @line_datas = gruff_options[:line_datas]
26
+ @min_value = gruff_options[:min_value] || MIN_VALUE
27
+ @max_value = gruff_options[:max_value] || MAX_VALUE
28
+ end
29
+
30
+ def relative_filename
31
+ "#{@relative_path}#{filename}"
32
+ end
33
+
34
+ def filename
35
+ "#{graph_name(versions.join("-"))}.png"
36
+ end
37
+
38
+ def absolute_filename
39
+ "#{absolute_destination}/#{filename}"
40
+ end
41
+
42
+ def write
43
+ raise NoData if @line_datas.nil? || @line_datas.empty?
44
+ ensure_destination
45
+ gruff.title = @title
46
+ gruff.labels = @labels
47
+ @line_datas.each_with_index do |line_data,index|
48
+ gruff.data graph_name(@versions[index]), line_data
49
+ end
50
+ gruff.minimum_value = @min_value
51
+ gruff.maximum_value = @max_value
52
+ gruff.write(absolute_filename)
53
+ absolute_filename
54
+ end
55
+
56
+ private
57
+
58
+ def absolute_destination
59
+ File.expand_path(File.join(@root, @relative_path))
60
+ end
61
+
62
+ def ensure_destination
63
+ FileUtils.mkdir_p(File.expand_path(absolute_destination))
64
+ end
65
+
66
+ def graph_name(append_text = nil)
67
+ append_text = append_text.nil? ? "" : "-#{append_text}"
68
+ "#{gem_name}"+ append_text
69
+ end
70
+
71
+ def gruff
72
+ @gruff ||= Gruff::Line.new
73
+ end
74
+
75
+ end
@@ -0,0 +1,13 @@
1
+ module Helpers
2
+
3
+ extend self
4
+
5
+ def time_format_str(whatever)
6
+ Date.parse(whatever.to_s).strftime("%Y-%m-%dT%H:%M:%SZ")
7
+ end
8
+
9
+ def time_format_str_small(whatever)
10
+ Date.parse(whatever.to_s).strftime("%Y-%m-%d")
11
+ end
12
+
13
+ end
@@ -0,0 +1,131 @@
1
+ class Velocitator
2
+
3
+ include ::Helpers
4
+
5
+ attr_accessor :gem_name, :versions
6
+
7
+ # modifiers on the end result image being rendered.
8
+ attr_accessor :date_range, :max_value, :min_value, :root
9
+
10
+ def initialize(gem_name, versions)
11
+ @gem_name = gem_name || raise(ArgumentError, 'need a name')
12
+ @versions = if versions.is_a?(String)
13
+ [versions]
14
+ else
15
+ versions
16
+ end || raise(ArgumentError, 'required versions')
17
+ end
18
+
19
+ def date_range=(args)
20
+ return nil if args.nil?
21
+ unless args.is_a?(Array) && args.size == 2
22
+ raise(ArgumentError, "must pass a range with time objects like [start,end]")
23
+ end
24
+ @date_range = args.map{|t| time_format_str(t) }
25
+ end
26
+
27
+ def line_datas
28
+ versions.map do |v|
29
+ specific_days_in_range.map do |day_in_range|
30
+ day_in_range = time_format_str_small(day_in_range) #conform to rubygems api format
31
+ if gem_data.downloads_day(v).map {|day,total| day}.include?(day_in_range)
32
+ total = Hash[gem_data.downloads_day(v)][day_in_range]
33
+ else
34
+ 0
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def effective_date_range
41
+ # we allow overwriting by passing a date range.
42
+ if @date_range.is_a?(Array) && @date_range.compact.size==2
43
+ @date_range
44
+ else
45
+ default_date_range
46
+ end
47
+ end
48
+
49
+ # call, after you set all the attributes you want.
50
+ # you can set (or there will be fallback defaults)
51
+ #
52
+ # max, min
53
+ # date_range (leave nil for default values in either start or end)
54
+ def gruff_builder
55
+ opts = {
56
+ :title => "#{gem_name}-#{versions.join("-")}",
57
+ # just the first and last dates. give a small offset so it fits into the pciture.
58
+ # line_datas.first.size -2 should be the max of any one of the line-datas, all should be same size.
59
+ :labels => ({1 => time_format_str_small(effective_start_time), (line_datas.first.size-2) => time_format_str_small(effective_end_time) }),
60
+ :max_value => max_value || default_max_value,
61
+ :min_value => min_value || default_min_value,
62
+ :line_datas => line_datas
63
+ }
64
+ builder = GruffBuilder.new(@root || Dir.pwd,nil,versions,gem_name,opts)
65
+ builder
66
+ end
67
+
68
+ def graph(root_arg = nil, range = nil, min = nil, max = nil)
69
+ # if nil, defaults will be used
70
+ self.date_range = range
71
+ self.root = root_arg
72
+ self.max_value = max
73
+ self.min_value = min
74
+ gruff_builder.write
75
+ end
76
+
77
+ def specific_days_in_range
78
+ all_days = []
79
+ s = Date.parse(effective_start_time)
80
+ e = Date.parse(effective_end_time)
81
+ i = s
82
+ while (i <= e )
83
+ all_days << i
84
+ i += 1.day
85
+ end
86
+ all_days
87
+ end
88
+
89
+ def default_min_value
90
+ 0
91
+ end
92
+
93
+ def default_max_value
94
+ totals = []
95
+ versions.each {|v|
96
+ totals << gem_data.downloads_day(v).map {|day,total| total}
97
+ }
98
+ totals.flatten.compact.max
99
+ end
100
+
101
+ private
102
+
103
+ def effective_start_time
104
+ effective_date_range.first
105
+ end
106
+
107
+ def effective_end_time
108
+ effective_date_range.last
109
+ end
110
+
111
+ def default_date_range
112
+ range = default_start, default_end
113
+ end
114
+
115
+ def default_start
116
+ earliest_start = versions.map{|v| Date.parse(time_built(v)) }.min
117
+ default_start = time_format_str(earliest_start)
118
+ end
119
+
120
+ def default_end
121
+ default_end = time_format_str(Time.now)
122
+ end
123
+
124
+ def time_built(version)
125
+ gem_data.versions_built_at[version]
126
+ end
127
+
128
+ def gem_data
129
+ @gem_data ||= GemData.new(@gem_name)
130
+ end
131
+ end
@@ -0,0 +1,3 @@
1
+ module GemVelocity
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe GemData do
4
+ before do
5
+ Timecop.travel(Time.local(2013, 10, 7, 0, 0, 0))
6
+ Timecop.freeze
7
+ end
8
+
9
+ it "collects version info for a given gem" do
10
+ VCR.use_cassette('gem-data-haml-i18n-extractor-0.0.17-versions') do
11
+ GemData.new("haml-i18n-extractor").versions.should include "0.0.17"
12
+ end
13
+ end
14
+
15
+ it "maps built_at and versions for access" do
16
+ VCR.use_cassette('gem-data-haml-i18n-extractor-0.0.17-versions-built-at') do
17
+ GemData.new("haml-i18n-extractor").versions_built_at["0.0.17"].should == "2013-06-16T00:00:00Z"
18
+ end
19
+ end
20
+
21
+ it "can show download information" do
22
+ VCR.use_cassette('gem-data-haml-i18n-extractor-0.0.17-downloads-day') do
23
+ GemData.new("haml-i18n-extractor").downloads_day("0.0.17").should == [["2013-07-11", 3], ["2013-07-12", 5], ["2013-07-13", 6], ["2013-07-14", 6], ["2013-07-15", 8], ["2013-07-16", 10], ["2013-07-17", 16], ["2013-07-18", 16], ["2013-07-19", 19], ["2013-07-20", 20], ["2013-07-21", 20], ["2013-07-22", 22], ["2013-07-23", 23], ["2013-07-24", 29], ["2013-07-25", 29], ["2013-07-26", 29], ["2013-07-27", 29], ["2013-07-28", 29], ["2013-07-29", 30], ["2013-07-30", 32], ["2013-07-31", 34], ["2013-08-01", 34], ["2013-08-02", 34], ["2013-08-03", 34], ["2013-08-04", 34], ["2013-08-05", 36], ["2013-08-06", 36], ["2013-08-07", 36], ["2013-08-08", 39], ["2013-08-09", 39], ["2013-08-10", 39], ["2013-08-11", 39], ["2013-08-12", 40], ["2013-08-13", 42], ["2013-08-14", 43], ["2013-08-15", 45], ["2013-08-16", 45], ["2013-08-17", 46], ["2013-08-18", 46], ["2013-08-19", 46], ["2013-08-20", 46], ["2013-08-21", 47], ["2013-08-22", 49], ["2013-08-23", 53], ["2013-08-24", 53], ["2013-08-25", 54], ["2013-08-26", 54], ["2013-08-27", 56], ["2013-08-28", 56], ["2013-08-29", 58], ["2013-08-30", 58], ["2013-08-31", 58], ["2013-09-01", 60], ["2013-09-02", 62], ["2013-09-03", 63], ["2013-09-04", 63], ["2013-09-05", 65], ["2013-09-06", 67], ["2013-09-07", 67], ["2013-09-08", 67], ["2013-09-09", 68], ["2013-09-10", 68], ["2013-09-11", 68], ["2013-09-12", 73], ["2013-09-13", 73], ["2013-09-14", 73], ["2013-09-15", 73], ["2013-09-16", 74], ["2013-09-17", 74], ["2013-09-18", 74], ["2013-09-19", 75], ["2013-09-20", 76], ["2013-09-21", 76], ["2013-09-22", 76], ["2013-09-23", 76], ["2013-09-24", 79], ["2013-09-25", 83], ["2013-09-26", 90], ["2013-09-27", 90], ["2013-09-28", 90], ["2013-09-29", 92], ["2013-09-30", 92], ["2013-10-01", 92], ["2013-10-02", 92], ["2013-10-03", 92], ["2013-10-04", 94], ["2013-10-05", 94], ["2013-10-06", 94], ["2013-10-07", 95]]
24
+ end
25
+ end
26
+
27
+
28
+ end
29
+
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe GruffBuilder do
4
+ before do
5
+ @tmp_dir = SpecHelper.tmpdir
6
+ end
7
+
8
+ it "raises if no root or if versions isnt an array" do
9
+ lambda { builder = GruffBuilder.new(nil,nil,nil,nil, {}) }.should raise_error
10
+ end
11
+
12
+ it "has defaults" do
13
+ builder = GruffBuilder.new(@tmp_dir,nil,[],nil, {})
14
+ builder.root = @tmp_dir
15
+ builder.relative_path = "images/"
16
+ builder.versions = []
17
+ builder.gem_name = nil
18
+
19
+ builder.title = ""
20
+ builder.labels = {}
21
+ builder.line_datas = nil
22
+ builder.min_value = 0
23
+ builder.max_value = 300
24
+ end
25
+
26
+ it "has a filename" do
27
+ builder = GruffBuilder.new(@tmp_dir,nil,["0.0.17"],"foo-baz", {})
28
+ builder.relative_filename.should eq "public/images/foo-baz-0.0.17.png"
29
+ end
30
+
31
+ it "can not write a file if there is no line data" do
32
+ builder = GruffBuilder.new(@tmp_dir,nil,["0.0.17"],"foo-baz", {})
33
+ lambda { builder.write }.should raise_error GruffBuilder::NoData
34
+ end
35
+
36
+ it "can write out a file" do
37
+ builder = GruffBuilder.new(@tmp_dir,nil,["0.0.17"],"foo-baz", {})
38
+ builder.line_datas = [1,2,3]
39
+ builder.write
40
+ file = builder.absolute_filename
41
+ File.exists?(file).should be_true
42
+ end
43
+
44
+ it "can write out a file with gruff data" do
45
+ gruff_options = {
46
+ :title => "A pickture",
47
+ :labels => {1 => "label", 3 => "label2"},
48
+ :line_datas => [1,2,3,10,8,12],
49
+ :min_value => 0,
50
+ :max_value => 20,
51
+ }
52
+ builder = GruffBuilder.new(@tmp_dir,nil,["0.0.17"],"foo-baz", gruff_options)
53
+ builder.write
54
+ file = builder.absolute_filename
55
+ File.exists?(file).should be_true
56
+ end
57
+
58
+ end
59
+
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ class Whatever
4
+ extend Helpers
5
+ end
6
+
7
+ describe Helpers do
8
+
9
+ it "can format date" do
10
+ date = Date.parse("2013-09-15")
11
+ Whatever.time_format_str(date).should eq "2013-09-15T00:00:00Z"
12
+ end
13
+
14
+ it "can format str" do
15
+ date = "2013-09-15"
16
+ Whatever.time_format_str(date).should eq "2013-09-15T00:00:00Z"
17
+ end
18
+
19
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'with no time stubbing' do
4
+
5
+ it "has a shortcut graph method #1" do
6
+ VCR.use_cassette('velocitator-rails-multiple-graph-shortcut-3') do
7
+ velocitator = Velocitator.new("rails", ["4.0.0","3.2.14","2.3.5"])
8
+ file = velocitator.graph("/tmp")
9
+ File.exist?(file).should be_true
10
+ end
11
+ end
12
+
13
+ it "has a shortcut graph method #2" do
14
+ VCR.use_cassette('velocitator-rails-multiple-graph-shortcut-4') do
15
+ velocitator = Velocitator.new("rails", ["4.0.0","3.2.14","0.9.1"])
16
+ file = velocitator.graph("/tmp", [3.months.ago, Time.now])
17
+ File.exist?(file).should be_true
18
+ end
19
+ end
20
+
21
+ end
22
+
@@ -0,0 +1,23 @@
1
+ require 'gem_velocity'
2
+ require 'pry'
3
+ require 'vcr'
4
+ require 'active_support/all' # time
5
+ require 'timecop'
6
+
7
+ VCR.configure do |c|
8
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
9
+ c.hook_into :webmock # or :fakeweb
10
+ end
11
+
12
+ module SpecHelper
13
+ def self.tmpdir
14
+ File.expand_path File.join(File.dirname(__FILE__), "tmp")
15
+ end
16
+ end
17
+
18
+ RSpec.configure do |c|
19
+ c.after(:suite) do
20
+ FileUtils.rm_rf(SpecHelper.tmpdir)
21
+ end
22
+ end
23
+
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ describe Velocitator do
4
+
5
+ before do
6
+ # for Time.now
7
+ # Also, the 10 mins flattens out to 00: but we don't care at this point as it's day by day.
8
+ Timecop.travel(Time.local(2013, 9, 20, 10, 0, 0))
9
+ Timecop.freeze
10
+ end
11
+
12
+ after do
13
+ Timecop.return
14
+ end
15
+
16
+ it 'raises if you dont pass name and version(s)' do
17
+ lambda { Velocitator.new(nil,nil) }.should raise_error ArgumentError
18
+ end
19
+
20
+ describe "a specific version" do
21
+ it "sets a specific date range according to the gem's info" do
22
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-versions-info') do
23
+ velocitator = Velocitator.new("haml-i18n-extractor", "0.0.17")
24
+ velocitator.effective_date_range.should eq ["2013-06-16T00:00:00Z", "2013-09-20T00:00:00Z"]
25
+ end
26
+ end
27
+
28
+ it "can override the default time ranges if its in the range" do
29
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-versions-override') do
30
+ velocitator = Velocitator.new("haml-i18n-extractor", "0.0.17")
31
+ velocitator.date_range = [1.day.ago, Time.now]
32
+ velocitator.effective_date_range.should eq ["2013-09-19T00:00:00Z", "2013-09-20T00:00:00Z"]
33
+ velocitator.line_datas.size.should eq (velocitator.versions.size)
34
+ end
35
+ end
36
+
37
+ it "can set a max and min" do
38
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-versions') do
39
+ velocitator = Velocitator.new("haml-i18n-extractor", "0.0.17")
40
+ lambda {
41
+ velocitator.max_value = 500
42
+ velocitator.min_value = 10
43
+ }.should_not raise_error
44
+ end
45
+ end
46
+
47
+ it "can render a graph" do
48
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-versions-graph') do
49
+ velocitator = Velocitator.new("haml-i18n-extractor", "0.0.17")
50
+ velocitator.date_range = [1.day.ago, Time.now]
51
+ velocitator.root = SpecHelper.tmpdir
52
+ builder = velocitator.gruff_builder
53
+
54
+ # fixture / webmock / data etc.. if it fails, rm -rf spec/fixtures/vcr_cassettes
55
+ builder.line_datas.should == [[75,76]]
56
+ builder.title.should == "haml-i18n-extractor-0.0.17"
57
+ builder.labels.should == ({1=>"2013-09-19", (builder.line_datas.first.size-2) =>"2013-09-20"})
58
+ builder.max_value.should == 95
59
+ builder.min_value.should == 0
60
+
61
+ file = builder.write
62
+ File.exist?(file).should be_true
63
+ #`open #{file} -a preview.app`
64
+ #Kernel.sleep(10)
65
+ end
66
+ end
67
+
68
+ it "has a shortcut graph method #1" do
69
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-graph-shortcut-1') do
70
+ velocitator = Velocitator.new("haml-i18n-extractor", "0.0.17")
71
+ file = velocitator.graph(SpecHelper.tmpdir,[1.day.ago, Time.now])
72
+ File.exist?(file).should be_true
73
+ end
74
+ end
75
+
76
+ it "has a shortcut graph method #2" do
77
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-graph-shortcut-2') do
78
+ velocitator = Velocitator.new("haml-i18n-extractor", "0.0.17")
79
+ file = velocitator.graph
80
+ File.exist?(file).should be_true
81
+ end
82
+ end
83
+
84
+ it "has a shortcut graph metho #3" do
85
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-graph-shortcut-3') do
86
+ velocitator = Velocitator.new("haml-i18n-extractor", "0.0.17")
87
+ file = velocitator.graph(nil,nil,0,1000)
88
+ File.exist?(file).should be_true
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ describe "Multiple versions" do
95
+ before do
96
+ @some_versions = ["0.0.17", "0.0.5","0.0.10"]
97
+ Timecop.travel(Time.local(2013, 9, 20, 10, 0, 0))
98
+ Timecop.freeze
99
+
100
+ end
101
+
102
+ after do
103
+ Timecop.return
104
+ end
105
+
106
+
107
+ it "can initialize multiple versions" do
108
+ VCR.use_cassette('velocitator-haml-i18n-extractor-multiple-versions') do
109
+ velocitator = Velocitator.new("haml-i18n-extractor", @some_versions)
110
+ velocitator.versions.should == @some_versions
111
+ end
112
+ end
113
+
114
+ it "sets the earliest start range from to all of the versions info" do
115
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-multiple-versions-info') do
116
+ # some_versions.map{|v| GemData.new("haml-i18n-extractor").versions_built_at[v]}
117
+ # => ["2013-06-16T00:00:00Z", "2013-03-22T00:00:00Z", "2013-05-06T00:00:00Z"]
118
+ velocitator = Velocitator.new("haml-i18n-extractor", @some_versions)
119
+ velocitator.effective_date_range.should eq ["2013-03-22T00:00:00Z", "2013-09-20T00:00:00Z"]
120
+ end
121
+ end
122
+
123
+ it "sets the max value to the max of all of versions" do
124
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-multiple-versions-max-value') do
125
+ velocitator = Velocitator.new("haml-i18n-extractor", @some_versions)
126
+ velocitator.default_max_value.should eq 95
127
+ end
128
+ end
129
+
130
+ it "sets the max value to the max of all of versions" do
131
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-multiple-versions-max-value') do
132
+ velocitator = Velocitator.new("haml-i18n-extractor", @some_versions)
133
+ velocitator.default_max_value.should eq 95
134
+ end
135
+ end
136
+
137
+ it "should set the line data to an array of versions.size with equal length which should be the max value of any one of them" do
138
+ VCR.use_cassette('velocitator-haml-i18n-extractor-0.0.17-multiple-versions-line-data') do
139
+ velocitator = Velocitator.new("haml-i18n-extractor", @some_versions)
140
+ velocitator.line_datas.size.should == @some_versions.size
141
+ # all of them should be the same size, padded with 0's if there is no download info
142
+ velocitator.line_datas.map{|d| d.size }.uniq.size.should == 1
143
+ end
144
+ end
145
+
146
+ it "has a shortcut graph method" do
147
+ VCR.use_cassette('velocitator-haml-i18n-extractor-multiple-graph-shortcut') do
148
+ velocitator = Velocitator.new("haml-i18n-extractor", @some_versions)
149
+ file = velocitator.graph
150
+ puts file.inspect
151
+ File.exist?(file).should be_true
152
+ end
153
+ end
154
+ end
155
+
156
+
157
+ end
158
+
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem_velocity
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Shai Rosenfeld
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gruff
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
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: gems
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: vcr
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: '1.13'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: '1.13'
139
+ - !ruby/object:Gem::Dependency
140
+ name: timecop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: generate gem velocity images
154
+ email:
155
+ - srosenfeld@engineyard.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - .gitignore
161
+ - Gemfile
162
+ - LICENSE.txt
163
+ - README.md
164
+ - Rakefile
165
+ - TODO
166
+ - examples/rails-4.0.0-3.2.14-0.9.1.png
167
+ - examples/rails-4.0.0-3.2.14-2.3.5.png
168
+ - gem_velocity.gemspec
169
+ - lib/gem_velocity.rb
170
+ - lib/gem_velocity/gem_data.rb
171
+ - lib/gem_velocity/gruff_builder.rb
172
+ - lib/gem_velocity/helpers.rb
173
+ - lib/gem_velocity/velocitator.rb
174
+ - lib/gem_velocity/version.rb
175
+ - spec/gem_data_spec.rb
176
+ - spec/gruff_builder_spec.rb
177
+ - spec/helpers_spec.rb
178
+ - spec/no_time_cop_spec.rb
179
+ - spec/spec_helper.rb
180
+ - spec/velocitator_spec.rb
181
+ homepage: https://github.com/shaiguitar/gem_velocities
182
+ licenses:
183
+ - MIT
184
+ metadata: {}
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ! '>='
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ required_rubygems_version: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ! '>='
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project:
201
+ rubygems_version: 2.0.3
202
+ signing_key:
203
+ specification_version: 4
204
+ summary: generate gem velocity images
205
+ test_files:
206
+ - spec/gem_data_spec.rb
207
+ - spec/gruff_builder_spec.rb
208
+ - spec/helpers_spec.rb
209
+ - spec/no_time_cop_spec.rb
210
+ - spec/spec_helper.rb
211
+ - spec/velocitator_spec.rb
212
+ has_rdoc: