mongo_browser 0.1.3 → 0.2.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.gitignore +3 -0
  2. data/.travis.yml +3 -3
  3. data/README.md +1 -25
  4. data/Rakefile +0 -1
  5. data/app/assets/images/background.png +0 -0
  6. data/app/assets/javascripts/app/controllers/alerts.js.coffee +12 -0
  7. data/app/assets/javascripts/app/controllers/breadcrumbs.js.coffee +25 -0
  8. data/app/assets/javascripts/app/controllers/collections.js.coffee +40 -0
  9. data/app/assets/javascripts/app/controllers/databases.js.coffee +39 -0
  10. data/app/assets/javascripts/app/controllers/documents.js.coffee +49 -0
  11. data/app/assets/javascripts/app/controllers/main.js.coffee +10 -0
  12. data/app/assets/javascripts/app/controllers/server_info.js.coffee +14 -0
  13. data/app/assets/javascripts/app/controllers.js.coffee +2 -0
  14. data/app/assets/javascripts/app/directives.js.coffee +20 -0
  15. data/app/assets/javascripts/app/filters.js.coffee +48 -0
  16. data/app/assets/javascripts/app/modules/dialogs.js.coffee +29 -0
  17. data/app/assets/javascripts/app/modules/pager.js.coffee +87 -0
  18. data/app/assets/javascripts/app/modules/table_filter.js.coffee +27 -0
  19. data/app/assets/javascripts/app/resources.js.coffee +22 -0
  20. data/app/assets/javascripts/app/services.js.coffee +36 -0
  21. data/app/assets/javascripts/app.js.coffee +8 -0
  22. data/app/assets/javascripts/application.js.coffee +35 -6
  23. data/app/assets/javascripts/templates/.gitkeep +0 -0
  24. data/app/assets/javascripts/templates.js.coffee +1 -0
  25. data/app/assets/javascripts/vendor.js.coffee +5 -0
  26. data/app/assets/stylesheets/application.css.scss +46 -3
  27. data/app/assets/templates/collections.html +53 -0
  28. data/app/assets/templates/databases.html +32 -0
  29. data/app/assets/templates/documents.html +45 -0
  30. data/app/assets/templates/pager.html +13 -0
  31. data/app/{views/server_info.erb → assets/templates/server_info.html} +5 -7
  32. data/app/assets/templates/table_filter.html +10 -0
  33. data/bin/mongo_browser +8 -45
  34. data/config-e2e.ru +20 -0
  35. data/grunt.js +36 -0
  36. data/lib/mongo_browser/application.rb +143 -64
  37. data/lib/mongo_browser/middleware/sprockets_base.rb +11 -0
  38. data/lib/mongo_browser/middleware/sprockets_sinatra.rb +3 -7
  39. data/lib/mongo_browser/middleware/sprockets_specs.rb +18 -0
  40. data/lib/mongo_browser/models/collection.rb +67 -0
  41. data/lib/mongo_browser/models/database.rb +52 -0
  42. data/lib/mongo_browser/models/document.rb +17 -0
  43. data/lib/mongo_browser/models/pager.rb +30 -0
  44. data/lib/mongo_browser/models/server.rb +51 -0
  45. data/lib/mongo_browser/version.rb +1 -1
  46. data/lib/mongo_browser.rb +10 -5
  47. data/mongo_browser.gemspec +4 -11
  48. data/public/index.html +47 -0
  49. data/script/ci_all +21 -0
  50. data/script/ci_e2e +11 -0
  51. data/script/ci_javascripts +4 -0
  52. data/script/ci_rspec +3 -0
  53. data/spec/features/collections_list_spec.rb +6 -49
  54. data/spec/features/documents_list_spec.rb +15 -14
  55. data/spec/features/server_info_spec.rb +3 -3
  56. data/spec/javascripts/app/controllers/alerts_spec.js.coffee +36 -0
  57. data/spec/javascripts/app/controllers/breadcrumbs_spec.js.coffee +28 -0
  58. data/spec/javascripts/app/controllers/collections_spec.js.coffee +78 -0
  59. data/spec/javascripts/app/controllers/databases_spec.js.coffee +55 -0
  60. data/spec/javascripts/app/controllers/documents_spec.js.coffee +62 -0
  61. data/spec/javascripts/app/controllers/main_spec.js.coffee +20 -0
  62. data/spec/javascripts/app/controllers/server_info_spec.js.coffee +21 -0
  63. data/spec/javascripts/app/directives_spec.js.coffee +58 -0
  64. data/spec/javascripts/app/filters_spec.js.coffee +99 -0
  65. data/spec/javascripts/app/modules/dialogs_spec.js.coffee +51 -0
  66. data/spec/javascripts/app/modules/pager_spec.js.coffee +104 -0
  67. data/spec/javascripts/app/modules/table_filter_spec.js.coffee +76 -0
  68. data/spec/javascripts/app/services_spec.js.coffee +83 -0
  69. data/spec/javascripts/config/testacular-e2e.conf.js +19 -0
  70. data/spec/javascripts/config/testacular.conf.js +43 -0
  71. data/spec/javascripts/e2e/collections_scenario.js.coffee +49 -0
  72. data/spec/javascripts/e2e/databases_scenario.js.coffee +74 -0
  73. data/spec/javascripts/e2e/documents_scenario.js.coffee +18 -0
  74. data/spec/javascripts/e2e/server_info_scenario.js.coffee +12 -0
  75. data/spec/javascripts/helpers/matchers.js.coffee +5 -0
  76. data/spec/javascripts/helpers/mocks.js.coffee +7 -0
  77. data/spec/javascripts/helpers_e2e/app_element.js.coffee +6 -0
  78. data/spec/javascripts/lib/angular-mocks.js +1740 -0
  79. data/spec/javascripts/lib/angular-scenario.js +26147 -0
  80. data/spec/javascripts/lib/jasmine-html.js +681 -0
  81. data/spec/javascripts/lib/jasmine.css +82 -0
  82. data/spec/javascripts/lib/jasmine.js +2600 -0
  83. data/spec/javascripts/runner.html +54 -0
  84. data/spec/javascripts/runner_e2e.html +10 -0
  85. data/spec/javascripts/spec.js.coffee +2 -0
  86. data/spec/javascripts/spec_e2e.js.coffee +2 -0
  87. data/spec/lib/models/collection_spec.rb +80 -0
  88. data/spec/lib/models/database_spec.rb +75 -0
  89. data/spec/lib/models/document_spec.rb +17 -0
  90. data/spec/lib/models/pager_spec.rb +64 -0
  91. data/spec/lib/models/server_spec.rb +76 -0
  92. data/spec/lib/mongo_browser_spec.rb +1 -1
  93. data/spec/spec_helper.rb +2 -19
  94. data/spec/support/feature_example_group.rb +8 -3
  95. data/spec/support/fixtures/databases.json +8 -0
  96. data/spec/support/fixtures.rb +20 -3
  97. data/spec/support/matchers/have_flash_message.rb +1 -1
  98. data/spec/support/mongod.rb +37 -21
  99. data/spec/support/mongodb.conf +47 -0
  100. data/vendor/assets/javascripts/angular/angular-bootstrap.js +166 -0
  101. data/vendor/assets/javascripts/angular/angular-resource.js +435 -0
  102. data/vendor/assets/javascripts/angular/angular-sanitize.js +535 -0
  103. data/vendor/assets/javascripts/angular/angular.js +14531 -0
  104. data/vendor/assets/javascripts/underscore.js +1200 -0
  105. metadata +136 -148
  106. data/app/assets/javascripts/app/table_filter.js.coffee +0 -50
  107. data/app/assets/javascripts/ujs.js.coffee +0 -23
  108. data/app/views/collections/index.erb +0 -59
  109. data/app/views/databases/index.erb +0 -29
  110. data/app/views/documents/index.erb +0 -61
  111. data/app/views/layout/_flash_messages.erb +0 -10
  112. data/app/views/layout/_navbar.erb +0 -22
  113. data/app/views/layout.erb +0 -20
  114. data/app/views/shared/_filter.erb +0 -14
  115. data/features/mongo_browser.feature +0 -18
  116. data/features/step_definitions/mongo_browser_steps.rb +0 -1
  117. data/features/support/env.rb +0 -18
  118. data/spec/features/databases_list_spec.rb +0 -65
