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.
- data/.gitignore +3 -0
- data/.travis.yml +3 -3
- data/README.md +1 -25
- data/Rakefile +0 -1
- data/app/assets/images/background.png +0 -0
- data/app/assets/javascripts/app/controllers/alerts.js.coffee +12 -0
- data/app/assets/javascripts/app/controllers/breadcrumbs.js.coffee +25 -0
- data/app/assets/javascripts/app/controllers/collections.js.coffee +40 -0
- data/app/assets/javascripts/app/controllers/databases.js.coffee +39 -0
- data/app/assets/javascripts/app/controllers/documents.js.coffee +49 -0
- data/app/assets/javascripts/app/controllers/main.js.coffee +10 -0
- data/app/assets/javascripts/app/controllers/server_info.js.coffee +14 -0
- data/app/assets/javascripts/app/controllers.js.coffee +2 -0
- data/app/assets/javascripts/app/directives.js.coffee +20 -0
- data/app/assets/javascripts/app/filters.js.coffee +48 -0
- data/app/assets/javascripts/app/modules/dialogs.js.coffee +29 -0
- data/app/assets/javascripts/app/modules/pager.js.coffee +87 -0
- data/app/assets/javascripts/app/modules/table_filter.js.coffee +27 -0
- data/app/assets/javascripts/app/resources.js.coffee +22 -0
- data/app/assets/javascripts/app/services.js.coffee +36 -0
- data/app/assets/javascripts/app.js.coffee +8 -0
- data/app/assets/javascripts/application.js.coffee +35 -6
- data/app/assets/javascripts/templates/.gitkeep +0 -0
- data/app/assets/javascripts/templates.js.coffee +1 -0
- data/app/assets/javascripts/vendor.js.coffee +5 -0
- data/app/assets/stylesheets/application.css.scss +46 -3
- data/app/assets/templates/collections.html +53 -0
- data/app/assets/templates/databases.html +32 -0
- data/app/assets/templates/documents.html +45 -0
- data/app/assets/templates/pager.html +13 -0
- data/app/{views/server_info.erb → assets/templates/server_info.html} +5 -7
- data/app/assets/templates/table_filter.html +10 -0
- data/bin/mongo_browser +8 -45
- data/config-e2e.ru +20 -0
- data/grunt.js +36 -0
- data/lib/mongo_browser/application.rb +143 -64
- data/lib/mongo_browser/middleware/sprockets_base.rb +11 -0
- data/lib/mongo_browser/middleware/sprockets_sinatra.rb +3 -7
- data/lib/mongo_browser/middleware/sprockets_specs.rb +18 -0
- data/lib/mongo_browser/models/collection.rb +67 -0
- data/lib/mongo_browser/models/database.rb +52 -0
- data/lib/mongo_browser/models/document.rb +17 -0
- data/lib/mongo_browser/models/pager.rb +30 -0
- data/lib/mongo_browser/models/server.rb +51 -0
- data/lib/mongo_browser/version.rb +1 -1
- data/lib/mongo_browser.rb +10 -5
- data/mongo_browser.gemspec +4 -11
- data/public/index.html +47 -0
- data/script/ci_all +21 -0
- data/script/ci_e2e +11 -0
- data/script/ci_javascripts +4 -0
- data/script/ci_rspec +3 -0
- data/spec/features/collections_list_spec.rb +6 -49
- data/spec/features/documents_list_spec.rb +15 -14
- data/spec/features/server_info_spec.rb +3 -3
- data/spec/javascripts/app/controllers/alerts_spec.js.coffee +36 -0
- data/spec/javascripts/app/controllers/breadcrumbs_spec.js.coffee +28 -0
- data/spec/javascripts/app/controllers/collections_spec.js.coffee +78 -0
- data/spec/javascripts/app/controllers/databases_spec.js.coffee +55 -0
- data/spec/javascripts/app/controllers/documents_spec.js.coffee +62 -0
- data/spec/javascripts/app/controllers/main_spec.js.coffee +20 -0
- data/spec/javascripts/app/controllers/server_info_spec.js.coffee +21 -0
- data/spec/javascripts/app/directives_spec.js.coffee +58 -0
- data/spec/javascripts/app/filters_spec.js.coffee +99 -0
- data/spec/javascripts/app/modules/dialogs_spec.js.coffee +51 -0
- data/spec/javascripts/app/modules/pager_spec.js.coffee +104 -0
- data/spec/javascripts/app/modules/table_filter_spec.js.coffee +76 -0
- data/spec/javascripts/app/services_spec.js.coffee +83 -0
- data/spec/javascripts/config/testacular-e2e.conf.js +19 -0
- data/spec/javascripts/config/testacular.conf.js +43 -0
- data/spec/javascripts/e2e/collections_scenario.js.coffee +49 -0
- data/spec/javascripts/e2e/databases_scenario.js.coffee +74 -0
- data/spec/javascripts/e2e/documents_scenario.js.coffee +18 -0
- data/spec/javascripts/e2e/server_info_scenario.js.coffee +12 -0
- data/spec/javascripts/helpers/matchers.js.coffee +5 -0
- data/spec/javascripts/helpers/mocks.js.coffee +7 -0
- data/spec/javascripts/helpers_e2e/app_element.js.coffee +6 -0
- data/spec/javascripts/lib/angular-mocks.js +1740 -0
- data/spec/javascripts/lib/angular-scenario.js +26147 -0
- data/spec/javascripts/lib/jasmine-html.js +681 -0
- data/spec/javascripts/lib/jasmine.css +82 -0
- data/spec/javascripts/lib/jasmine.js +2600 -0
- data/spec/javascripts/runner.html +54 -0
- data/spec/javascripts/runner_e2e.html +10 -0
- data/spec/javascripts/spec.js.coffee +2 -0
- data/spec/javascripts/spec_e2e.js.coffee +2 -0
- data/spec/lib/models/collection_spec.rb +80 -0
- data/spec/lib/models/database_spec.rb +75 -0
- data/spec/lib/models/document_spec.rb +17 -0
- data/spec/lib/models/pager_spec.rb +64 -0
- data/spec/lib/models/server_spec.rb +76 -0
- data/spec/lib/mongo_browser_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -19
- data/spec/support/feature_example_group.rb +8 -3
- data/spec/support/fixtures/databases.json +8 -0
- data/spec/support/fixtures.rb +20 -3
- data/spec/support/matchers/have_flash_message.rb +1 -1
- data/spec/support/mongod.rb +37 -21
- data/spec/support/mongodb.conf +47 -0
- data/vendor/assets/javascripts/angular/angular-bootstrap.js +166 -0
- data/vendor/assets/javascripts/angular/angular-resource.js +435 -0
- data/vendor/assets/javascripts/angular/angular-sanitize.js +535 -0
- data/vendor/assets/javascripts/angular/angular.js +14531 -0
- data/vendor/assets/javascripts/underscore.js +1200 -0
- metadata +136 -148
- data/app/assets/javascripts/app/table_filter.js.coffee +0 -50
- data/app/assets/javascripts/ujs.js.coffee +0 -23
- data/app/views/collections/index.erb +0 -59
- data/app/views/databases/index.erb +0 -29
- data/app/views/documents/index.erb +0 -61
- data/app/views/layout/_flash_messages.erb +0 -10
- data/app/views/layout/_navbar.erb +0 -22
- data/app/views/layout.erb +0 -20
- data/app/views/shared/_filter.erb +0 -14
- data/features/mongo_browser.feature +0 -18
- data/features/step_definitions/mongo_browser_steps.rb +0 -1
- data/features/support/env.rb +0 -18
- 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,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
|
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
|
19
|
+
config.before do
|
29
20
|
test_server.start! do |port|
|
30
|
-
MongoBrowser.mongodb_host = "
|
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
|
-
|
5
|
-
|
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
|
data/spec/support/fixtures.rb
CHANGED
@@ -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
|
-
|
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::
|
48
|
+
Mongo::Connection.new(MongoBrowser::DEFAULT_MONGODB_HOST, MongoBrowser.mongodb_port)
|
32
49
|
end
|
33
50
|
end
|
34
51
|
end
|
data/spec/support/mongod.rb
CHANGED
@@ -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
|
-
|
10
|
-
|
11
|
-
|
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
|
23
|
+
@pid = Mongod.start
|
19
24
|
wait_until_responsive
|
20
25
|
|
21
|
-
yield
|
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::
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
55
|
-
|
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
|
-
|
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
|