noms-command 0.5.0
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE +191 -0
- data/README.rst +376 -0
- data/ROADMAP.rst +127 -0
- data/Rakefile +49 -0
- data/TODO.rst +7 -0
- data/bin/noms2 +20 -0
- data/fixture/dnc.rb +120 -0
- data/fixture/identity +5 -0
- data/fixture/public/dnc.json +22 -0
- data/fixture/public/echo.json +7 -0
- data/fixture/public/files/data.json +12 -0
- data/fixture/public/files/foo.json +2 -0
- data/fixture/public/lib/dnc.js +81 -0
- data/fixture/public/lib/noms-args.js +13 -0
- data/fixture/public/lib/showopt.js +18 -0
- data/fixture/public/location.json +8 -0
- data/fixture/public/showopt.json +15 -0
- data/fixture/rig2json +21 -0
- data/lib/noms/command/application.rb +204 -0
- data/lib/noms/command/auth/identity.rb +62 -0
- data/lib/noms/command/auth.rb +117 -0
- data/lib/noms/command/base.rb +22 -0
- data/lib/noms/command/document.rb +59 -0
- data/lib/noms/command/error.rb +11 -0
- data/lib/noms/command/formatter.rb +178 -0
- data/lib/noms/command/urinion/data.rb +63 -0
- data/lib/noms/command/urinion.rb +29 -0
- data/lib/noms/command/useragent.rb +134 -0
- data/lib/noms/command/version.rb +7 -0
- data/lib/noms/command/window.rb +95 -0
- data/lib/noms/command/xmlhttprequest.rb +181 -0
- data/lib/noms/command.rb +107 -0
- data/noms-command.gemspec +30 -0
- data/spec/01noms-command_spec.rb +30 -0
- data/spec/02noms-command.sh +31 -0
- data/spec/03application_spec.rb +47 -0
- data/spec/04application_spec.rb +61 -0
- data/spec/05formatter_spec.rb +195 -0
- data/spec/06urinion_data.rb +20 -0
- data/spec/07js_spec.rb +87 -0
- data/spec/08xhr_spec.rb +209 -0
- data/spec/09bookmarks_spec.rb +60 -0
- data/spec/10auth_spec.rb +33 -0
- data/spec/spec_helper.rb +40 -0
- metadata +228 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
@test "command usage" {
|
4
|
+
noms2 | grep Usage:
|
5
|
+
}
|
6
|
+
|
7
|
+
@test "command error" {
|
8
|
+
run noms2 foo
|
9
|
+
[ $status -ne 0 ]
|
10
|
+
echo "$output" | grep -q "noms error: noms command \"foo\" not found: not a URL or bookmark"
|
11
|
+
}
|
12
|
+
|
13
|
+
@test "command js error" {
|
14
|
+
run noms2 'data:application/json,{"$doctype":"noms-v2","$script":["window.alert(\"test error string\")"],"$body":[]}'
|
15
|
+
echo "$output" | grep -q "test error string"
|
16
|
+
}
|
17
|
+
|
18
|
+
@test "command js error (different namespace)" {
|
19
|
+
run noms2 'data:application/json,{"$doctype":"noms-v2","$script":["alert(\"test error string\")"],"$body":[]}'
|
20
|
+
echo "$output" | grep -q "test error string"
|
21
|
+
}
|
22
|
+
|
23
|
+
|
24
|
+
@test "scriptable auth" {
|
25
|
+
rake start
|
26
|
+
chmod 0600 test/identity
|
27
|
+
noms2 -i test/identity http://localhost:8787/auth/dnc.json | grep -q Usage:
|
28
|
+
ec=$?
|
29
|
+
rake stop
|
30
|
+
[ $ec -eq 0 ]
|
31
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'noms/command/application'
|
6
|
+
|
7
|
+
describe "NOMS::Command::Application" do
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
setup_fixture 'test'
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
teardown_fixture 'test'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.new' do
|
18
|
+
context 'with local file' do
|
19
|
+
before(:all) do
|
20
|
+
@doc = NOMS::Command::Application.new(
|
21
|
+
"file:///#{Dir.pwd}/test/public/files/foo.json", [])
|
22
|
+
@doc.fetch!
|
23
|
+
end
|
24
|
+
|
25
|
+
specify { expect(@doc.type).to eq 'noms-v2' }
|
26
|
+
specify { expect(@doc.body).to have_key '$doctype' }
|
27
|
+
specify { expect(@doc.body).to have_key '$body' }
|
28
|
+
specify { expect(@doc.display).to eq 'Test output for foo.json' }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with data URL' do
|
32
|
+
before(:all) do
|
33
|
+
@doc = NOMS::Command::Application.new(
|
34
|
+
'data:application/json,{"$doctype":"noms-v2","$body":[]}',
|
35
|
+
[])
|
36
|
+
@doc.fetch!
|
37
|
+
end
|
38
|
+
|
39
|
+
specify { expect(@doc.type).to eq 'noms-v2' }
|
40
|
+
specify { expect(@doc.body).to have_key '$doctype' }
|
41
|
+
specify { expect(@doc.body).to have_key '$body' }
|
42
|
+
specify { expect(@doc.display).to eq '' }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'uri'
|
6
|
+
require 'noms/command/application'
|
7
|
+
require 'noms/command/window'
|
8
|
+
|
9
|
+
describe NOMS::Command::Application do
|
10
|
+
|
11
|
+
before(:all) do
|
12
|
+
# Start the DNC application web server on port 8787
|
13
|
+
setup_fixture
|
14
|
+
start_server
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:all) do
|
18
|
+
stop_server
|
19
|
+
teardown_fixture
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.new' do
|
23
|
+
|
24
|
+
context 'with no arguments' do
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
@app = NOMS::Command::Application.new(
|
28
|
+
URI.parse('http://localhost:8787/dnc.json'),
|
29
|
+
[])
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should produce a usage message" do
|
35
|
+
app = NOMS::Command::Application.new('http://localhost:8787/dnc.json',
|
36
|
+
['dnc'])
|
37
|
+
app.fetch!
|
38
|
+
app.render!
|
39
|
+
expect(app.display).to include 'Usage:'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should produce a list of DNC records" do
|
43
|
+
app = NOMS::Command::Application.new('http://localhost:8787/dnc.json',
|
44
|
+
['dnc', 'list'])
|
45
|
+
app.fetch!
|
46
|
+
app.render!
|
47
|
+
expect(app.display.split("\n").length).to be > 9
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should follow a redirect" do
|
51
|
+
app = NOMS::Command::Application.new('http://localhost:8787/alt/dnc.json',
|
52
|
+
['dnc', 'list'])
|
53
|
+
app.fetch!
|
54
|
+
app.render!
|
55
|
+
expect(app.display.split("\n").length).to be > 9
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,195 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
require 'noms/command/formatter'
|
8
|
+
|
9
|
+
describe NOMS::Command::Formatter do
|
10
|
+
|
11
|
+
describe '#render' do
|
12
|
+
|
13
|
+
subject(:formatter) { NOMS::Command::Formatter.new }
|
14
|
+
|
15
|
+
it 'renders nil as ""' do
|
16
|
+
expect(formatter.render(nil)).to eq ''
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'renders a string as a string' do
|
20
|
+
expect(formatter.render("one")).to eq 'one'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'renders a number as a string' do
|
24
|
+
expect(formatter.render(1)).to eq '1'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'renders a boolean as a string' do
|
28
|
+
expect(formatter.render(true)).to eq 'true'
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'renders an array of strings as a list of lines' do
|
32
|
+
lines = [
|
33
|
+
'one',
|
34
|
+
'two',
|
35
|
+
'three' ]
|
36
|
+
expect(formatter.render(lines)).to eq "one\ntwo\nthree"
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'renders a raw object as a YAML object' do
|
40
|
+
object = {
|
41
|
+
'one' => 1,
|
42
|
+
'two' => 2,
|
43
|
+
'three' => 3
|
44
|
+
}
|
45
|
+
expect(formatter.render(object)).to eq object.to_yaml
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'renders a object-list as formatted lines' do
|
49
|
+
object_list = {
|
50
|
+
'$type' => 'object-list',
|
51
|
+
'$header' => true,
|
52
|
+
'$columns' => [
|
53
|
+
{
|
54
|
+
'field' => 'priority',
|
55
|
+
'width' => 3,
|
56
|
+
'align' => 'right',
|
57
|
+
'heading' => 'Pri'
|
58
|
+
},
|
59
|
+
{
|
60
|
+
'field' => 'title',
|
61
|
+
'width' => 10,
|
62
|
+
'heading' => 'Name'
|
63
|
+
},
|
64
|
+
'description'
|
65
|
+
],
|
66
|
+
'$data' => [
|
67
|
+
{
|
68
|
+
'title' => 'Issue 1',
|
69
|
+
'priority' => 3,
|
70
|
+
'description' => 'The first issue'
|
71
|
+
},
|
72
|
+
{
|
73
|
+
'title' => 'Issue 2',
|
74
|
+
'priority' => 2,
|
75
|
+
'description' => 'The second issue'
|
76
|
+
}
|
77
|
+
]
|
78
|
+
}
|
79
|
+
output = <<-TEST.gsub(/^\s{12}/,'').gsub(/\n$/,'')
|
80
|
+
Pri Name description
|
81
|
+
3 Issue 1 The first issue
|
82
|
+
2 Issue 2 The second issue
|
83
|
+
TEST
|
84
|
+
expect(formatter.render(object_list)).to eq output
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'renders an object as record-formatted' do
|
88
|
+
object = {
|
89
|
+
'$type' => 'object',
|
90
|
+
'$data' => {
|
91
|
+
'title' => 'Issue 2',
|
92
|
+
'priority' => 3,
|
93
|
+
'description' => 'The second issue',
|
94
|
+
'contributors' => [
|
95
|
+
'fred',
|
96
|
+
'wilma',
|
97
|
+
'barney',
|
98
|
+
'gazoo'
|
99
|
+
]
|
100
|
+
}
|
101
|
+
}
|
102
|
+
output = <<-TEST.gsub(/^\s{12}/,'').gsub(/\n$/,'')
|
103
|
+
contributors: ["fred","wilma","barney","gazoo"]
|
104
|
+
description: The second issue
|
105
|
+
priority: 3
|
106
|
+
title: Issue 2
|
107
|
+
TEST
|
108
|
+
expect(formatter.render(object)).to eq output
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'honors field list and option for object' do
|
112
|
+
object = {
|
113
|
+
'$type' => 'object',
|
114
|
+
'$fields' => ['title'],
|
115
|
+
'$labels' => false,
|
116
|
+
'$data' => {
|
117
|
+
'title' => 'Issue 2',
|
118
|
+
'priority' => 3,
|
119
|
+
'description' => 'The second issue',
|
120
|
+
'contributors' => [
|
121
|
+
'fred',
|
122
|
+
'wilma',
|
123
|
+
'barney',
|
124
|
+
'gazoo'
|
125
|
+
]
|
126
|
+
}
|
127
|
+
}
|
128
|
+
output = 'Issue 2'
|
129
|
+
expect(formatter.render(object)).to eq output
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'renders an object-list as CSV' do
|
133
|
+
object_list = {
|
134
|
+
'$type' => 'object-list',
|
135
|
+
'$header' => true,
|
136
|
+
'$format' => 'csv',
|
137
|
+
'$columns' => [
|
138
|
+
{
|
139
|
+
'field' => 'priority',
|
140
|
+
'width' => 3,
|
141
|
+
'align' => 'right',
|
142
|
+
'heading' => 'Pri'
|
143
|
+
},
|
144
|
+
{
|
145
|
+
'field' => 'title',
|
146
|
+
'width' => 10,
|
147
|
+
'heading' => 'Name'
|
148
|
+
},
|
149
|
+
'description'
|
150
|
+
],
|
151
|
+
'$data' => [
|
152
|
+
{
|
153
|
+
'title' => 'Issue 1',
|
154
|
+
'priority' => 3,
|
155
|
+
'description' => 'The first issue'
|
156
|
+
},
|
157
|
+
{
|
158
|
+
'title' => 'Issue 2',
|
159
|
+
'priority' => 2,
|
160
|
+
'description' => 'The second issue'
|
161
|
+
}
|
162
|
+
]
|
163
|
+
}
|
164
|
+
output = <<-TEST.gsub(/^\s{12}/,'').gsub(/\n$/,'')
|
165
|
+
Pri,Name,description
|
166
|
+
3,Issue 1,The first issue
|
167
|
+
2,Issue 2,The second issue
|
168
|
+
TEST
|
169
|
+
expect(formatter.render(object_list)).to eq output
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'renders an object as JSON' do
|
173
|
+
object = {
|
174
|
+
'$type' => 'object',
|
175
|
+
'$format' => 'json',
|
176
|
+
'$fields' => ['title','priority'],
|
177
|
+
'$data' => {
|
178
|
+
'title' => 'Issue 2',
|
179
|
+
'priority' => 3,
|
180
|
+
'description' => 'The second issue',
|
181
|
+
'contributors' => [
|
182
|
+
'fred',
|
183
|
+
'wilma',
|
184
|
+
'barney',
|
185
|
+
'gazoo'
|
186
|
+
]
|
187
|
+
}
|
188
|
+
}
|
189
|
+
output = JSON.pretty_generate({ 'title' => 'Issue 2', 'priority' => 3 })
|
190
|
+
expect(formatter.render(object)).to eq output
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'noms/command/urinion/data'
|
6
|
+
|
7
|
+
describe NOMS::Command::URInion::Data do
|
8
|
+
describe '.parse' do
|
9
|
+
context 'when parsing JSON' do
|
10
|
+
subject(:url) { NOMS::Command::URInion::Data.parse('data:application/json;charset=UTF-8,{"one":1}') }
|
11
|
+
specify { expect(url.host).to be_nil }
|
12
|
+
specify { expect(url.scheme).to eq 'data' }
|
13
|
+
specify { expect(url.path).to be_nil }
|
14
|
+
specify { expect(url.data_encoding).to be_nil }
|
15
|
+
specify { expect(url.mime_type).to eq 'application/json' }
|
16
|
+
specify { expect(url.character_set).to eq 'UTF-8' }
|
17
|
+
specify { expect(url.data).to eq '{"one":1}' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/07js_spec.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
require 'base64'
|
7
|
+
require 'logger'
|
8
|
+
|
9
|
+
require 'noms/command/application'
|
10
|
+
|
11
|
+
def make_script_app(js, opt={})
|
12
|
+
doc = {
|
13
|
+
'$doctype' => 'noms-v2',
|
14
|
+
'$body' => ['Usage:',' noms echo <string>'],
|
15
|
+
'$script' => [js]
|
16
|
+
}
|
17
|
+
NOMS::Command::Application.new('data:application/json,' + JSON.pretty_generate(doc),
|
18
|
+
%w(echo one two three), opt)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe NOMS::Command::Application do
|
22
|
+
|
23
|
+
describe '.render!' do
|
24
|
+
|
25
|
+
subject(:doc) do
|
26
|
+
make_script_app "window.document.body = window.document.argv.slice(1).join(' ')"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have initial output" do
|
30
|
+
doc.fetch!
|
31
|
+
expect(doc.display).to eq "Usage:\n noms echo <string>"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should render by echoing arguments" do
|
35
|
+
doc.fetch!
|
36
|
+
doc.render!
|
37
|
+
expect(doc.display).to eq "one two three"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'in javascript runtime' do
|
43
|
+
|
44
|
+
describe ' window' do
|
45
|
+
|
46
|
+
describe '.name' do
|
47
|
+
|
48
|
+
it "should have a name" do
|
49
|
+
app = make_script_app "document.body = window.name"
|
50
|
+
app.window.name = 'test-js_spec'
|
51
|
+
app.fetch!
|
52
|
+
app.render!
|
53
|
+
expect(app.display).to eq 'test-js_spec'
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'console' do
|
61
|
+
|
62
|
+
it "should produce debugging output" do
|
63
|
+
logcatcher = StringIO.new
|
64
|
+
log = Logger.new(logcatcher)
|
65
|
+
log.level = Logger::DEBUG
|
66
|
+
|
67
|
+
app = make_script_app("console.log('test debug output')", :logger => log)
|
68
|
+
app.fetch!
|
69
|
+
app.render!
|
70
|
+
expect(logcatcher.string).to match(/^D,.*test debug output$/)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'location' do
|
76
|
+
|
77
|
+
it "should describe URL location" do
|
78
|
+
app = make_script_app "document.body = location.protocol"
|
79
|
+
app.fetch!
|
80
|
+
app.render!
|
81
|
+
expect(app.display).to eq 'data'
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/spec/08xhr_spec.rb
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
#!/usr/bin/env rspec
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'v8'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
require 'noms/command/xmlhttprequest'
|
9
|
+
|
10
|
+
describe NOMS::Command::XMLHttpRequest do
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
# I'm going to go with this class variable for now
|
14
|
+
|
15
|
+
# Start the DNC application web server on port 8787
|
16
|
+
setup_fixture 'test'
|
17
|
+
start_server 'test'
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:all) do
|
21
|
+
stop_server 'test'
|
22
|
+
teardown_fixture 'test'
|
23
|
+
end
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
NOMS::Command::XMLHttpRequest.origin = 'http://localhost:8787/files/dnc.json'
|
27
|
+
NOMS::Command::XMLHttpRequest.useragent = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'from ruby' do
|
31
|
+
|
32
|
+
before(:each) do
|
33
|
+
@xhr = NOMS::Command::XMLHttpRequest.new
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#readyState' do
|
37
|
+
it 'should be 0' do
|
38
|
+
expect(@xhr.readyState).to eq 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'statuses' do
|
43
|
+
it 'should be equal to the correct number' do
|
44
|
+
expect(@xhr.OPENED).to eq 1
|
45
|
+
expect(@xhr.HEADERS_RECEIVED).to eq 2
|
46
|
+
expect(@xhr.LOADING).to eq 3
|
47
|
+
expect(@xhr.DONE).to eq 4
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#open' do
|
52
|
+
# open, send, check readyState and responseText
|
53
|
+
|
54
|
+
it 'should retrieve web content' do
|
55
|
+
@xhr.open('GET', 'http://localhost:8787/files/data.json', false)
|
56
|
+
@xhr.send()
|
57
|
+
expect(@xhr.responseText).to match /^\[/
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should retrieve web content from relative URL' do
|
61
|
+
@xhr.open('GET', '/files/data.json', false)
|
62
|
+
@xhr.send()
|
63
|
+
expect(@xhr.responseText).to match /^\[/
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should raise an error on different-origin' do
|
67
|
+
expect {
|
68
|
+
@xhr.open('GET', 'http://localhost:8786/files/data.json', false)
|
69
|
+
}.to raise_error NOMS::Command::Error
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#setRequestHeader' do
|
75
|
+
|
76
|
+
it 'should set the request header' do
|
77
|
+
@xhr.setRequestHeader('Accept', 'text/plain')
|
78
|
+
expect(@xhr.headers['Accept']).to eq 'text/plain'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#abort' do
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'from javascript' do
|
89
|
+
|
90
|
+
before(:each) do
|
91
|
+
@v8 = V8::Context.new
|
92
|
+
@v8[:XMLHttpRequest] = NOMS::Command::XMLHttpRequest
|
93
|
+
@v8.eval 'var xhr = new XMLHttpRequest()'
|
94
|
+
@xhr = @v8[:xhr]
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#open' do
|
98
|
+
# open, send, check readyState and responseText
|
99
|
+
it 'should retrieve web content' do
|
100
|
+
@v8.eval 'xhr.open("GET", "http://localhost:8787/files/data.json", false)'
|
101
|
+
@v8.eval 'xhr.send()'
|
102
|
+
expect(@v8.eval 'xhr.responseText').to match(/^\[/)
|
103
|
+
expect(@v8.eval 'xhr.readyState').to eq 4
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should retrieve web content from relative URL' do
|
107
|
+
@v8.eval 'xhr.open("GET", "/files/data.json", false)'
|
108
|
+
@v8.eval 'xhr.send()'
|
109
|
+
expect(@v8.eval 'xhr.responseText').to match(/^\[/)
|
110
|
+
expect(@v8.eval 'xhr.readyState').to eq 4
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should post objects to rest app' do
|
114
|
+
@v8[:newdata] = {
|
115
|
+
'name' => 'Frances Simmons',
|
116
|
+
'street' => '180 Tomkins Blcd',
|
117
|
+
'city' => 'Minneapolis, MN 55401',
|
118
|
+
'phone' => '(612) 555-0180'
|
119
|
+
}.to_json
|
120
|
+
@v8.eval 'xhr.open("POST", "/dnc", false);'
|
121
|
+
@v8.eval 'xhr.send(newdata);'
|
122
|
+
obj = JSON.parse(@v8.eval 'xhr.responseText')
|
123
|
+
expect(obj).to have_key 'id'
|
124
|
+
|
125
|
+
@v8.eval "xhr.open(\"GET\", \"/dnc/#{obj['id']}\", false);"
|
126
|
+
@v8.eval 'xhr.send();'
|
127
|
+
retobj = JSON.parse(@v8.eval 'xhr.responseText')
|
128
|
+
expect(retobj['name']).to eq 'Frances Simmons'
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should update objects in rest app' do
|
132
|
+
@v8.eval 'xhr.open("GET", "/dnc/1", false);'
|
133
|
+
@v8.eval 'xhr.send();'
|
134
|
+
obj = JSON.parse(@v8.eval 'xhr.responseText')
|
135
|
+
obj['phone'] = '(999) 555-9999'
|
136
|
+
@v8[:newobject] = obj.to_json
|
137
|
+
|
138
|
+
@v8.eval 'xhr.open("PUT", "/dnc/1", false);'
|
139
|
+
@v8.eval 'xhr.send(newobject);'
|
140
|
+
newobject = JSON.parse(@v8.eval 'xhr.responseText')
|
141
|
+
expect(newobject['id']).to eq 1
|
142
|
+
expect(newobject['phone']).to eq '(999) 555-9999'
|
143
|
+
|
144
|
+
@v8.eval 'xhr.open("GET", "/dnc/1", false);'
|
145
|
+
@v8.eval 'xhr.send();'
|
146
|
+
retobj = JSON.parse(@v8.eval 'xhr.responseText')
|
147
|
+
expect(retobj['phone']).to eq '(999) 555-9999'
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should delete objects in rest app' do
|
151
|
+
@v8.eval 'xhr.open("DELETE", "/dnc/2", false);'
|
152
|
+
@v8.eval 'xhr.send();'
|
153
|
+
expect(@v8.eval 'xhr.status').to eq 204
|
154
|
+
|
155
|
+
@v8.eval 'xhr.open("GET", "/dnc/2", false);'
|
156
|
+
@v8.eval 'xhr.send();'
|
157
|
+
expect(@v8.eval 'xhr.status').to eq 404
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should not follow cross-origin redirects' do
|
161
|
+
@v8.eval 'xhr.open("GET", "/readme", false);'
|
162
|
+
@v8.eval 'xhr.send();'
|
163
|
+
expect(@v8.eval 'xhr.status').to eq 302
|
164
|
+
expect(@v8.eval 'xhr.responseText').to eq 'README'
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
describe '#setRequestHeader' do
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '#onreadystatechange' do
|
174
|
+
|
175
|
+
it 'should be triggered by state change events' do
|
176
|
+
@v8.eval <<-JS
|
177
|
+
var content = "";
|
178
|
+
xhr.onreadystatechange = function() {
|
179
|
+
if (this.readyState == this.DONE) {
|
180
|
+
content = this.responseText;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
JS
|
184
|
+
@v8.eval 'xhr.open("GET", "/files/data.json", true)'
|
185
|
+
@v8.eval 'xhr.send()'
|
186
|
+
@xhr.useragent.wait
|
187
|
+
expect(@v8[:content]).to match(/^\[/)
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
describe '#abort' do
|
193
|
+
|
194
|
+
it 'cancels a request' do
|
195
|
+
# We don't really have true asynchronous requests,
|
196
|
+
# in particular we can't interrupt between calling
|
197
|
+
# send() and the readyState changing to 4. So
|
198
|
+
# this is kind of a no-op.
|
199
|
+
|
200
|
+
@v8.eval 'xhr.open("GET", "/files/data.json", true);'
|
201
|
+
@v8.eval 'xhr.abort();'
|
202
|
+
expect(@v8.eval 'xhr.readyState').to eq 0
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|