@@ -0,0 +1,54 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
+ "http://www.w3.org/TR/html4/loose.dtd">
3
+ <html>
4
+ <head>
5
+ <title>Jasmine Spec Runner</title>
6
+ <script type="text/javascript" src="/assets/vendor.js"></script>
7
+
8
+ <!-- Load libraries -->
9
+ <link rel="stylesheet" type="text/css" href="/_specs/lib/jasmine.css">
10
+ <script type="text/javascript" src="/_specs/lib/jasmine.js"></script>
11
+ <script type="text/javascript" src="/_specs/lib/jasmine-html.js"></script>
12
+ <script type="text/javascript" src="/_specs/lib/angular-mocks.js"></script>
13
+
14
+ <!-- Load application files -->
15
+ <script type="text/javascript" src="/assets/app.js"></script>
16
+
17
+ <!-- Load specs -->
18
+ <script type="text/javascript" src="/assets/templates.js"></script>
19
+ <script type="text/javascript" src="/_specs/spec.js"></script>
20
+
21
+ <script type="text/javascript">
22
+ (function () {
23
+ var jasmineEnv = jasmine.getEnv();
24
+ jasmineEnv.updateInterval = 1000;
25
+
26
+ var trivialReporter = new jasmine.TrivialReporter();
27
+
28
+ jasmineEnv.addReporter(trivialReporter);
29
+
30
+ jasmineEnv.specFilter = function (spec) {
31
+ return trivialReporter.specFilter(spec);
32
+ };
33
+
34
+ var currentWindowOnload = window.onload;
35
+
36
+ window.onload = function () {
37
+ if (currentWindowOnload) {
38
+ currentWindowOnload();
39
+ }
40
+ execJasmine();
41
+ };
42
+
43
+ function execJasmine() {
44
+ jasmineEnv.execute();
45
+ }
46
+
47
+ })();
48
+ </script>
49
+
50
+ </head>
51
+
52
+ <body>
53
+ </body>
54
+ </html>
@@ -0,0 +1,10 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>End2end Test Runner</title>
5
+ <script src="/_specs/lib/angular-scenario.js" ng-autotest></script>
6
+ <script src="/_specs/spec_e2e.js"></script>
7
+ </head>
8
+ <body>
9
+ </body>
10
+ </html>
@@ -0,0 +1,2 @@
1
+ #= require_tree ./helpers
2
+ #= require_tree ./app
@@ -0,0 +1,2 @@
1
+ #= require_tree ./helpers_e2e
2
+ #= require_tree ./e2e
@@ -0,0 +1,80 @@
1
+ require "spec_helper"
2
+
3
+ describe MongoBrowser::Models::Collection do
4
+ let(:mongo_db_name) { "first_database" }
5
+ let(:mongo_collection_name) { "first_collection" }
6
+
7
+ let(:server) { MongoBrowser::Models::Server.current }
8
+
9
+ let(:mongo_collection) do
10
+ server.connection[mongo_db_name]
11
+ .collection(mongo_collection_name)
12
+ end
13
+
14
+ let(:collection) { described_class.new(mongo_collection) }
15
+ subject { collection }
16
+
17
+ it "is initialized with Mongo::Collection" do
18
+ collection.mongo_collection.should == mongo_collection
19
+ end
20
+
21
+ its(:db_name) { should == mongo_db_name }
22
+ its(:name) { should == mongo_collection_name }
23
+ its(:size) { should == 2 }
24
+
25
+ describe "#stats" do
26
+ let(:stats) { collection.stats }
27
+
28
+ it "returns stats for the collection" do
29
+ expect(stats).not_to be_nil
30
+ expect(stats).to be_an_instance_of(BSON::OrderedHash)
31
+ end
32
+ end
33
+
34
+ describe "#drop!" do
35
+ let(:database) { server.database(mongo_db_name) }
36
+
37
+ it "drops the collection" do
38
+ collection.drop!
39
+ expect(database.collection_names).not_to include(database.name)
40
+ end
41
+ end
42
+
43
+ describe "#documents_with_pagination" do
44
+ it "returns a collection of documents"
45
+
46
+ it "returns a pager"
47
+ end
48
+
49
+ describe "#find" do
50
+ let(:document) { collection.find(id) }
51
+
52
+ context "when a document exists in the collection" do
53
+ let(:mongo_document) { mongo_collection.find.first }
54
+ let(:id) { mongo_document["_id"].to_s }
55
+
56
+ it "returns a documents with the given id" do
57
+ expect(document).not_to be_nil
58
+ expect(document).to be_an_instance_of(MongoBrowser::Models::Document)
59
+ expect(document.id.to_s).to eq(id)
60
+ end
61
+ end
62
+
63
+ context "when the document does not exist" do
64
+ let(:id) { "50b908f9dac5d53509000010" }
65
+
66
+ it "returns nil" do
67
+ expect(document).to be_nil
68
+ end
69
+ end
70
+ end
71
+
72
+ describe "#remove!" do
73
+ let(:document) { MongoBrowser::Models::Document.new(mongo_collection.find.first) }
74
+
75
+ it "removes a document from the collection" do
76
+ expect(collection.remove!(document)).to be_true
77
+ expect(collection.find(document.id)).to be_nil
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe MongoBrowser::Models::Database do
4
+ let(:connection) { MongoBrowser::Models::Server.current.connection }
5
+ let(:mongo_db_name) { "first_database" }
6
+ let(:mongo_db) { connection[mongo_db_name] }
7
+
8
+ let(:database) { described_class.new(mongo_db) }
9
+ subject { database }
10
+
11
+ it "is initialized with Mongo::DB" do
12
+ database.mongo_db.should == mongo_db
13
+ end
14
+
15
+ its(:id) { should == mongo_db_name }
16
+ its(:name) { should == mongo_db_name }
17
+
18
+ its(:size) { should be_an_instance_of(Fixnum) }
19
+
20
+ describe "#collection_names" do
21
+ subject { database.collection_names }
22
+
23
+ it { should be_an_instance_of(Array) }
24
+ it { should have(4).items }
25
+ it { should include("system.indexes") }
26
+ it { should include("first_collection") }
27
+ it { should include("second_collection") }
28
+ it { should include("third_collection") }
29
+ end
30
+
31
+ describe "#collections" do
32
+ let(:collections) { database.collections }
33
+ subject { collections }
34
+
35
+ it { should be_an_instance_of(Array) }
36
+ it { should have(4).items }
37
+
38
+ it "contains Collections" do
39
+ collections.each do |db|
40
+ expect(db).to be_an_instance_of(MongoBrowser::Models::Collection)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#count" do
46
+ it "returns a number of collections" do
47
+ expect(database.count).to eq(database.collections.count)
48
+ end
49
+ end
50
+
51
+ describe "#stats" do
52
+ it "returns stats for the database" do
53
+ stats = database.stats
54
+
55
+ expect(stats).not_to be_nil
56
+ expect(stats).to be_an_instance_of(BSON::OrderedHash)
57
+ end
58
+ end
59
+
60
+ describe "#drop!" do
61
+ it "drops the database" do
62
+ database.drop!
63
+ expect(connection.database_names).not_to include(database.name)
64
+ end
65
+ end
66
+
67
+ describe "#collection" do
68
+ it "returns a collection with the given name" do
69
+ collection = database.collection("first_collection")
70
+
71
+ expect(collection).to be_an_instance_of(MongoBrowser::Models::Collection)
72
+ expect(collection.name).to eq("first_collection")
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ describe MongoBrowser::Models::Document do
4
+ let(:mongo_db_name) { "first_database" }
5
+ let(:mongo_collection_name) { "first_collection" }
6
+
7
+ let(:server) { MongoBrowser::Models::Server.current }
8
+ let(:mongo_collection) { server.connection[mongo_db_name].collection(mongo_collection_name) }
9
+ let(:mongo_document) { mongo_collection.find.first }
10
+
11
+ let(:document) { described_class.new(mongo_document) }
12
+ subject { document }
13
+
14
+ its(:id) { should_not be_nil }
15
+ its(:data) { should_not be_nil }
16
+ its(:data) { should_not be_an_instance_of(Hash) }
17
+ end
@@ -0,0 +1,64 @@
1
+ require "spec_helper"
2
+
3
+ describe MongoBrowser::Models::Pager do
4
+ let(:current_page) { 1 }
5
+ let(:size) { 25 }
6
+
7
+ let(:pager) { described_class.new(current_page, size) }
8
+ subject { pager }
9
+
10
+ before { pager.stub(:per_page).and_return(25) }
11
+
12
+ describe "#current_page" do
13
+ subject { pager.current_page }
14
+
15
+ [-2, -1, 0, 1].each do |number|
16
+ context "when the given page number is #{number}" do
17
+ let(:current_page) { number }
18
+
19
+ it("return the first page") { should == 1 }
20
+ end
21
+ end
22
+
23
+ context "when the given page number exceed the total pages number" do
24
+ let(:current_page) { 3 }
25
+ let(:size) { 30 }
26
+
27
+ it("returns the last page number") { should == 2 }
28
+ end
29
+
30
+ context "otherwise" do
31
+ let(:current_page) { 2 }
32
+ let(:size) { 26 }
33
+
34
+ it("returns the current page") { should == current_page }
35
+ end
36
+ end
37
+
38
+ describe "#offset" do
39
+ subject { pager.offset }
40
+
41
+ context "when current_page eq 1" do
42
+ it { should == 0 }
43
+ end
44
+
45
+ context "otherwise" do
46
+ let(:current_page) { 2 }
47
+ let(:size) { 26 }
48
+
49
+ it("return a valid offset") { should == 25 }
50
+ end
51
+ end
52
+
53
+ describe "#total_pages" do
54
+ subject { pager.total_pages }
55
+
56
+ { 1 => 1, 25 => 1, 26 => 2, 50 => 2, 51 => 3, 101 => 5 }.each do |size, expected|
57
+ context "when the size is #{size}" do
58
+ let(:size) { size }
59
+
60
+ it { should == expected }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,76 @@
1
+ require "spec_helper"
2
+
3
+ describe MongoBrowser::Models::Server do
4
+ describe ".current" do
5
+ it "instantiates an instance for the current (localhost) server" do
6
+ server = described_class.current
7
+ expect(server).to be_an_instance_of(described_class)
8
+ end
9
+ end
10
+
11
+ let(:server) { described_class.new(MongoBrowser.mongodb_host, MongoBrowser.mongodb_port) }
12
+ subject { server }
13
+
14
+ its(:host) { should == MongoBrowser.mongodb_host }
15
+ its(:port) { should == MongoBrowser.mongodb_port }
16
+
17
+ describe "#connection" do
18
+ it "returns a connection to the database" do
19
+ connection = server.connection
20
+ expect(connection).to be_an_instance_of(Mongo::Connection)
21
+ end
22
+ end
23
+
24
+ describe "#database_names" do
25
+ subject { server.database_names }
26
+
27
+ it { should be_an_instance_of(Array) }
28
+ it { should include("first_database") }
29
+ it { should include("second_database") }
30
+ end
31
+
32
+ describe "#databases" do
33
+ let(:databases) { server.databases }
34
+ subject { databases }
35
+
36
+ it { should be_an_instance_of(Array) }
37
+
38
+ it "contains Databases" do
39
+ databases.each do |db|
40
+ expect(db).to be_an_instance_of(MongoBrowser::Models::Database)
41
+ end
42
+ end
43
+
44
+ describe "first database" do
45
+ subject { databases.find { |db| db.name == "first_database" } }
46
+
47
+ it { should be_an_instance_of(MongoBrowser::Models::Database) }
48
+ its(:name) { should == "first_database" }
49
+ end
50
+
51
+ describe "second database" do
52
+ subject { databases.find { |db| db.name == "second_database" } }
53
+
54
+ it { should be_an_instance_of(MongoBrowser::Models::Database) }
55
+ its(:name) { should == "second_database" }
56
+ end
57
+
58
+ describe "#database" do
59
+ let(:database) { server.database("first_database") }
60
+
61
+ it "returns a database with the given name" do
62
+ expect(database).to be_an_instance_of(MongoBrowser::Models::Database)
63
+ expect(database.name).to eq("first_database")
64
+ end
65
+ end
66
+
67
+ describe "#info" do
68
+ let(:info) { server.info }
69
+
70
+ it "returns an information about the current connection" do
71
+ expect(info).not_to be_nil
72
+ expect(info).to be_an_instance_of(BSON::OrderedHash)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  describe MongoBrowser do
4
4
 
5
5
  it "defines a default host" do
6
- expect(MongoBrowser.mongodb_host).to eq("localhost")
6
+ expect(MongoBrowser.mongodb_host).to eq("127.0.0.1")
7
7
  end
8
8
 
9
9
  end
data/spec/spec_helper.rb CHANGED
@@ -4,15 +4,6 @@ require "mongo_browser"
4
4
 
5
5
  require "debugger"
6
6
  require "rspec"
7
- require "capybara"
8
- require "capybara/rspec"
9
- require "socket"
10
-
11
- require "capybara/webkit"
12
- Capybara.javascript_driver = :webkit
13
-
14
- Capybara.ignore_hidden_elements = true
15
- Capybara.app = MongoBrowser::Application
16
7
 
17
8
  # Requires supporting ruby files with custom matchers and macros, etc,
18
9
  # from spec/support/ and its subdirectories.
@@ -25,22 +16,14 @@ RSpec.configure do |config|
25
16
  config.include FeatureExampleGroup, type: :request
26
17
 
27
18
  # Run test mongod instance and load database fixtures
28
- config.before type: :request do
19
+ config.before do
29
20
  test_server.start! do |port|
30
- MongoBrowser.mongodb_host = "localhost"
21
+ MongoBrowser.mongodb_host = "127.0.0.1"
31
22
  MongoBrowser.mongodb_port = port
