railsless-active_record 0.0.1

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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +8 -0
  5. data/README.md +144 -0
  6. data/Rakefile +8 -0
  7. data/lib/railsless/active_record/config.rb +65 -0
  8. data/lib/railsless/active_record/load_tasks.rb +13 -0
  9. data/lib/railsless/active_record/rake.rb +74 -0
  10. data/lib/railsless/active_record/root.rb +42 -0
  11. data/lib/railsless/active_record/seed_loader.rb +14 -0
  12. data/lib/railsless/active_record/sinatra_extension.rb +40 -0
  13. data/lib/railsless/active_record/version.rb +5 -0
  14. data/lib/railsless/active_record.rb +27 -0
  15. data/railsless-active_record.gemspec +24 -0
  16. data/spec/active_record/config_spec.rb +70 -0
  17. data/spec/active_record/root_spec.rb +35 -0
  18. data/spec/active_record/seed_loader_spec.rb +21 -0
  19. data/spec/apps/sinatra-classic/Gemfile +7 -0
  20. data/spec/apps/sinatra-classic/Rakefile +4 -0
  21. data/spec/apps/sinatra-classic/app.rb +16 -0
  22. data/spec/apps/sinatra-classic/config/database.yml +25 -0
  23. data/spec/apps/sinatra-classic/config.ru +2 -0
  24. data/spec/apps/sinatra-classic/db/migrate/20140201145729_create_messages.rb +8 -0
  25. data/spec/apps/sinatra-classic/db/schema.rb +22 -0
  26. data/spec/apps/sinatra-modular/Gemfile +7 -0
  27. data/spec/apps/sinatra-modular/Rakefile +4 -0
  28. data/spec/apps/sinatra-modular/app.rb +18 -0
  29. data/spec/apps/sinatra-modular/config/database.yml +25 -0
  30. data/spec/apps/sinatra-modular/config.ru +2 -0
  31. data/spec/apps/sinatra-modular/db/migrate/20140201145729_create_messages.rb +8 -0
  32. data/spec/apps/sinatra-modular/db/schema.rb +22 -0
  33. data/spec/fixtures/app_with_paths/config/database.yml +5 -0
  34. data/spec/fixtures/find_root_with_flag/app.rb +0 -0
  35. data/spec/fixtures/find_root_with_flag/bin/app +0 -0
  36. data/spec/fixtures/find_root_with_flag/config.ru +0 -0
  37. data/spec/fixtures/seeds.rb +4 -0
  38. data/spec/integrations/sinatra_spec.rb +141 -0
  39. data/spec/spec_helper.rb +25 -0
  40. data/spec/support/fs_fixture_helpers.rb +11 -0
  41. data/spec/support/inline_timeout_helpers.rb +15 -0
  42. data/templates/database.yml +25 -0
  43. metadata +155 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f122a117e6b93dbe3c7349d10e6161421bbf8dd7
