Standupguy 0.0.6

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,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