32
23
  end
33
24
 
34
25
  fixtures.load!
35
26
  end
36
-
37
- # Take a screenshot and html dump when the scenario has failed
38
- config.after type: :request do
39
- if example.exception
40
- file_name = example.full_description.downcase.gsub(/\s/, "-")
41
- capture_page(file_name)
42
- end
43
- end
44
27
  end
45
28
 
46
29
  at_exit do
@@ -1,9 +1,8 @@
1
1
  module FeatureExampleGroup
2
2
 
3
3
  def fill_in_filter(value)
4
- page.execute_script <<-JS
5
- $("form.filter input[type='text']").val("#{value}").keyup();
6
- JS
4
+ filter_input = find(%Q{form.filter input[type="text"]})
5
+ filter_input.set(value)
7
6
  end
8
7
 
9
8
  def confirm_dialog(message = 'Are you sure?')
@@ -17,6 +16,12 @@ module FeatureExampleGroup
17
16
  page.should have_content(message)
18
17
  click_link "OK"
19
18
  end
19
+
20
+ begin
21
+ wait_until { page.has_no_css?("div.bootbox.modal") }
22
+ rescue Capybara::TimeoutError
23
+ raise "Expected confirmation modal to be disposed."
24
+ end
20
25
  end
21
26
 
22
27
  def should_hide_the_table_and_display_a_notification
