gem_velocity 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: