Standupguy 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5de7e3f00059222502c7d1da5129d2daddfb5853
4
+ data.tar.gz: 4d83f6f677e20f529241204e17bbf1582d617791
5
+ SHA512:
6
+ metadata.gz: cfa537dc8fe381f18395e6f45498613815bea3bdd30aea4fe76853329d316e18c94bdaa682648ca6b674a1cb1fb62e7dc4c5a3bb36890795a744cc7d15ccd591
7
+ data.tar.gz: eca38c2cb3fb5d0b30bcb3b587f7daddce6914ca0ae4b3b43de80839550869d5ef2aae50f9ffe4232c0b4032f0789316f729019d863cca5614c63ad3ddb44d7e
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ repo_token: SMdgGBpI2HGDSJE9f3G6t4jYDtyhgafvf
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.json
16
+ vendor/
data/.hound.yml ADDED
@@ -0,0 +1,2 @@
1
+ ruby:
2
+ enabled: true
data/.semver ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 6
5
+ :special: ''
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in Standupguy.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,33 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ # Note: The cmd option is now required due to the increasing number of ways
5
+ # rspec may be run, below are examples of the most common uses.
6
+ # * bundler: 'bundle exec rspec'
7
+ # * bundler binstubs: 'bin/rspec'
8
+ # * spring: 'bin/rsspec' (This will use spring if running and you have
9
+ # installed the spring binstubs per the docs)
10
+ # * zeus: 'zeus rspec' (requires the server to be started separetly)
11
+ # * 'just' rspec: 'rspec'
12
+ guard :rspec, cmd: 'bundle exec rspec' do
13
+ watch(%r{^spec/.+_spec\.rb$})
14
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
15
+ watch('spec/spec_helper.rb') { "spec" }
16
+
17
+ # Rails example
18
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
19
+ watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
20
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
21
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
22
+ watch('config/routes.rb') { "spec/routing" }
23
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
24
+ watch('spec/rails_helper.rb') { "spec" }
25
+
26
+ # Capybara features specs
27
+ watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
28
+
29
+ # Turnip features and steps
30
+ watch(%r{^spec/acceptance/(.+)\.feature$})
31
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
32
+ end
33
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Adam Panzer
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,33 @@
1
+ [![Coverage Status](https://img.shields.io/coveralls/apanzerj/Standupguy.svg)](https://coveralls.io/r/apanzerj/Standupguy) [![Test Status](https://travis-ci.org/apanzerj/Standupguy.svg?branch=master)](https://travis-ci.org/apanzerj/Standupguy)
2
+
3
+ # Standupguy
4
+
5
+ Quickly and easily manage your daily standup from the command line.
6
+
7
+ ## Installation
8
+
9
+ Install it yourself as:
10
+
11
+ $ gem install Standupguy
12
+
13
+ ## Usage
14
+
15
+ ### Adding an item
16
+
17
+ $ standupguy https://foo.zendesk.com/tickets/2
18
+
19
+ $ standupguy I did a thing today
20
+
21
+ ### Viewing your standup
22
+
23
+ $ standupguy --report TEXT
24
+
25
+ $ standupguy --report HTML
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it ( https://github.com/[my-github-username]/Standupguy/fork )
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ # Default directory to look in is `/specs`
5
+ # Run with `rake spec`
6
+ RSpec::Core::RakeTask.new(:spec) do |task|
7
+ task.rspec_opts = ['--color', '--format', 'documentation']
8
+ end
9
+
10
+ RSpec::Core::RakeTask.new(:sublime) do |task|
11
+ task.rspec_opts = ['--no-color']
12
+ end
13
+
14
+ task :default => :spec
15
+
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'Standupguy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "Standupguy"
8
+ spec.version = Standupguy::VERSION
9
+ spec.authors = ["Adam Panzer"]
10
+ spec.email = ["apanzerj@gmail.com"]
11
+ spec.summary = %q{Manage your daily activity or "Stand Up" quickly and easily}
12
+ spec.description = %q{Integrated with Zendesk. Manage your daily StandUp report easily.}
13
+ spec.homepage = "https://github.com/apanzerj/Standupguy"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "byebug"
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "rspec-nc"
26
+ spec.add_development_dependency "guard"
27
+ spec.add_development_dependency "guard-rspec"
28
+ spec.add_development_dependency "semver"
29
+ spec.add_development_dependency "mocha"
30
+ spec.add_development_dependency "webmock"
31
+ spec.add_development_dependency "coveralls"
32
+
33
+ spec.add_runtime_dependency "zendesk_api"
34
+ spec.add_runtime_dependency "launchy"
35
+ spec.add_runtime_dependency "haml"
36
+ end
data/bin/standupguy ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ require 'Standupguy'
3
+ require 'optparse'
4
+
5
+ options = {}
6
+
7
+ OptionParser.new do |opts|
8
+ opts.banner = 'Usage: standupguy [options]'
9
+
10
+ opts.on('-r', '--report=FORMAT', 'Show an HTML report') do |r|
11
+ options[:report] = r
12
+ end
13
+
14
+ opts.on('-d', '--date=YYYY-MM-DD', 'Date of standup. ALL for all') do |date|
15
+ options[:date] = date
16
+ end
17
+ end.parse!
18
+
19
+ options.merge!(item: ARGV.join(' ')) unless ARGV.empty?
20
+
21
+ Standupguy::Core.new(options)
data/lib/Standupguy.rb ADDED
@@ -0,0 +1,225 @@
1
+ require "zendesk_api"
2
+ require "tempfile"
3
+ require "haml"
4
+ require "launchy"
5
+ require "open-uri"
6
+
7
+ # StandUpGuy manages your daily standups by giving you a simple command line
8
+ # interface to add new items. It grabs contextual information from the items
9
+ # in your standup and fetches additional information from available sources.
10
+ #
11
+ # Currently supported external sources:
12
+ #
13
+ # 1. Zendesk
14
+ #
15
+ # To be implemented
16
+ #
17
+ # 1. Jira
18
+ #
19
+ module Standupguy
20
+ # Generic methods for pulling data from standup.json
21
+ module DataMethods
22
+ def date_key(date = :today)
23
+ date = date == :today ? DateTime.now : DateTime.strptime(date, "%Y-%m-%d")
24
+ date.strftime("%Y-%m-%d")
25
+ rescue ArgumentError
26
+ date = :today
27
+ retry
28
+ end
29
+
30
+ def filename
31
+ File.join(Standupguy::Core::DATA_ROOT, "standup.json")
32
+ end
33
+
34
+ def load_data
35
+ @current_standup = JSON.load(File.open(filename))
36
+ end
37
+
38
+ def write_data(current_standup)
39
+ File.open(filename, "w") do |f|
40
+ f << JSON.dump(current_standup)
41
+ end
42
+ end
43
+ end
44
+
45
+ # Generic methods that were moved from bin/standupguy to here
46
+ # in order to better test this code. Mostly init stuff.
47
+ class Core
48
+ DATA_ROOT = File.join(ENV["HOME"], ".standupguy")
49
+ def initialize(options)
50
+ first_time! unless Dir.exist?(DATA_ROOT)
51
+
52
+ if options[:item]
53
+ item = Standupguy::Item.new
54
+ item.add_to_today(options[:item])
55
+ item.save
56
+ date = DateTime.now.strftime("%Y-%m-%d")
57
+ options = { report: "TEXT", date: date }.merge(options)
58
+ end
59
+
60
+ report(options).show unless options[:report].nil?
61
+ end
62
+
63
+ def report(options)
64
+ case options[:report]
65
+ when "HTML"
66
+ Standupguy::HTMLReport.new(options[:date])
67
+ when "TEXT"
68
+ Standupguy::TextReport.new(options[:date])
69
+ when "EMAIL"
70
+ Standupguy::EmailReport.new(options[:date])
71
+ end
72
+ end
73
+
74
+ def first_time!
75
+ Kernel.puts("First time running...\nCreating data directory")
76
+ Dir.mkdir(DATA_ROOT)
77
+ File.open(File.join(DATA_ROOT, "standup.json"), "a+").close
78
+ end
79
+ end
80
+
81
+ # Generic methods for all types of report.
82
+ class Report
83
+ include DataMethods
84
+ attr_accessor :current_standup, :date
85
+
86
+ def initialize(date = nil)
87
+ @current_standup = JSON.load(File.open(filename))
88
+ date ||= "ALL"
89
+ @date = date == "ALL" ? :all : date_key(date)
90
+ end
91
+
92
+ def link
93
+ "file:///#{file.path}"
94
+ end
95
+
96
+ def template(file)
97
+ spec = Gem::Specification.find_by_name("Standupguy")
98
+ gem_root = spec.gem_dir
99
+ File.read(File.join(gem_root, "lib", "Standupguy", file))
100
+ end
101
+
102
+ def data(date = :all)
103
+ scope = @current_standup
104
+ scope = { date => @current_standup[date] } unless date == :all
105
+ scope
106
+ end
107
+ end
108
+
109
+ # HTML Formatted report. Creates a tempfile that is deleted in 5 seconds.
110
+ # Tempfile is opened in browser using Launchy.
111
+ class HTMLReport < Report
112
+ def show
113
+ File.write(file, render)
114
+ file.close
115
+ Launchy.open link
116
+ Kernel.sleep 5
117
+ file.unlink
118
+ end
119
+
120
+ def render
121
+ ::Haml::Engine.new(template("report.html.haml")).
122
+ render(Object.new, standup: data(@date))
123
+ end
124
+
125
+ def file
126
+ @file ||= Tempfile.new(["report", ".html"])
127
+ end
128
+ end
129
+
130
+ # Text formatted report. Output to STDOUT
131
+ class TextReport < Report
132
+ def show
133
+ puts render
134
+ end
135
+
136
+ def render
137
+ ::Haml::Engine.new(template("report.txt.haml")).
138
+ render(Object.new, standup: data(@date))
139
+ end
140
+ end
141
+
142
+ # Basically a text report that is outputted to a mailto link. Only supports
143
+ # the Mac OS operating system at the moment.
144
+ class EmailReport < TextReport
145
+ def show
146
+ @date = !date.nil? ? date : date_key(:today)
147
+ body = render
148
+ parameters = ::URI.encode_www_form([
149
+ ["subject", "StandUp for #{date_key(:today)}"],
150
+ ["body", body]])
151
+ link = "mailto:?#{parameters}"
152
+ Kernel.system("open '#{link}'") if mac?
153
+ end
154
+
155
+ def render
156
+ ::Haml::Engine.new(template("report.email.haml")).
157
+ render(Object.new, standup: data(@date))
158
+ end
159
+
160
+ def mac?
161
+ Launchy::Detect::HostOs.new.host_os.start_with?("darwin")
162
+ end
163
+ end
164
+
165
+ # Basic Item class. Each line in your standup is an Item.
166
+ class Item
167
+ include DataMethods
168
+
169
+ attr_accessor :data
170
+
171
+ def method_missing(method, *args)
172
+ return unless [:description=, :name=, :date=].include?(method)
173
+ method = method.to_s.chop.to_sym
174
+ @data[method] = args.first
175
+ end
176
+
177
+ def save
178
+ current_standup = load_data
179
+ current_standup ||= { date_key => [] }
180
+ data_exists = current_standup.keys.include?(date_key)
181
+ current_standup[date_key] = [] unless data_exists
182
+ current_standup[date_key] << @data
183
+ write_data(current_standup)
184
+ end
185
+
186
+ def add_to_today(item)
187
+ @data ||= { description: "", name: "", date: "" }
188
+ ticket = TicketUrl.new(item)
189
+ if ticket.valid?
190
+ zendesk_ticket = client(ticket.subdomain).tickets.find(id: ticket.id)
191
+ self.description = "#{item} => (#{zendesk_ticket.subject})"
192
+ else
193
+ self.description = item
194
+ end
195
+
196
+ self.name = `whoami`.chop
197
+ self.date = key
198
+ end
199
+
200
+ def client(subdomain)
201
+ @client ||= ZendeskAPI::Client.new do |config|
202
+ config.url = "https://#{subdomain}.zendesk.com/api/v2"
203
+ config.username = ENV["zendesk_user"]
204
+ config.token = ENV["zendesk_token"]
205
+ end
206
+ end
207
+
208
+ TicketUrl = Struct.new(:url, :subdomain, :id) do
209
+ CLASSIC_TICKET = %r{https?:\/\/(.*?)\.zendesk.com\/[a-z].*?\/(.*)}
210
+ LOTUS_TICKET = \
211
+ %r{https?:\/\/(.*?)\.zendesk.com\/agent\/#?\/?tickets\/(\d+)\/?.*?}
212
+ def initialize(url)
213
+ [LOTUS_TICKET, CLASSIC_TICKET].each do |pattern|
214
+ subdomain, id = url.downcase.scan(pattern).flatten
215
+ super(url, subdomain, id)
216
+ return if self.valid?
217
+ end
218
+ end
219
+
220
+ def valid?
221
+ !(id.nil? && subdomain.nil?)
222
+ end
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,4 @@
1
+ - standup.keys.each do |date|
2
+ ="Date: #{date}"
3
+ - standup[date].each do |i|
4
+ ="* #{i["description"]}"
@@ -0,0 +1,6 @@
1
+ %html
2
+ - standup.keys.each do |date|
3
+ %span="Date: #{date}"
4
+ %ul
5
+ - standup[date].each do |i|
6
+ %li=i["description"]
@@ -0,0 +1,4 @@
1
+ - standup.keys.each do |date|
2
+ ="Date: #{date}"
3
+ - standup[date].each do |i|
4
+ ="* #{i["description"]}"
@@ -0,0 +1,3 @@
1
+ module Standupguy
2
+ VERSION = "0.0.6"
3
+ end
data/spec/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/spec/core_spec.rb ADDED
@@ -0,0 +1,73 @@
1
+ require "spec_helper"
2
+ require_relative "../lib/Standupguy"
3
+
4
+ describe Standupguy::Core do
5
+ before do
6
+ Standupguy::Item.any_instance.stubs(:save)
7
+ @file = create_test_file!
8
+ end
9
+
10
+ subject{ {} }
11
+ it "takes options" do
12
+ Standupguy::Core.new(subject)
13
+ end
14
+
15
+ it "can generate a TEXT report" do
16
+ subject.merge!(report: "TEXT")
17
+ Standupguy::TextReport.any_instance.expects(:show)
18
+ Standupguy::Core.new(subject)
19
+ end
20
+
21
+ it "can generate an HTML report" do
22
+ subject.merge!(report: "HTML")
23
+ Standupguy::HTMLReport.any_instance.expects(:show)
24
+ Standupguy::Core.new(subject)
25
+ end
26
+
27
+ it "can generate an EMAIL report" do
28
+ subject.merge!(report: "EMAIL")
29
+ Standupguy::EmailReport.any_instance.expects(:show)
30
+ Standupguy::Core.new(subject)
31
+ end
32
+
33
+ describe "adding an item" do
34
+ it "can add an item" do
35
+ subject.merge!(item: "Test Item", report: nil)
36
+ Standupguy::Core.new(subject)
37
+ end
38
+
39
+ it "runs a text report for today" do
40
+ subject.merge!(:item => "Test Item")
41
+ report = stub
42
+ Standupguy::TextReport.expects(:new).
43
+ with(DateTime.now.strftime("%Y-%m-%d")).returns(report)
44
+ report.expects(:show)
45
+ Standupguy::Core.new(subject)
46
+ end
47
+ end
48
+
49
+ describe "#first_time!" do
50
+ before do
51
+ Kernel.stubs(:puts)
52
+ Dir.stubs(:exist?).returns(false)
53
+ end
54
+
55
+ it "is called when no directory exists" do
56
+ Standupguy::Core.any_instance.expects(:first_time!)
57
+ Standupguy::Core.new({})
58
+ end
59
+
60
+ it "creates the directory and makes the file" do
61
+ File.expects(:open).
62
+ with(File.join(Standupguy::Core::DATA_ROOT, "standup.json"), "a+").
63
+ returns(@file)
64
+ Dir.expects(:mkdir)
65
+ Standupguy::Core.new({})
66
+ end
67
+ end
68
+
69
+ after do
70
+ @file.close
71
+ @file.unlink
72
+ end
73
+ end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+ require_relative "../lib/Standupguy"
3
+ include Standupguy::DataMethods
4
+
5
+ describe Standupguy::DataMethods do
6
+ describe "#date_key" do
7
+ it "returns the current date formatted string when give :today" do
8
+ expect(date_key(:today)).to be_a_kind_of(String)
9
+ expect(date_key(:today)).to match(/\d{4}-\d{2}-\d{2}/)
10
+ expect(date_key(:today)).to eq(DateTime.now.strftime("%Y-%m-%d"))
11
+ end
12
+
13
+ it "returns the date formatted sting when given same" do
14
+ expect(date_key("2014-10-10")).to be_a_kind_of(String)
15
+ expect(date_key("2014-10-10")).to match(/\d{4}-\d{2}-\d{2}/)
16
+ expect(date_key("2014-10-10")).to eq("2014-10-10")
17
+ end
18
+
19
+ it "returns today when given a non date formatted string" do
20
+ expect(date_key("foo")).to eq(DateTime.now.strftime("%Y-%m-%d"))
21
+ end
22
+ end
23
+
24
+ describe "#filename" do
25
+ it do
26
+ result = File.join(Standupguy::Core::DATA_ROOT, "standup.json")
27
+ expect(filename).to eq(result)
28
+ end
29
+ end
30
+
31
+ describe "#load_data" do
32
+ before do
33
+ @file = Tempfile.new("foo")
34
+ stubs(filename: @file.path)
35
+ end
36
+
37
+ it "reads an existing file" do
38
+ File.write(@file, '{"foo": "bar"}')
39
+ expect(load_data).to eq({"foo" => "bar"})
40
+ end
41
+
42
+ it "writes the current standup" do
43
+ write_data({"foo" => "bar"})
44
+ expect(File.read(@file)).to eq('{"foo":"bar"}')
45
+ File.delete(@file)
46
+ end
47
+
48
+ after do
49
+ @file.close
50
+ @file.unlink
51
+ end
52
+ end
53
+ end
data/spec/item_spec.rb ADDED
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+ require_relative "../lib/Standupguy"
3
+
4
+ describe Standupguy::Item do
5
+ describe "#add_to_today" do
6
+ subject(:item) { Standupguy::Item.new }
7
+
8
+ context "for zendesk tickets" do
9
+ before do
10
+ expect_zendesk("foo", "api/v2/tickets/1").
11
+ to_return(headers: {"Content-Type" => "application/json"}, body: JSON.dump("ticket" => {"subject" => "test ticket"}))
12
+ item.add_to_today("https://foo.zendesk.com/tickets/1")
13
+ end
14
+
15
+ it "includes the ticket subject in the description" do
16
+ expect(item.data[:description]).to match(/test ticket/)
17
+ end
18
+
19
+ it "includes the original url" do
20
+ expect(item.data[:description]).to match(/foo.zendesk.com\/tickets\/1/)
21
+ end
22
+ end
23
+
24
+ context "for non-zendesk tickets" do
25
+ it "takes an item" do
26
+ item.add_to_today("foob")
27
+ expect(item.data[:description]).to match(/foob/)
28
+ expect(item.data[:name]).to match(`whoami`.chop)
29
+ expect(item.data[:date]).to match(key)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#save" do
35
+ before do
36
+ @datafile = create_test_file!
37
+ end
38
+
39
+ subject(:item) do
40
+ test_item = Standupguy::Item.new
41
+ test_item.add_to_today("foo")
42
+ test_item
43
+ end
44
+
45
+ it "writes a file" do
46
+ item.save
47
+ expect_datafile(@datafile, %r{foo})
48
+ end
49
+
50
+ after do
51
+ @datafile.close
52
+ @datafile.unlink
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+ require_relative "../lib/Standupguy"
3
+
4
+ describe Standupguy::Report do
5
+ before do
6
+ @datafile = create_test_file!
7
+ @item = Standupguy::Item.new
8
+ @item.add_to_today("foob a doob")
9
+ @item.save
10
+ end
11
+
12
+ describe "#initialize" do
13
+ subject(:report) { Standupguy::Report.new }
14
+
15
+ it "reads current standup data" do
16
+ expect(report.current_standup[key].first["description"]).to match(@item.data[:description])
17
+ end
18
+ end
19
+
20
+ describe "#link" do
21
+ subject(:report) { Standupguy::HTMLReport.new }
22
+
23
+ it "returns a link" do
24
+ expect(report.link).to match(%r{file:///})
25
+ end
26
+ end
27
+
28
+ describe "#data" do
29
+ let(:report) { Standupguy::Report.new }
30
+
31
+ it "returns the current_standup without a date" do
32
+ expect(report.data).to be(report.current_standup)
33
+ end
34
+
35
+ it "returns scoped data when passed a date" do
36
+ report.instance_variable_set(:@current_standup, {"2014-10-10"=>["foo"], "2014-10-11"=>[nil]})
37
+ expect(report.data("2014-10-10").first).to eq(["2014-10-10", ["foo"]])
38
+ end
39
+ end
40
+
41
+ describe "#mac?" do
42
+ subject { Standupguy::EmailReport.new }
43
+ it "tells me if I'm on a mac" do
44
+ host_os = Launchy::Detect::HostOs.new.host_os
45
+ expect(subject.mac?).to be(host_os.start_with?("darwin"))
46
+ end
47
+ end
48
+
49
+ [:html, :txt, :email].each do |format|
50
+ describe "#show" do
51
+ subject(:report) do
52
+ case format
53
+ when :html then Standupguy::HTMLReport.new
54
+ when :txt then Standupguy::TextReport.new
55
+ when :email then Standupguy::EmailReport.new
56
+ end
57
+ end
58
+
59
+ before do
60
+ Launchy.stubs(:open)
61
+ Standupguy::EmailReport.any_instance.stubs(:mac?).returns(true)
62
+ Kernel.stubs(:sleep)
63
+ Kernel.stubs(:system)
64
+ Standupguy::TextReport.send(:define_method, :puts) { |*args| "" }
65
+ end
66
+
67
+ describe format.to_s do
68
+ it "calls #render" do
69
+ report.expects(:render).returns("foo")
70
+ report.show
71
+ end
72
+
73
+ describe "#render" do
74
+ it "renders a HAML template" do
75
+ @file = "= key"
76
+ report.expects(:template).with("report.#{format}.haml").returns(@file)
77
+ expect(report.render).to match(key)
78
+ end
79
+
80
+ it "is rendered with the current_standup" do
81
+ expect(report.render).to match(/foob a doob/)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ after do
89
+ @datafile.close
90
+ @datafile.unlink
91
+ end
92
+ end
@@ -0,0 +1,43 @@
1
+ require 'webmock/rspec'
2
+ require 'json'
3
+ require 'byebug'
4
+ require 'coveralls'
5
+ Coveralls::Output.silent = true
6
+ Coveralls.wear!
7
+
8
+ RSpec.configure do |config|
9
+ config.run_all_when_everything_filtered = true
10
+ config.mock_with :mocha
11
+ config.order = 'random'
12
+ end
13
+
14
+ def expect_zendesk(subdomain, endpoint)
15
+ ENV["zendesk_user"] = "foo@bar.com"
16
+ ENV["zendesk_token"] = "123abc"
17
+ crazy_piece = "foo%40bar.com%2Ftoken:123abc"
18
+ stub_request(:get, %r{#{subdomain}.zendesk.com.#{endpoint}})
19
+ end
20
+
21
+ def create_test_file!(temp_file = true)
22
+ datafile = Tempfile.new(["standup", ".json"], File.join(`pwd`.chop, "test")) if temp_file
23
+ datafile ||= File.join(`pwd`.chop, "test", "standup.json")
24
+ stub_filename(datafile)
25
+ end
26
+
27
+ def stub_filename(datafile)
28
+ path = datafile.is_a?(String) ? datafile : datafile.path
29
+ Standupguy::DataMethods.stubs(:filename).returns(path)
30
+ Standupguy::Report.any_instance.stubs(:filename).returns(path)
31
+ Standupguy::Item.any_instance.stubs(:filename).returns(path)
32
+ datafile
33
+ end
34
+
35
+ def expect_datafile(file, pattern)
36
+ data = File.read(file.path)
37
+ expect(data).to match(pattern)
38
+ end
39
+
40
+ def key(date=:today)
41
+ return DateTime.now.strftime("%Y-%m-%d") if date==:today
42
+ return DateTime.strptime(date,"%Y-%m-%d") if date.is_a?(String)
43
+ end
@@ -0,0 +1 @@
1
+ require "spec_helper"
data/test/.gitkeep ADDED
File without changes
metadata ADDED
@@ -0,0 +1,274 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Standupguy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Adam Panzer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
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: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-nc
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: guard
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: guard-rspec
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: semver
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: mocha
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: webmock
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
+ - !ruby/object:Gem::Dependency
154
+ name: coveralls
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: zendesk_api
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: launchy
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: haml
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ description: Integrated with Zendesk. Manage your daily StandUp report easily.
210
+ email:
211
+ - apanzerj@gmail.com
212
+ executables:
213
+ - standupguy
214
+ extensions: []
215
+ extra_rdoc_files: []
216
+ files:
217
+ - ".coveralls.yml"
218
+ - ".gitignore"
219
+ - ".hound.yml"
220
+ - ".semver"
221
+ - ".travis.yml"
222
+ - Gemfile
223
+ - Guardfile
224
+ - LICENSE.txt
225
+ - README.md
226
+ - Rakefile
227
+ - Standupguy.gemspec
228
+ - bin/standupguy
229
+ - lib/Standupguy.rb
230
+ - lib/Standupguy/report.email.haml
231
+ - lib/Standupguy/report.html.haml
232
+ - lib/Standupguy/report.txt.haml
233
+ - lib/Standupguy/version.rb
234
+ - spec/.rspec
235
+ - spec/core_spec.rb
236
+ - spec/data_methods_spec.rb
237
+ - spec/item_spec.rb
238
+ - spec/report_spec.rb
239
+ - spec/spec_helper.rb
240
+ - spec/standupguy_spec.rb
241
+ - test/.gitkeep
242
+ homepage: https://github.com/apanzerj/Standupguy
243
+ licenses:
244
+ - MIT
245
+ metadata: {}
246
+ post_install_message:
247
+ rdoc_options: []
248
+ require_paths:
249
+ - lib
250
+ required_ruby_version: !ruby/object:Gem::Requirement
251
+ requirements:
252
+ - - ">="
253
+ - !ruby/object:Gem::Version
254
+ version: '0'
255
+ required_rubygems_version: !ruby/object:Gem::Requirement
256
+ requirements:
257
+ - - ">="
258
+ - !ruby/object:Gem::Version
259
+ version: '0'
260
+ requirements: []
261
+ rubyforge_project:
262
+ rubygems_version: 2.2.2
263
+ signing_key:
264
+ specification_version: 4
265
+ summary: Manage your daily activity or "Stand Up" quickly and easily
266
+ test_files:
267
+ - spec/.rspec
268
+ - spec/core_spec.rb
269
+ - spec/data_methods_spec.rb
270
+ - spec/item_spec.rb
271
+ - spec/report_spec.rb
272
+ - spec/spec_helper.rb
273
+ - spec/standupguy_spec.rb
274
+ - test/.gitkeep