@@ -36,5 +36,13 @@
36
36
  "name": "first_collection"
37
37
  }
38
38
  ]
39
+ },
40
+ {
41
+ "name": "third_database",
42
+ "collections": [
43
+ {
44
+ "name": "first_collection"
45
+ }
46
+ ]
39
47
  }
40
48
  ]
@@ -1,3 +1,5 @@
1
+ require "singleton"
2
+
1
3
  class Fixtures
2
4
  include Singleton
3
5
 
@@ -5,7 +7,6 @@ class Fixtures
5
7
  def load!
6
8
  cleanup!
7
9
 
8
- data = JSON.parse(File.open(File.expand_path("spec/support/fixtures/databases.json"), "r").read)
9
10
  data.each do |database_data|
10
11
  database = connection.db(database_data["name"])
11
12
 
@@ -21,14 +22,30 @@ class Fixtures
21
22
 
22
23
  # Delete all databases
23
24
  def cleanup!
24
- connection.database_names.each do |db_name|
25
+ fixture_databases = data.map { |db| db["name"] }
26
+
27
+ # Drop all databases outside fixtures
28
+ other_databases = connection.database_names - fixture_databases
29
+ other_databases.each do |db_name|
25
30
  connection.drop_database(db_name)
26
31
  end
32
+
33
+ # Drop collections inside databases
34
+ fixture_databases.each do |db_name|
35
+ collection_names = connection[db_name].collection_names - ["system.indexes"]
36
+ collection_names.each do |collection_name|
37
+ connection[db_name][collection_name].drop
38
+ end
39
+ end
40
+ end
41
+
42
+ def data
43
+ JSON.parse(File.open(File.expand_path("spec/support/fixtures/databases.json"), "r").read)
27
44
  end
