vault-tools 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vault-tools.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Chris Continanza
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.
@@ -0,0 +1,47 @@
1
+ # Vault Tools
2
+
3
+ Tooling for the Heroku Vault team to enable faster bootstrapping for Ruby projects.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'vault-tools'
10
+
11
+ ## Usage
12
+
13
+ ### Sinatra Base Class
14
+
15
+ Includes request logging and health endpoints
16
+
17
+ ```ruby
18
+ class Web < Vault::Web
19
+ helpers Vault::SinatraHelpers::HtmlSerializer
20
+
21
+ end
22
+ ```
23
+
24
+ ### Test Base Classes
25
+
26
+ Provides a Stock TestCase and Spec classes to customize.
27
+
28
+ To extend your test classes uniformly, use the Vault::
29
+
30
+ ```ruby
31
+
32
+ module MyTestHelperClass
33
+ def app; Vault::InvoiceBuilder::Web; end
34
+ end
35
+
36
+ Vault::TestHelpers.include_in_all Vault::InvoiceBuilderHelpers
37
+ ```
38
+
39
+ Now you have an `#app` method in your `Vault::TestCase`s and your `Vault::Spec`s
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,15 @@
1
+ require "vault-tools/version"
2
+
3
+ module Vault
4
+ def self.require
5
+ Kernel.require 'bundler'
6
+ STDERR.puts "Loading #{ENV['RACK_ENV']} environment..."
7
+ Bundler.require :default, ENV['RACK_ENV'].to_sym
8
+ end
9
+ end
10
+
11
+ require 'sinatra/base'
12
+
13
+ require 'vault-tools/sinatra_helpers/html_serializer'
14
+ require 'vault-tools/log'
15
+ require 'vault-tools/web'
@@ -0,0 +1,62 @@
1
+ module Vault
2
+ module Log
3
+ extend self
4
+
5
+ # Public: logs a counter
6
+ #
7
+ # name - Name of the counter
8
+ #
9
+ # Examples
10
+ # Log.count('foo')
11
+ # => "measure=true at=foo"
12
+ #
13
+ # Logs via Scrolls
14
+ def count(name)
15
+ log(measure: true, at: name)
16
+ end
17
+
18
+ # Public: logs an HTTP status code
19
+ #
20
+ # status - HTTP status code
21
+ #
22
+ # Examples
23
+ # Log.count_status(400)
24
+ # => "measure=true at=web-40"
25
+ #
26
+ # Logs via Scrolls
27
+ def count_status(status)
28
+ if prefix = status.to_s.match(/\d\d/)[0]
29
+ log(measure: true, at: "web-#{prefix}")
30
+ end
31
+ end
32
+
33
+ # Public: logs the time of a web request
34
+ #
35
+ # name - a Sinatra-formatted route url
36
+ # t - time (integer seconds or milliseconds)
37
+ #
38
+ # Examples
39
+ # Log.time()
40
+ # => "measure=true at=web-40"
41
+ #
42
+ # Logs via Scrolls
43
+ def time(name, t)
44
+ if name
45
+ name.
46
+ gsub(/\/:\w+/,''). #remove param names from path
47
+ gsub("/","-"). #remove slash from path
48
+ gsub(/[^A-Za-z0-9\-\_]/, ''). #only keep subset of chars
49
+ slice(1..-1).
50
+ tap {|res| log(measure: true, fn: res, elapsed: t)}
51
+ end
52
+ end
53
+
54
+ # Internal: log something
55
+ #
56
+ # Logs via Scrolls
57
+ def log(data, &blk)
58
+ Scrolls.log(data, &blk)
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,87 @@
1
+ require 'base64'
2
+
3
+ module Vault
4
+ module SinatraHelpers
5
+ # Public: Methods for including and serializing javascript and css files for HTML
6
+ #
7
+ # Examples
8
+ #
9
+ # # = js 'foo'
10
+ # # <%= js 'foo', 'bar', 'foo/bar' %>
11
+ #
12
+ # # = css 'foo'
13
+ # # <%= cssjs 'foo', 'bar', 'foo/bar' %>
14
+ module HtmlSerializer
15
+
16
+ # Public: create js markup by concatenating all javascript files
17
+ #
18
+ # files - one or many file names assuming settings.public_folder/js/ is the root
19
+ #
20
+ # Examples
21
+ #
22
+ # # given: settings.public_folder/js/hello.js
23
+ #
24
+ # js('hello')
25
+ # # => "
26
+ # # <script type='text/javascript'>
27
+ # # //<![CDATA[
28
+ # # alert("hello, world")
29
+ # # //]]>
30
+ # # </script>"
31
+ #
32
+ # Returns the HTML String
33
+ def js(*files)
34
+ files.inject('') do |string, filename|
35
+ filename = File.join('/js', filename) + '.js'
36
+ string + %{
37
+ <script type='text/javascript'>
38
+ //<![CDATA[
39
+ #{slurp(filename)}
40
+ //]]>
41
+ </script>
42
+ }
43
+ end
44
+ end
45
+
46
+ # Public: create css markup with file references replaced by data-urls
47
+ #
48
+ # files - one or many file names assuming settings.public_folder/css/ is the root
49
+ #
50
+ # Examples
51
+ #
52
+ # # given: settings.public_folder/css/invoice.css
53
+ #
54
+ # css('invoice')
55
+ # # => "
56
+ # # <style>
57
+ # # h1{background:url(data:image/png;base64;DEADBEEF)}
58
+ # # </style>"
59
+ #
60
+ # Returns the HTML String
61
+ def css(*files)
62
+ files.inject('') do |string, filename|
63
+ filename = File.join('/css', filename) + '.css'
64
+ string + "<style>\n#{inject_data_urls(slurp(filename))}\n</style>"
65
+ end
66
+ end
67
+
68
+ private
69
+ def inject_data_urls(css_text)
70
+ css_text.gsub(/url\('\/[^\)]+\)/) do |url|
71
+ filename = url.sub(/^url\(["']*/,'').sub(/["']*\)$/,'')
72
+ data = Base64.encode64(slurp(filename)).gsub(/\n/, '')
73
+ if filename =~ /font/
74
+ "url(data:font/opentype;base64,#{data})"
75
+ else
76
+ type = File.extname(filename)[1..-1]
77
+ "url(data:image/#{type};base64,#{data})"
78
+ end
79
+ end
80
+ end
81
+
82
+ def slurp(file)
83
+ File.read(File.join(settings.public_folder, file))
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,71 @@
1
+ require 'minitest/unit'
2
+ require 'minitest/spec'
3
+
4
+ # Base class for Vault test cases.
5
+ class Vault::TestCase < MiniTest::Unit::TestCase
6
+ def setup
7
+ super
8
+ Scrolls.stream = StringIO.new
9
+ end
10
+
11
+ def teardown
12
+ super
13
+ end
14
+ end
15
+
16
+ class Vault::Spec < MiniTest::Spec
17
+ before do
18
+ Scrolls.stream = StringIO.new
19
+ end
20
+ end
21
+
22
+ # Register our Spec class as the default
23
+ MiniTest::Spec.register_spec_type //, Vault::Spec
24
+
25
+ module Vault::TestHelpers
26
+ def self.include_in_all(_module)
27
+ Vault::TestCase.send(:include, _module)
28
+ Vault::Spec.send(:include, _module)
29
+ end
30
+
31
+ def save_and_open_page(html = nil, name = 'page.html', i = 1)
32
+ html ||= last_response.body
33
+ name = "page_#{i=i+1}.html" while File.exist? name
34
+ File.open(name, 'w') { |f| f << html }
35
+ system "open #{name}"
36
+ end
37
+
38
+ def set_doc(body)
39
+ @doc = Nokogiri::HTML(body)
40
+ end
41
+
42
+ def doc
43
+ @doc || Nokogiri::HTML(last_response.body)
44
+ end
45
+
46
+ def css(string)
47
+ doc.css(string)
48
+ end
49
+
50
+ def assert_includes_css(css_string)
51
+ exists = doc.css(css_string).first
52
+ assert exists, "Last response must include #{css_string}"
53
+ end
54
+
55
+ def assert_css(css_string, content)
56
+ e = css(css_string).first
57
+ assert e, "Element not found: #{css_string}"
58
+ assert_includes e.content, content
59
+ end
60
+
61
+ def with_env(key, value)
62
+ old_env = ENV[key]
63
+ ENV[key] = value
64
+ yield
65
+ ensure
66
+ ENV[key] = old_env
67
+ end
68
+ end
69
+
70
+ Vault::TestHelpers.include_in_all Rack::Test::Methods
71
+ Vault::TestHelpers.include_in_all Vault::TestHelpers
@@ -0,0 +1,5 @@
1
+ module Vault
2
+ module Tools
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+ require 'vault-tools/log'
2
+
3
+ module Vault
4
+ class Web < Sinatra::Base
5
+ def self.route(verb, action, *)
6
+ condition { @action = action }
7
+ super
8
+ end
9
+
10
+ before do
11
+ @start_request = Time.now
12
+ end
13
+
14
+ after do
15
+ Log.count_status(response.status)
16
+ Log.time(@action, Time.now - @start_request)
17
+ end
18
+
19
+ # Health check on HEAD
20
+ head('/') { status(200) }
21
+
22
+ # Trigger a 500 to test live monitoring and paging
23
+ head('/boom') { status(500) }
24
+
25
+ # Can do more than the head request
26
+ get('/health') { [200, 'OK'] }
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vault-tools/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "vault-tools"
8
+ gem.version = Vault::Tools::VERSION
9
+ gem.authors = ["Chris Continanza", "Jamu Kakar"]
10
+ gem.email = ["chriscontinanza@gmail.com", "csquared@heroku.com", "jkakar@heroku.com"]
11
+ gem.description = %q{Basic tools for Heroku Vault's Ruby projects}
12
+ gem.summary = %q{Test classes, base web classes, and helpers - oh my!}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'sinatra'
21
+ gem.add_dependency 'rack-test'
22
+ gem.add_dependency 'scrolls'
23
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vault-tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Continanza
9
+ - Jamu Kakar
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-12-07 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: rack-test
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: scrolls
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ description: Basic tools for Heroku Vault's Ruby projects
64
+ email:
65
+ - chriscontinanza@gmail.com
66
+ - csquared@heroku.com
67
+ - jkakar@heroku.com
68
+ executables: []
69
+ extensions: []
70
+ extra_rdoc_files: []
71
+ files:
72
+ - .gitignore
73
+ - Gemfile
74
+ - LICENSE.txt
75
+ - README.md
76
+ - Rakefile
77
+ - lib/vault-tools.rb
78
+ - lib/vault-tools/log.rb
79
+ - lib/vault-tools/sinatra_helpers/html_serializer.rb
80
+ - lib/vault-tools/test.rb
81
+ - lib/vault-tools/version.rb
82
+ - lib/vault-tools/web.rb
83
+ - vault-tools.gemspec
84
+ homepage: ''
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ segments:
97
+ - 0
98
+ hash: -2653287850415797196
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ segments:
106
+ - 0
107
+ hash: -2653287850415797196
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.23
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Test classes, base web classes, and helpers - oh my!
114
+ test_files: []