mongo_browser 0.1.3 → 0.2.0.rc2

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