28
45
 
29
46
  def connection
30
47
  @connection ||= begin
31
- Mongo::Connection.new(MongoBrowser::DEFAULT_HOST, MongoBrowser.mongodb_port)
48
+ Mongo::Connection.new(MongoBrowser::DEFAULT_MONGODB_HOST, MongoBrowser.mongodb_port)
32
49
  end
33
50
  end
34
51
  end
@@ -5,7 +5,7 @@
5
5
  # end
6
6
  RSpec::Matchers.define :have_flash_message do |message|
7
7
  match do
8
- within "div#flash-messages" do
8
+ within "aside#alerts" do
9
9
  page.should have_content(message)
10
10
  end
11
11
  end
@@ -1,38 +1,44 @@
1
+ require "singleton"
2
+
3
+ # Utility for run and manage test mongod instance.
1
4
  class Mongod
2
5
  include Singleton
3
6
 
4
7
  MONGODB_DBPATH = "/tmp/mongo_browser/db"
8
+ # port for test mongod instance
9
+ MONGODB_PORT = 27018
5
10
 
6
- attr_reader :port
7
11
  attr_reader :pid
8
12
 
9
- def initialize
10
- @port = find_available_port
11
- end
12
-
13
+ # Start test mongod instance
14
+ # * it cleans up the test server directory
15
+ # * starts a daemon
16
+ # * and wait until its fully responsive
13
17
  def start!