4
+ data.tar.gz: 2503c67f693b02ab67decdaff8aa982d4e02d9d9
5
+ SHA512:
6
+ metadata.gz: bb0e33c4b0de00d44b34545acccb0b96628186f89b08cb0804ac998a0f502493b9d1046f8dc0211c61693f0c64121b475920434d10a782e5d66e9bcf93388cc2
7
+ data.tar.gz: 398ea7f655fa43bf16c90c857cd73b1ed4fa422110e0ae9f0085364fadc0b88ce43ffbcaec8cc26225767ba1086d221c33751e9067bc0b350b480165ab3bb819
data/.gitignore ADDED
@@ -0,0 +1,20 @@
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
+
19
+ # Dummy app ignores
20
+ /spec/apps/sinatra-*/db/*.sqlite3
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ script:
7
+ - bundle exec rake spec SPEC_OPTS="--format d"
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rspec', '~> 2.14'
7
+ gem 'simplecov', '~> 0.7'
8
+ end
data/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # Railsless-ActiveRecord [![Build Status](https://travis-ci.org/damncabbage/railsless-active_record.png?branch=master)](https://travis-ci.org/damncabbage/railsless-active_record)
2
+
3
+ Provides a ActiveRecord Rake tasks and integration for Sinatra, Grape and other not-Rails frameworks.
4
+
5
+ ## Installation
6
+
7
+ Add `gem 'railsless-active_record'` to your Gemfile (along with `gem 'sqlite3'`, or whatever other database you're using). Run `bundle install` to pull it down and set it up.
8
+
9
+ ### Rake
10
+
11
+ In your Rakefile, add the following lines:
12
+
13
+ ```ruby
14
+ require 'railsless/active_record/load_tasks'
15
+ task :environment do
16
+ require './app' # or whatever the path to your app or server is.
17
+ end
18
+ ```
19
+
20
+ (You **will** need to put the app `require` inside the `:environment` block, or face having tasks like `db:generate:config` fail because of the app trying to establish a database connection immediately when required.)
21
+
22
+ You'll then need to integrate this gem with your app; here's how to do it with some common non-Rails frameworks:
23
+
24
+ ### Sinatra
25
+
26
+ In your application, add a `register Railsless::ActiveRecord::SinatraExtension` line to use the extension to manage your database configuration and connections, eg.
27
+
28
+ ```ruby
29
+ require 'sinatra/base'
30
+ require 'railsless/active_record/sinatra_extension'
31
+ class MyApp < Sinatra::Base
32
+ register Railsless::ActiveRecord::SinatraExtension
33
+
34
+ # ... And the rest of your app goes here.
35
+ end
36
+ ```
37
+
38
+ ... Or with the "Classic" style:
39
+
40
+ ```ruby
41
+ require 'sinatra'
42
+ require 'railsless/active_record/sinatra_extension'
43
+
44
+ # get '/foo', ... etc.
45
+ ```
46
+
47
+ ### Grape
48
+
49
+ TODO. :sweat_smile:
50
+
51
+ ### Generic
52
+
53
+ ```ruby
54
+ require 'railsless/active_record'
55
+ config = Railsless::ActiveRecord::Config.new
56
+ config.root = File.dirname(__FILE__)
57
+
58
+ # On app startup:
59
+ Railsless::ActiveRecord.connect!(config)
60
+
61
+ # On app shutdown:
62
+ Railsless::ActiveRecord.disconnect!
63
+ ```
64
+
65
+
66
+ ## Configuration
67
+
68
+ Run `rake db:generate:config` to generate a `config/database.yml` to fill in.
69
+
70
+ If you don't, it will fall back to parsing `ENV['DATABASE_URL']` (eg. `sqlite3:///db/development.sqlite3`). If that isn't provided, this gem will raise an error.
71
+
72
+
73
+ ## Usage
74
+
75
+ Have a look at the Rake tasks now available to you:
76
+
77
+ ```
78
+ $ rake -T
79
+ rake db:create # Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)
80
+ rake db:drop # Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)
81
+ rake db:fixtures:load # Load fixtures into the current environment's database
82
+ rake db:generate:config # Generate and write a config/database.yml
83
+ rake db:generate:migration # Generate a database migration, eg: rake db:generate:migration NAME=CreatePosts
84
+ rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)
85
+ rake db:migrate:status # Display status of migrations
86
+ rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n)
87
+ rake db:schema:cache:clear # Clear a db/schema_cache.dump file
88
+ rake db:schema:cache:dump # Create a db/schema_cache.dump file
89
+ rake db:schema:dump # Create a db/schema.rb file that can be portably used against any DB supported by AR
90
+ rake db:schema:load # Load a schema.rb file into the database
91
+ rake db:seed # Load the seed data from db/seeds.rb
92
+ rake db:setup # Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)
93
+ rake db:structure:dump # Dump the database structure to db/structure.sql
94
+ rake db:version # Retrieves the current schema version number
95
+ ```
96
+
97
+ Create a new DB migration with:
98
+
99
+ ```
100
+ $ rake db:generate:migration NAME=create_posts
101
+ ```
102
+
103
+ This will create a migration file in your migrations directory (`db/migrate`), eg.
104
+
105
+ ```ruby
106
+ class CreateUsers < ActiveRecord::Migration
107
+ def change
108
+ create_table :posts do |t|
109
+ t.string :name
110
+ t.timestamps
111
+ end
112
+ end
113
+ end
114
+ ```
115
+
116
+ ## Contributing
117
+
118
+ 1. Fork it
119
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
120
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
121
+ 4. Push to the branch (`git push origin my-new-feature`)
122
+ 5. Create new Pull Request
123
+
124
+ ## Notes
125
+
126
+ Apologies for the horrendous name. ActiveRecord has the gem name `activerecord`, but you need to `require 'active_record'` when using it. I decided to be up-front with you as to how to require the damn thing.
127
+
128
+ Why not [sinatra-activerecord](https://github.com/janko-m/sinatra-activerecord)? It takes the (understandable) approach of *emulating* the ActiveRecord Rake tasks, instead of using them directly; this unfortunately which leaves large gaps in the set of tasks Rails users are used to. These ActiveRecord tasks have only really been able to be used directly since v4.0, though, so putting these changes back into Blake's/Janko's library would be very backwards-incompatible.
129
+
130
+ ## License
131
+
132
+ Copyright 2013, Rob Howard
133
+
134
+ Licensed under the Apache License, Version 2.0 (the "License");
135
+ you may not use this file except in compliance with the License.
136
+ You may obtain a copy of the License at
137
+
138
+ http://www.apache.org/licenses/LICENSE-2.0
139
+
140
+ Unless required by applicable law or agreed to in writing, software
141
+ distributed under the License is distributed on an "AS IS" BASIS,
142
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143
+ See the License for the specific language governing permissions and
144
+ limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+ desc "Run all specs"
5
+ RSpec::Core::RakeTask.new(:spec) do |t|
6
+ t.pattern = 'spec/**/*_spec.rb'
7
+ end
8
+ task :default => :spec
@@ -0,0 +1,65 @@
1
+ require 'railsless/active_record/root'
2
+ require 'logger'
3
+ require 'yaml'
4
+ require 'erb'
5
+
6
+ module Railsless
7
+ module ActiveRecord
8
+ class Config
9
+ def self.attr_accessor_with_default(name, &block)
10
+ module_eval do
11
+ attr_writer name
12
+ define_method(name) do
13
+ # Don't cache the result; if you really needs to, define a method manually.
14
+ instance_variable_get(:"@#{name}") || instance_exec(&block)
15
+ end
16
+ end
17
+ end
18
+
19
+ def initialize(overrides={})
20
+ overrides.each { |attr,val| send(:"#{attr}=", val) }
21
+ end
22
+
23
+ # An overblown way of figuring out where the calling application's root
24
+ # is, borrowed from Rails.
25
+ attr_writer :root
26
+ def root
27
+ @root ||= Root.calculate
28
+ end
29
+
30
+ # Fumble around picking the right running environment.
31
+ attr_accessor_with_default(:env) do
32
+ ENV['RACK_ENV'] || ENV['SINATRA_ENV'] || ENV['RAILS_ENV'] || ENV['ENV'] || 'development'
33
+ end
34
+
35
+ attr_accessor_with_default(:db_config) do
36
+ case
37
+ when File.exist?(db_config_path)
38
+ YAML.load(read_config(db_config_path))
39
+ when ENV.has_key?('DATABASE_URL')
40
+ ENV.fetch('DATABASE_URL')
41
+ else
42
+ raise "Unable to locate database config; DATABASE_URL or config file at #{db_config_path} required."
43
+ end
44
+ end
45
+
46
+ attr_accessor_with_default(:db_config_path) do
47
+ File.join(root, 'config', 'database.yml')
48
+ end
49
+ attr_accessor_with_default(:db_path) { File.join(root, 'db') }
50
+ attr_accessor_with_default(:seeds_path) { File.join(db_path, 'seeds.rb') }
51
+ attr_accessor_with_default(:schema_path) { File.join(db_path, 'schema.rb') }
52
+ attr_accessor_with_default(:migrations_path) { File.join(db_path, 'migrate') }
53
+
54
+ attr_accessor_with_default(:logger) { Logger.new(STDOUT) }
55
+
56
+ protected
57
+
58
+ # Intentionally explodes violently if the file doesn't exist.
59
+ def read_config(filename)
60
+ ERB.new(File.read(filename)).result
61
+ end
62
+ end
63
+ end
64
+ end
65
+
@@ -0,0 +1,13 @@
1
+ require 'railsless/active_record'
2
+
3
+ # HACK: Some internals of the ActiveRecord Rake tasks refer to Rails.root
4
+ # directly. Define it here if necessary, and be careful about it.
5
+ unless defined?(Rails) && Rails.respond_to?(:root)
6
+ module Rails
7
+ def self.root
8
+ Railsless::ActiveRecord::Config.new.root
9
+ end
10
+ end
11
+ end
12
+
13
+ Railsless::ActiveRecord::Rake.load_tasks!
@@ -0,0 +1,74 @@
1
+ require 'active_record'
2
+ require 'rake'
3
+ require 'fileutils'
4
+
5
+ module Railsless
6
+ module ActiveRecord
7
+ module Rake
8
+ module_function
9
+
10
+ TEMPLATES_PATH = File.expand_path('../../../templates', File.dirname(__FILE__))
11
+
12
+ def load_tasks!(config=nil)
13
+ config ||= Railsless::ActiveRecord::Config.new
14
+ load_database_tasks!(config)
15
+ load_generator_tasks!(config)
16
+ end
17
+
18
+ def load_database_tasks!(config)
19
+ extend ::Rake::DSL
20
+
21
+ # ActiveRecord looks to db:load_config for its DatabaseTasks setup.
22
+ # Load it up with our own configuration first.
23
+ namespace :db do
24
+ task :load_config do
25
+ ::ActiveRecord::Tasks::DatabaseTasks.root = config.root
26
+ ::ActiveRecord::Tasks::DatabaseTasks.env = config.env
27
+ ::ActiveRecord::Tasks::DatabaseTasks.db_dir = config.db_path
28
+ ::ActiveRecord::Tasks::DatabaseTasks.database_configuration = config.db_config
29
+ ::ActiveRecord::Tasks::DatabaseTasks.migrations_paths = config.migrations_path
30
+ ::ActiveRecord::Tasks::DatabaseTasks.seed_loader = SeedLoader.new(config.seeds_path)
31
+ ::ActiveRecord::Tasks::DatabaseTasks.fixtures_path = nil # TODO
32
+ end
33
+ end
34
+
35
+ # Stub out the :environment task that DatabaseTasks depends on.
36
+ # Ideally, the app using this library loads the app from within an
37
+ # :environment task (as per the README), but provide this as a fallback.
38
+ unless ::Rake::Task.task_defined? :environment
39
+ task :environment
40
+ end
41
+
42
+ load 'active_record/railties/databases.rake'
43
+ end
44
+
45
+ # Creates database.yml files and migrations.
46
+ def load_generator_tasks!(config)
47
+ extend ::Rake::DSL
48
+ namespace :db do
49
+ namespace :generate do
50
+
51
+ desc "Generate and write a config/database.yml"
52
+ task :config do
53
+ config_path = config.db_config_path
54
+ if File.exists?(config_path)
55
+ puts "Database config already exists at #{config_path}; skipping..."
56
+ else
57
+ FileUtils.cp(
58
+ File.join(TEMPLATES_PATH, 'database.yml'),
59
+ config_path
60
+ )
61
+ end
62
+ end
63
+
64
+ desc "Generate a database migration, eg: rake db:generate:migration NAME=CreatePosts"
65
+ task :migration do
66
+ # TODO: NAME=...
67
+ raise "Not Implemented"
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,42 @@
1
+ # Partially inspired by railties-4.0.0/lib/rails/engine.rb
2
+ # In essence, it's:
3
+ # - Picking a file to look for (eg. config.ru),
4
+ # - Starting at an arbitrary directory (eg. the current working directory), and then
5
+ # - Traversing back up the directory tree until it either finds a flag file, or hits
6
+ # the root folder.
7
+
8
+ module Railsless
9
+ module ActiveRecord
10
+ class Root
11
+ def self.calculate(flag_file=nil, start_from=nil)
12
+ find_root_with_flag(
13
+ flag_file || 'config.ru', # Look for something signifying Rack. Not much else to go on.
14
+ start_from || Dir.pwd # Yes, Rails does this.
15
+ )
16
+ end
17
+
18
+ # Starts from a directory, and works upwards looking for a particular file.
19
+ def self.find_root_with_flag(flag, starting_path)
20
+ # This process if only useful if the starting_path is an absolute path.
21
+ path = if starting_path[0] == '/'
22
+ starting_path
23
+ else
24
+ File.absolute_path(starting_path) # Relative; turn into absolute path
25
+ end
26
+
27
+ while path && File.directory?(path) && !File.exist?("#{path}/#{flag}")
28
+ parent = File.dirname(path)
29
+ path = (parent != path) && parent
30
+ end
31
+
32
+ if path && File.exist?("#{path}/#{flag}")
33
+ File.realpath path
34
+ else
35
+ raise "Could not find root path for hosting application"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+
@@ -0,0 +1,14 @@
1
+ module Railsless
2
+ module ActiveRecord
3
+ class SeedLoader
4
+ attr_accessor :path
5
+ def initialize(path)
6
+ @path = path
7
+ end
8
+
9
+ def load_seed
10
+ Kernel.load(path) if path && File.exist?(path)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ require 'railsless/active_record'
2
+
3
+ module Railsless
4
+ module ActiveRecord
5
+ module SinatraExtension
6
+
7
+ def self.registered(app)
8
+ unless app.respond_to?(:activerecord_config) && app.activerecord_config
9
+ app.set :activerecord_config, Railsless::ActiveRecord::Config.new
10
+ end
11
+ app.set :database, app.database
12
+ app.helpers SinatraExtensionHelper
13
+ app.after { Railsless::ActiveRecord.disconnect! }
14
+ end
15
+
16
+ def database
17
+ @database ||= Railsless::ActiveRecord.connect!(activerecord_config)
18
+ end
19
+
20
+ def activerecord_config=(config)
21
+ @database = nil
22
+ @activerecord_config = config
23
+ @database = Railsless::ActiveRecord.connect!(config)
24
+ end
25
+ end
26
+
27
+ module SinatraExtensionHelper
28
+ def database
29
+ settings.database
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ # HACK: Support classic apps by automatically registering the extension, as recommended
36
+ # by the Sinatra docs here: http://www.sinatrarb.com/extensions.html
37
+ if defined?(Sinatra) && defined?(Sinatra::Application)
38
+ # We're using classic; sinatra/main defines Sinatra::Application, so hook into that.
39
+ Sinatra::Application.send(:register, ::Railsless::ActiveRecord::SinatraExtension)
40
+ end
@@ -0,0 +1,5 @@
1
+ module Railsless
2
+ module ActiveRecord
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ require 'railsless/active_record/version'
2
+ require 'railsless/active_record/config'
3
+ require 'railsless/active_record/seed_loader'
4
+ require 'railsless/active_record/rake'
5
+ require 'active_record'
6
+
7
+ module Railsless
8
+ module ActiveRecord
9
+ module_function
10
+
11
+ def connect!(config)
12
+ db_config = config.db_config
13
+ if db_config.is_a?(String)
14
+ ::ActiveRecord::Base.establish_connection(db_config)
15
+ else
16
+ ::ActiveRecord::Base.configurations = db_config
17
+ ::ActiveRecord::Base.establish_connection(config.env)
18
+ end
19
+ ::ActiveRecord::Base.logger = config.logger
20
+ ::ActiveRecord::Base
21
+ end
22
+
23
+ def disconnect!
24
+ ::ActiveRecord::Base.clear_active_connections!
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'railsless/active_record/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "railsless-active_record"
8
+ spec.version = Railsless::ActiveRecord::VERSION
9
+ spec.authors = ["Rob Howard"]
10
+ spec.email = ["rob@robhoward.id.au"]
11
+ spec.description = %q{Provides a ActiveRecord Rake tasks and integration for Sinatra, Goliath, etc.}
12
+ spec.summary = %q{Provides a ActiveRecord Rake tasks and integration for Sinatra, Goliath and other apps that aren't using Rails.}
13
+ spec.homepage = "https://github.com/damncabbage/railsless-active_record"
14
+ spec.license = "Apache License, Version 2.0"
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_development_dependency "bundler", "~> 1.3"
22
+ spec.add_dependency "rake"
23
+ spec.add_dependency "activerecord", "~> 4.0" # < 4 is a pain in the butt to add Rake tasks for.
24
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Railsless::ActiveRecord::Config do
4
+ let(:config) do
5
+ described_class.new.tap do |c|
6
+ c.root = fixture('app_with_paths')
7
+ end
8
+ end
9
+
10
+ describe "#env" do
11
+ it "uses RACK_ENV, SINATRA_ENV, RAILS_ENV or ENV to determine environment" do
12
+ %w(RACK_ENV SINATRA_ENV RAILS_ENV ENV).each do |key|
13
+ with_blank_env do
14
+ ENV[key] = rand(1..999999).to_s
15
+ expect(config.env).to eq ENV[key]
16
+ end
17
+ end
18
+ end
19
+ it "defaults to 'development'" do
20
+ with_blank_env { expect(config.env).to eq 'development' }
21
+ end
22
+ end
23
+
24
+ describe "#db_config" do
25
+ let(:config_without_file) do
26
+ described_class.new.tap do |c|
27
+ c.root = fixture('find_root_with_flag')
28
+ end
29
+ end
30
+
31
+ it "uses a database config if it's present" do
32
+ expect(config.db_config).to eq({
33
+ 'development' => {
34
+ 'adapter' => 'sqlite3',
35
+ 'database' => 'db/development.sqlite3',
36
+ 'pool' => 5,
37
+ 'timeout' => 5000,
38
+ },
39
+ })
40
+ end
41
+ it "falls back to ENV['DATABASE_URL'] if no database config can be found" do
42
+ with_blank_env do
43
+ ENV['DATABASE_URL'] = 'sqlite3:///db/development.sqlite3'
44
+ expect(config_without_file.db_config).to eq ENV['DATABASE_URL']
45
+ end
46
+ end
47
+ it "explodes is neither config nor ENV['DATABASE_URL'] is present" do
48
+ with_blank_env do
49
+ expect { config_without_file.db_config }.to raise_error
50
+ end
51
+ end
52
+ end
53
+
54
+ it "has sensible defaults for the rest" do
55
+ expect(config.db_config_path).to eq File.join(config.root, 'config/database.yml')
56
+ expect(config.seeds_path).to eq File.join(config.root, 'db/seeds.rb')
57
+ expect(config.schema_path).to eq File.join(config.root, 'db/schema.rb')
58
+ expect(config.migrations_path).to eq File.join(config.root, 'db/migrate')
59
+ expect(config.logger).to be_a(Logger)
60
+ end
61
+
62
+ # Helpers
63
+
64
+ def with_blank_env(&block)
65
+ original = ENV
66
+ ENV.replace({})
67
+ yield if block_given?
68
+ ENV.replace(original)
69
+ end
70
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Railsless::ActiveRecord::Root do
4
+ let(:root) { described_class }
5
+
6
+ describe ".calculate" do
7
+ it "uses config.ru and the current working dir to find the app root" do
8
+ dir = fixture('find_root_with_flag')
9
+ expect(Dir).to receive(:pwd).and_return(dir)
10
+ expect(root.calculate).to eq dir
11
+ end
12
+ end
13
+
14
+ describe ".to eq dir.find_root_with_flag" do
15
+ it "finds a flag file in the starting directory (eg. current working dir)" do
16
+ starting = fixture('find_root_with_flag')
17
+ expect(root.find_root_with_flag('config.ru', starting)).to eq starting
18
+ end
19
+
20
+ it "looks up the tree until it finds the flag file" do
21
+ dir = fixture('find_root_with_flag')
22
+ starting = File.join(dir, 'bin') # find_root_with_flag/bin
23
+ expect(root.find_root_with_flag('config.ru', starting)).to eq dir
24
+ end
25
+
26
+ # If this test explodes on your machine, it probably means you have a
27
+ # config.ru hanging around in a parent directory. :)
28
+ it "explodes when it can't find the flag file" do
29
+ starting = File.dirname(__FILE__)
30
+ expect {
31
+ root.find_root_with_flag('config.ru', starting)
32
+ }.to raise_error(StandardError, "Could not find root path for hosting application")
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Railsless::ActiveRecord::SeedLoader do
4
+ let(:seed_path) { fixture('seeds.rb') }
5
+ let(:bad_seed_path) { fixture('doesnt_exist.rb') }
6
+ before { stub_const('BlogPost', double) }
7
+
8
+ it "loads a seed file that exists" do
9
+ loader = Railsless::ActiveRecord::SeedLoader.new(seed_path)
10
+ expect(BlogPost).to receive(:create).with(:title => "Example")
11
+ loader.load_seed
12
+ end
13
+
14
+ it "ignores non-existent seeds" do
15
+ [bad_seed_path, nil].each do |path|
16
+ loader = Railsless::ActiveRecord::SeedLoader.new(path)
17
+ expect(BlogPost).to_not receive(:create)
18
+ expect(loader.load_seed).to be_nil
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'sinatra'
5
+ gem 'sqlite3'
6
+ gem 'railsless-active_record',
7
+ :path => File.expand_path('../../..', File.dirname(__FILE__))
@@ -0,0 +1,4 @@
1
+ require 'railsless/active_record/load_tasks'
2
+ task :environment do
3
+ require './app'
4
+ end
@@ -0,0 +1,16 @@
1
+ require 'sinatra'
2
+ require 'railsless/active_record/sinatra_extension'
3
+ require 'json'
4
+
5
+ class Message < ActiveRecord::Base
6
+ # attributes: title
7
+ end
8
+
9
+ register Railsless::ActiveRecord::SinatraExtension
10
+
11
+ get '/messages' do
12
+ Message.all.to_json
13
+ end
14
+ post '/messages' do
15
+ Message.create!(:title => params[:title]).to_json
16
+ end
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ development:
7
+ adapter: sqlite3
8
+ database: db/development.sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ # Warning: The database defined as "test" will be erased and
13
+ # re-generated from your development database when you run "rake".
14
+ # Do not set this db to the same as development or production.
15
+ test:
16
+ adapter: sqlite3
17
+ database: db/test.sqlite3
18
+ pool: 5
19
+ timeout: 5000
20
+
21
+ production:
22
+ adapter: sqlite3
23
+ database: db/production.sqlite3
24
+ pool: 5
25
+ timeout: 5000
@@ -0,0 +1,2 @@
1
+ require './app'
2
+ run Sinatra::Application
@@ -0,0 +1,8 @@
1
+ class CreateMessages < ActiveRecord::Migration
2
+ def change
3
+ create_table :messages do |t|
4
+ t.string :title
5
+ t.timestamps
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended that you check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(version: 20140201145729) do
15
+
16
+ create_table "messages", force: true do |t|
17
+ t.string "title"
18
+ t.datetime "created_at"
19
+ t.datetime "updated_at"
20
+ end
21
+
22
+ end
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'sinatra'
5
+ gem 'sqlite3'
6
+ gem 'railsless-active_record',
7
+ :path => File.expand_path('../../..', File.dirname(__FILE__))
@@ -0,0 +1,4 @@
1
+ require 'railsless/active_record/load_tasks'
2
+ task :environment do
3
+ require './app'
4
+ end
@@ -0,0 +1,18 @@
1
+ require 'sinatra/base'
2
+ require 'railsless/active_record/sinatra_extension'
3
+ require 'json'
4
+
5
+ class Message < ActiveRecord::Base
6
+ # attributes: title
7
+ end
8
+
9
+ class TestSinatraApp < Sinatra::Base
10
+ register Railsless::ActiveRecord::SinatraExtension
11
+
12
+ get '/messages' do
13
+ Message.all.to_json
14
+ end
15
+ post '/messages' do
16
+ Message.create!(:title => params[:title]).to_json
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ development:
7
+ adapter: sqlite3
8
+ database: db/development.sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ # Warning: The database defined as "test" will be erased and
13
+ # re-generated from your development database when you run "rake".
14
+ # Do not set this db to the same as development or production.
15
+ test:
16
+ adapter: sqlite3
17
+ database: db/test.sqlite3
18
+ pool: 5
19
+ timeout: 5000
20
+
21
+ production:
22
+ adapter: sqlite3
23
+ database: db/production.sqlite3
24
+ pool: 5
25
+ timeout: 5000
@@ -0,0 +1,2 @@
1
+ require './app'
2
+ run TestSinatraApp
@@ -0,0 +1,8 @@
1
+ class CreateMessages < ActiveRecord::Migration
2
+ def change
3
+ create_table :messages do |t|
4
+ t.string :title
5
+ t.timestamps
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ # This file is auto-generated from the current state of the database. Instead
3
+ # of editing this file, please use the migrations feature of Active Record to
4
+ # incrementally modify your database, and then regenerate this schema definition.
5
+ #
6
+ # Note that this schema.rb definition is the authoritative source for your
7
+ # database schema. If you need to create the application database on another
8
+ # system, you should be using db:schema:load, not running all the migrations
9
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
11
+ #
12
+ # It's strongly recommended that you check this file into your version control system.
13
+
14
+ ActiveRecord::Schema.define(version: 20140201145729) do
15
+
16
+ create_table "messages", force: true do |t|
17
+ t.string "title"
18
+ t.datetime "created_at"
19
+ t.datetime "updated_at"
20
+ end
21
+
22
+ end
@@ -0,0 +1,5 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: db/development.sqlite3
4
+ pool: 5
5
+ timeout: 5000
File without changes
File without changes
File without changes
@@ -0,0 +1,4 @@
1
+ # Pretend ActiveRecord db/seeds.rb file
2
+ BlogPost.create(
3
+ :title => "Example",
4
+ )
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'net/http'
4
+ require 'open3'
5
+ require 'json'
6
+
7
+ # The following tests spin up a Sinatra app in a separate process; keeping it
8
+ # isolated means we can test the entire DB and app lifecycle without risk of pollution.
9
+
10
+ # This shared example is used by both the spec/apps/sinatra-modular and
11
+ # spec/apps/sinatra-classic dummy apps. The meat of the specs are in the example;
12
+ # see the bottom of file for app definitions. (We need to define the shared example
13
+ # before we can use it.)
14
+ shared_examples "a Sinatra app" do
15
+ before(:all) { run "bundle install" }
16
+
17
+ it "prints the expected list of ActiveRecord Rake tasks" do
18
+ out = run "bundle exec rake -T"
19
+ %w(
20
+ create drop fixtures:load migrate migrate:status rollback
21
+ schema:cache:clear schema:cache:dump schema:dump schema:load
22
+ seed setup structure:dump version
23
+ generate:config generate:migration
24
+ ).each do |task|
25
+ expect(out).to match /^rake db:#{task}/
26
+ end
27
+ end
28
+
29
+ context "generators" do
30
+ describe "db:generate:config" do
31
+ let(:config_path) do
32
+ File.join(app_path, 'config/database.yml')
33
+ end
34
+ let(:template_path) do
35
+ File.expand_path('../../templates/database.yml', File.dirname(__FILE__))
36
+ end
37
+
38
+ it "ignores an existing config file" do
39
+ expect(File).to exist(config_path)
40
+ out = run "bundle exec rake db:generate:config"
41
+ expect(out).to match /Database config already exists/
42
+ end
43
+
44
+ it "generates a config file that doesn't yet exist" do
45
+ FileUtils.rm_f(config_path)
46
+ out = run "bundle exec rake db:generate:config"
47
+ expect(File.read(config_path)).to eq File.read(template_path)
48
+ end
49
+
50
+ # Force a reset of the configuration, regardless of the test results.
51
+ after do
52
+ FileUtils.rm_f(config_path)
53
+ FileUtils.cp(template_path, config_path)
54
+ end
55
+ end
56
+
57
+ pending "'db:generate:migration NAME=NameHere' creates a migration" do
58
+ # TODO: 'NameHere' -> 'name_here' transform.
59
+ end
60
+ end
61
+
62
+ context "requests" do
63
+ # HACK: rackup doesn't allow "-p 0" for binding to a free non-privileged port.
64
+ # Suggested terrible, race-conditioney alternative:
65
+ # s = TCPServer.new('127.0.0.1', 0); port = s.addr[1]; s.close
66
+ let(:port) { rand(10_000..10_999) }
67
+ let(:host) { 'localhost' }
68
+
69
+ it "serves database-backed requests" do
70
+ run "bundle exec rake db:drop db:create db:migrate"
71
+ run_while "bundle exec rackup -p #{port}" do |stdout_and_err|
72
+ # Wait for Sinatra to show up; explode if it doesn't.
73
+ wait_for_port! host, port, 15 # seconds
74
+
75
+ uri = URI("http://#{host}:#{port}/messages")
76
+ expect(JSON.parse(Net::HTTP.get(uri))).to eq []
77
+
78
+ post = JSON.parse(Net::HTTP.post_form(uri, 'title' => "Hello World").body)
79
+ expect(post['title']).to eq "Hello World"
80
+
81
+ posts = JSON.parse(Net::HTTP.get(uri))
82
+ expect(posts.count).to eq 1
83
+ expect(posts[0]['title']).to eq post['title']
84
+ end
85
+ end
86
+ end
87
+
88
+ # Helpers
89
+
90
+ def run(command)
91
+ output = ""
92
+ Bundler.with_clean_env do
93
+ output, status = Open3.capture2(command, :chdir => app_path)
94
+ expect(status).to be_success
95
+ end
96
+ output
97
+ end
98
+
99
+ def run_while(command, &block)
100
+ Bundler.with_clean_env do
101
+ Open3.popen2e(command, :chdir => app_path) do |stdin, stdout_and_err, wait_thr|
102
+ pid = wait_thr.pid
103
+ begin
104
+ yield(stdout_and_err) if block_given?
105
+ ensure
106
+ # Have tried TERM, but Ruby 1.9.3 + Webrick flat-out ignores it.
107
+ # Break out kill -9.
108
+ Process.kill(:KILL, pid)
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ # Waits until a port is open; raise InlineTimeout::Error if times out.
115
+ def wait_for_port!(host, port, seconds, interval=0.5)
116
+ InlineTimeout.timeout(seconds, interval) do
117
+ begin
118
+ TCPSocket.new(host, port).close
119
+ true
120
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
121
+ false
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ # Example require('sinatra/base'), class-based Sinatra app.
128
+ describe "Sinatra 'Modular' Integration" do
129
+ def app_path
130
+ File.expand_path('../apps/sinatra-modular', File.dirname(__FILE__))
131
+ end
132
+ it_behaves_like "a Sinatra app"
133
+ end
134
+
135
+ # Example require('sinatra'), base-DSL-using Sinatra app.
136
+ describe "Sinatra 'Classic' Integration" do
137
+ def app_path
138
+ File.expand_path('../apps/sinatra-classic', File.dirname(__FILE__))
139
+ end
140
+ it_behaves_like "a Sinatra app"
141
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift File.expand_path("../lib", File.dirname(__FILE__))
2
+
3
+ require "simplecov"
4
+ SimpleCov.start do
5
+ add_filter "/spec/"
6
+ end
7
+ require "rspec"
8
+
9
+ # Library under test
10
+ require File.expand_path('../lib/railsless/active_record', File.dirname(__FILE__))
11
+
12
+ # Helpers
13
+ Dir["#{File.dirname(__FILE__)}/support/**/*_helpers.rb"].each { |f| require f }
14
+
15
+ RSpec.configure do |config|
16
+ config.treat_symbols_as_metadata_keys_with_true_values = true
17
+ config.run_all_when_everything_filtered = true
18
+ config.filter_run :focus
19
+
20
+ # Run specs in random order to surface order dependencies. If you find an
21
+ # order dependency and want to debug it, you can fix the order by providing
22
+ # the seed, which is printed after each run.
23
+ # --seed 1234
24
+ config.order = 'random'
25
+ end
@@ -0,0 +1,11 @@
1
+ module FSFixtureHelpers
2
+ def fixture(path)
3
+ File.expand_path(
4
+ File.join('..', 'fixtures', path),
5
+ File.dirname(__FILE__)
6
+ )
7
+ end
8
+ end
9
+ RSpec.configure do |c|
10
+ c.include FSFixtureHelpers
11
+ end
@@ -0,0 +1,15 @@
1
+ module InlineTimeout
2
+ module_function
3
+
4
+ def self.timeout(seconds, interval=nil)
5
+ start = Time.now.to_i
6
+ begin
7
+ result = yield
8
+ return if result
9
+ sleep(interval) if interval && interval > 0
10
+ end until (Time.now.to_i - start) > seconds
11
+ raise Error, "Timeout after #{seconds} seconds"
12
+ end
13
+
14
+ class Error < StandardError; end
15
+ end
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ development:
7
+ adapter: sqlite3
8
+ database: db/development.sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ # Warning: The database defined as "test" will be erased and
13
+ # re-generated from your development database when you run "rake".
14
+ # Do not set this db to the same as development or production.
15
+ test:
16
+ adapter: sqlite3
17
+ database: db/test.sqlite3
18
+ pool: 5
19
+ timeout: 5000
20
+
21
+ production:
22
+ adapter: sqlite3
23
+ database: db/production.sqlite3
24
+ pool: 5
25
+ timeout: 5000
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: railsless-active_record
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rob Howard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-10 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.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
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: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ description: Provides a ActiveRecord Rake tasks and integration for Sinatra, Goliath,
56
+ etc.
57
+ email:
58
+ - rob@robhoward.id.au
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - .travis.yml
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - lib/railsless/active_record.rb
69
+ - lib/railsless/active_record/config.rb
70
+ - lib/railsless/active_record/load_tasks.rb
71
+ - lib/railsless/active_record/rake.rb
72
+ - lib/railsless/active_record/root.rb
73
+ - lib/railsless/active_record/seed_loader.rb
74
+ - lib/railsless/active_record/sinatra_extension.rb
75
+ - lib/railsless/active_record/version.rb
76
+ - railsless-active_record.gemspec
77
+ - spec/active_record/config_spec.rb
78
+ - spec/active_record/root_spec.rb
79
+ - spec/active_record/seed_loader_spec.rb
80
+ - spec/apps/sinatra-classic/Gemfile
81
+ - spec/apps/sinatra-classic/Rakefile
82
+ - spec/apps/sinatra-classic/app.rb
83
+ - spec/apps/sinatra-classic/config.ru
84
+ - spec/apps/sinatra-classic/config/database.yml
85
+ - spec/apps/sinatra-classic/db/migrate/20140201145729_create_messages.rb
86
+ - spec/apps/sinatra-classic/db/schema.rb
87
+ - spec/apps/sinatra-modular/Gemfile
88
+ - spec/apps/sinatra-modular/Rakefile
89
+ - spec/apps/sinatra-modular/app.rb
90
+ - spec/apps/sinatra-modular/config.ru
91
+ - spec/apps/sinatra-modular/config/database.yml
92
+ - spec/apps/sinatra-modular/db/migrate/20140201145729_create_messages.rb
93
+ - spec/apps/sinatra-modular/db/schema.rb
94
+ - spec/fixtures/app_with_paths/config/database.yml
95
+ - spec/fixtures/find_root_with_flag/app.rb
96
+ - spec/fixtures/find_root_with_flag/bin/app
97
+ - spec/fixtures/find_root_with_flag/config.ru
98
+ - spec/fixtures/seeds.rb
99
+ - spec/integrations/sinatra_spec.rb
100
+ - spec/spec_helper.rb
101
+ - spec/support/fs_fixture_helpers.rb
102
+ - spec/support/inline_timeout_helpers.rb
103
+ - templates/database.yml
104
+ homepage: https://github.com/damncabbage/railsless-active_record
105
+ licenses:
106
+ - Apache License, Version 2.0
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.0.3
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Provides a ActiveRecord Rake tasks and integration for Sinatra, Goliath and
128
+ other apps that aren't using Rails.
129
+ test_files:
130
+ - spec/active_record/config_spec.rb
131
+ - spec/active_record/root_spec.rb
132
+ - spec/active_record/seed_loader_spec.rb
133
+ - spec/apps/sinatra-classic/Gemfile
134
+ - spec/apps/sinatra-classic/Rakefile
135
+ - spec/apps/sinatra-classic/app.rb
136
+ - spec/apps/sinatra-classic/config.ru
137
+ - spec/apps/sinatra-classic/config/database.yml
138
+ - spec/apps/sinatra-classic/db/migrate/20140201145729_create_messages.rb
139
+ - spec/apps/sinatra-classic/db/schema.rb
140
+ - spec/apps/sinatra-modular/Gemfile
141
+ - spec/apps/sinatra-modular/Rakefile
142
+ - spec/apps/sinatra-modular/app.rb
143
+ - spec/apps/sinatra-modular/config.ru
144
+ - spec/apps/sinatra-modular/config/database.yml
145
+ - spec/apps/sinatra-modular/db/migrate/20140201145729_create_messages.rb
146
+ - spec/apps/sinatra-modular/db/schema.rb
147
+ - spec/fixtures/app_with_paths/config/database.yml
148
+ - spec/fixtures/find_root_with_flag/app.rb
149
+ - spec/fixtures/find_root_with_flag/bin/app
150
+ - spec/fixtures/find_root_with_flag/config.ru
151
+ - spec/fixtures/seeds.rb
152
+ - spec/integrations/sinatra_spec.rb
153
+ - spec/spec_helper.rb
154
+ - spec/support/fs_fixture_helpers.rb
155
+ - spec/support/inline_timeout_helpers.rb