This repository has been archived by the owner on Sep 17, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
James Couball
committed
May 7, 2015
0 parents
commit 2df972e
Showing
42 changed files
with
2,705 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Created by .ignore support plugin (hsz.mobi) | ||
### JetBrains template | ||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm | ||
|
||
*.iml | ||
|
||
## Directory-based project format: | ||
.idea/ | ||
# if you remove the above rule, at least ignore the following: | ||
|
||
# User-specific stuff: | ||
# .idea/workspace.xml | ||
# .idea/tasks.xml | ||
# .idea/dictionaries | ||
|
||
# Sensitive or high-churn files: | ||
# .idea/dataSources.ids | ||
# .idea/dataSources.xml | ||
# .idea/sqlDataSources.xml | ||
# .idea/dynamic.xml | ||
# .idea/uiDesigner.xml | ||
|
||
# Gradle: | ||
# .idea/gradle.xml | ||
# .idea/libraries | ||
|
||
# Mongo Explorer plugin: | ||
# .idea/mongoSettings.xml | ||
|
||
## File-based project format: | ||
*.ipr | ||
*.iws | ||
|
||
## Plugin-specific files: | ||
|
||
# IntelliJ | ||
out/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
|
||
|
||
### Ruby template | ||
*.gem | ||
*.rbc | ||
/.config | ||
/coverage/ | ||
/InstalledFiles | ||
/pkg/ | ||
/spec/reports/ | ||
/test/tmp/ | ||
/test/version_tmp/ | ||
/tmp/ | ||
|
||
## Specific to RubyMotion: | ||
.dat* | ||
.repl_history | ||
build/ | ||
|
||
## Documentation cache and generated files: | ||
/.yardoc/ | ||
/_yardoc/ | ||
/doc/ | ||
/rdoc/ | ||
|
||
## Environment normalisation: | ||
/.bundle/ | ||
/vendor/bundle | ||
/lib/bundler/man/ | ||
|
||
# for a library or gem, you might want to ignore these files since the code is | ||
# intended to run in multiple environments; otherwise, check them in: | ||
Gemfile.lock | ||
.ruby-version | ||
.ruby-gemset | ||
|
||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: | ||
.rvmrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Style/Copyright: | ||
Enabled: true | ||
Notice: 'Copyright \(c\) 20[1-3][0-9] Yahoo Inc\.' | ||
AutocorrectNotice: "# Copyright (c) 2015 Yahoo Inc.\n# Copyrights licensed under the New BSD License.\n# See the accompanying LICENSE file for terms.\n" | ||
|
||
Metrics/LineLength: | ||
Max: 100 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Copyright (c) 2015 Yahoo Inc. | ||
# Copyrights licensed under the New BSD License. | ||
# See the accompanying LICENSE file for terms. | ||
|
||
source 'https://rubygems.org' | ||
|
||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
Copyright (c) 2015, Yahoo! Inc. All rights reserved. | ||
|
||
Redistribution and use of this software in source and binary forms, | ||
with or without modification, are permitted provided that the following | ||
conditions are met: | ||
|
||
* Redistributions of source code must retain the above | ||
copyright notice, this list of conditions and the | ||
following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above | ||
copyright notice, this list of conditions and the | ||
following disclaimer in the documentation and/or other | ||
materials provided with the distribution. | ||
|
||
* Neither the name of Yahoo! Inc. nor the names of its | ||
contributors may be used to endorse or promote products | ||
derived from this software without specific prior | ||
written permission of Yahoo! Inc. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# MySQL Expectations | ||
|
||
The `mysql_expectations` gem makes it easy to write RSpec expectations for MySQL | ||
schemas and data. | ||
|
||
**Continuous Delivery Testing for Databases** | ||
|
||
I make changes to the structure of my databases in a Continuous Delivery pipeline | ||
using Liquibase. While this works great, it is hard for a human to understand | ||
what the current structure of the database should be just by looking at the | ||
change log. This can make it hard to successfully write new change log entries. | ||
Specs written using this gem document the intended outcome of running the Liquibase | ||
change log. This gives additional confidence that new change log entries will | ||
be written correctly. | ||
|
||
**Test First Development for Databases** | ||
|
||
I also practice test first development for my database changes using this gem. | ||
First, I write the specs to express the outcome I want. For instance, I could | ||
add a new expectation that a certain field exists. Running the specs at this | ||
point fail. Next, I update the Liquibase change log. I know that I have gotten | ||
the change right once the tests pass. | ||
|
||
## Installation | ||
|
||
Installation is pretty standard: | ||
|
||
``` | ||
$ gem install mysql_expectations | ||
``` | ||
|
||
or install it using `bundler` by adding `mysql_expectations` to your `Gemfile`: | ||
|
||
``` | ||
group :development, :test do | ||
gem 'mysql_expectations', '~> 1.0' | ||
end | ||
``` | ||
|
||
and then download and install by running: | ||
|
||
``` | ||
bundle install | ||
``` | ||
|
||
## Usage | ||
|
||
MySQL Expectations uses the information returned from the `mysqldump` command | ||
as the actual values for your specs. Here is a sample `mysqldump` command: | ||
|
||
``` | ||
mysqldump --xml --no-data --all-databases \ | ||
--host=${host} --port=${port} \ | ||
--user=${user} -p > database_dump.xml | ||
``` | ||
|
||
The only real requirement is the `--xml` option. `mysqldump` has many other | ||
options that can help you limit the scope of the data returned or improve | ||
performance. Understanding the nuances of the `mysqldump` command is left | ||
as an exercise for the reader. | ||
|
||
Here is an example of using this gem in a spec file: | ||
|
||
```ruby | ||
require 'mysql_expectations' | ||
|
||
# So you don't have to specify the module name every time: | ||
include MySQLExpectations | ||
|
||
describe 'database order_tracking' do | ||
|
||
# Load the mysqldump xml and assign it to the `databases` variable: | ||
let :databases do | ||
MySQL.new(File.new('mysqldump.xml')) | ||
end | ||
|
||
# use your database name as a method on `databases`: | ||
subject { databases.order_tracking } | ||
|
||
# Express database-level expectations here: | ||
# | ||
it { is_expected.to only_have_tables('person', 'order') } | ||
|
||
describe 'the person table' do | ||
# use your table name as a method: | ||
subject { databases.order_tracking.person } | ||
|
||
# Express table level expectations here: | ||
# | ||
it { is_expected.to have_field('id').of_type('int(11)').not_nullable } | ||
it { is_expected.to have_field('first_name').of_type('varchar(50)').nullable } | ||
it { is_expected.to have_field('last_name').of_type('varchar(50)').nullable } | ||
... | ||
expected_key = Key.new('PRIMARY', Key::UNIQUE, [ | ||
KeyField.new('id', KeyField::ORDER_ASC) | ||
]) | ||
it { is_expected.to have_key(expected_key) } | ||
end | ||
|
||
describe 'the order table' do | ||
subject { databases.order_tracking.order } | ||
... | ||
end | ||
end | ||
``` | ||
|
||
## Detailed Examples | ||
|
||
Detailed examples for how to use this gem can be found in the Cucumber | ||
[features](features) in this code base. | ||
|
||
Each Cucumber feature file gives a complete rspec file template along with example | ||
expectation scenarios. For example, the [have_table_matcher.feature](features/RSpec Database Matchers/have_table_matcher.feature) | ||
gives an rspec template in the Background clause: | ||
|
||
```cucumber | ||
Given the rspec template for "database_spec.rb": | ||
"""ruby | ||
require 'mysql_expectations' | ||
include MySQLExpectations | ||
describe 'database order_tracking' do | ||
let :databases do | ||
MySQL.new(File.new('mysqldump.xml')) | ||
end | ||
describe 'table item' do | ||
subject { databases.order_tracking.item } | ||
# Replace the following with your expectation(s): | ||
# | ||
<%= expectation %> | ||
end | ||
end | ||
""" | ||
``` | ||
|
||
Each scenario for this feature gives an expectation that you can plug into this rspec template: | ||
|
||
```cucumber | ||
Scenario: expect database to have table | ||
Given the expectation: | ||
"""ruby | ||
it { is_expected.to have_table('order') } | ||
""" | ||
When I run rspec | ||
Then the exit status should be 0 | ||
And the description should be "should have table 'order'" | ||
``` | ||
|
||
All the features follow this same format. | ||
|
||
|
||
Code licensed under the New BSD license. See the [LICENSE](LICENSE) file for terms. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Copyright (c) 2015 Yahoo Inc. | ||
# Copyrights licensed under the New BSD License. | ||
# See the accompanying LICENSE file for terms. | ||
|
||
require 'bundler' | ||
require 'bundler/gem_tasks' | ||
|
||
begin | ||
Bundler.setup(:default, :development) | ||
rescue Bundler::BundlerError => e | ||
$stderr.puts e.message | ||
$stderr.puts 'Run `bundle install` to install missing gems' | ||
exit e.status_code | ||
end | ||
|
||
require 'rake' | ||
require 'rspec/core/rake_task' | ||
require 'rubocop/rake_task' | ||
require 'cucumber/rake/task' | ||
|
||
desc 'Clean up build artifacts.' | ||
task :clean do | ||
print 'Cleaning up build artifacts...' | ||
FileUtils.rm_rf('coverage') | ||
FileUtils.rm_rf('pkg') | ||
FileUtils.rm_rf('tmp') | ||
FileUtils.rm('mysqldump.xml') if File.file?('mysqldump.xml') | ||
puts 'DONE' | ||
end | ||
|
||
RSpec::Core::RakeTask.new | ||
|
||
RuboCop::RakeTask.new | ||
|
||
Cucumber::Rake::Task.new | ||
|
||
desc 'By default run clean, rspec tests, rubocop, and cucumber tests.' | ||
task default: [:clean, :spec, :rubocop, :cucumber] | ||
|
||
desc 'Run the irb console and require mysql_expectations.' | ||
task :console do | ||
require 'irb' | ||
require 'irb/completion' | ||
require 'mysql_expectations' | ||
ARGV.clear | ||
IRB.start | ||
end | ||
|
||
RELISH_PROJECT = 'mysql-expectations/mysql-expectations' | ||
RELISH_STAGING_PROJECT = 'mysql-expectations-staging/mysql-expectations' | ||
|
||
desc 'Push cucumber features to http://relishapp.com' | ||
task :relish, :version do |_t, args| | ||
fail 'rake relish[VERSION]' unless args[:version] | ||
if `relish versions #{RELISH_PROJECT}`.split.map(&:strip).include? args[:version] | ||
puts "Version #{args[:version]} already exists" | ||
else | ||
sh "relish versions:add #{RELISH_PROJECT}:#{args[:version]}" | ||
end | ||
sh "relish push #{RELISH_PROJECT}:#{args[:version]}" | ||
end | ||
|
||
desc 'Push to relish staging environment of http://relishapp.com' | ||
task :relish_staging do | ||
sh "relish push #{RELISH_STAGING_PROJECT}" | ||
end |
Oops, something went wrong.