14
18
  return if running?
15
19
 
20
+ FileUtils.rm_rf(MONGODB_DBPATH) if Dir.exist?(MONGODB_DBPATH)
16
21
  FileUtils.mkdir_p(MONGODB_DBPATH)
17
22
 
18
- @pid = Mongod.start(port)
23
+ @pid = Mongod.start
19
24
  wait_until_responsive
20
25
 
21
- yield port if block_given?
26
+ yield MONGODB_PORT if block_given?
22
27
  end
23
28
 
29
+ # Kills test mongod instance
24
30
  def shutdown!
31
+ puts "shutdown! test mongod instance"
25
32
  return unless running?
26
33
 
27
34
  Process.kill('HUP', pid)
28
- FileUtils.rm_rf(MONGODB_DBPATH)
29
35
 
30
36
  @pid = nil
31
37
  end
32
38
 
33
39
  # Returns true is mongodb server is ready to use
34
40
  def responsive?
35
- Mongo::Connection.new(MongoBrowser::DEFAULT_HOST, port)
41
+ Mongo::Connection.new(MongoBrowser::DEFAULT_MONGODB_HOST, MONGODB_PORT)
36
42
  true
37
43
  rescue Mongo::ConnectionFailure
38
44
  false
@@ -44,19 +50,29 @@ class Mongod
44
50
 
45
51
  private
46
52
 
47
- def find_available_port
48
- server = TCPServer.new(MongoBrowser::DEFAULT_HOST, 0)
49
- server.addr[1]
50
- ensure
51
- server.close if server
52
- end
53
+ class << self
54
+
55
+ # Check whether port for test mongod is available,
56
+ def test_port_available?
57
+ begin
58
+ server = TCPServer.new(MongoBrowser::DEFAULT_MONGODB_HOST, MONGODB_PORT)
59
+ true
60
+ rescue
61
+ false
62
+ end
63
+ ensure
64
+ server.close if server
65
+ end
66
+
67
+ # Starts a core MongoDB test daemon.
68
+ def start
69
+ raise "port #{MONGODB_PORT} is not available" unless test_port_available?
53
70
 
54
- # Starts a core MongoDB daemon on the given port.
55
- def self.start(port)
56
- command = "mongod --port #{port} --dbpath #{MONGODB_DBPATH} --nojournal"
57
- log_file = File.open(File.expand_path("log/test_mongod.log"), "w")
71
+ command = "mongod --config #{File.expand_path("spec/support/mongodb.conf")}"
72
+ log_file = File.open(File.expand_path("log/test_mongod.log"), "w")
58
73
 
59
- Process.spawn(command, out: log_file)
74
+ Process.spawn(command, out: log_file)
75
+ end
60
76
  end
61
77
 
62
78
  # Uses exponential back-off technique for waiting for the mongodb server
@@ -66,7 +82,7 @@ class Mongod
66
82
  timeout = 10
67
83
 
68
84
  until responsive?
69
- raise "Could not start mongod" if Time.now - start_time >= timeout
85
+ raise "Could not start mongod after #{timeout} seconds" if Time.now - start_time >= timeout
70
86
 
71
87
  sleep wait_time
72
88
  wait_time *= 2
@@ -0,0 +1,47 @@
1
+ # mongodb.conf
2
+
3
+ # Where to store the data.
4
+
5
+ # Note: if you run mongodb as a non-root user (recommended) you may
6
+ # need to create and set permissions for this directory manually,
7
+ # e.g., if the parent directory isn't mutable by the mongodb user.
8
+ dbpath=/tmp/mongo_browser/db
9
+
10
+ #where to log
11
+ logpath=/tmp/mongo_browser/db.log
12
+
13
+ logappend=true
14
+
15
+ port = 27018
16
+
17
+ # Disables write-ahead journaling
18
+ nojournal = true
19
+
20
+ # Turn on/off security. Off is currently the default
21
+ noauth = true
22
+ auth = true
23
+
24
+ # Verbose logging output.
25
+ verbose = true
26
+
27
+ # Inspect all client data for validity on receipt (useful for
28
+ # developing drivers)
29
+ objcheck = true
30
+
31
+ # Set oplogging level where n is
32
+ # 0=off (default)
33
+ # 1=W
34
+ # 2=R
35
+ # 3=both
36
+ # 7=W+some reads
37
+ diaglog = 3
38
+
39
+ # Disable the HTTP interface (Defaults to localhost:28017).
40
+ nohttpinterface = true
41
+
42
+ # Turns off server-side scripting. This will result in greatly limited
43
+ # functionality
44
+ noscripting = true
45
+
46
+ # Disable data file preallocation.
47
+ #noprealloc = true