jsonapi-grader 0.0.1 → 0.1.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 +4 -4
- data/bin/jsonapi-grader +10 -1
- data/lib/jsonapi/grader/serialization_grader.rb +64 -0
- data/lib/jsonapi/grader/server/scenarii/empty_collection.rb +45 -0
- data/lib/jsonapi/grader/server/scenarii.rb +1 -0
- data/lib/jsonapi/grader/server/scenario.rb +31 -0
- data/lib/jsonapi/grader/server_grader.rb +41 -0
- data/lib/jsonapi/grader.rb +2 -63
- data/{scenarii.json → scenarii_serialization.json} +0 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36b447ba1230dd7ab8e6c1546ed576c0bf559c29
|
4
|
+
data.tar.gz: 9b28cc55cb678ce74d91a2e1d44ac02cc0154c14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab4280c8cc133cf54a8169c26b247ef290d818a0d745533a451222d8d54b4600c557c6b3e0a0d96f24bce641dc8bc3626bdc8b3c50a7ca0f0771a8ab260ffc5a
|
7
|
+
data.tar.gz: d20412c5bb6b74c1c1470bf5704c64c2b3b072ede3068aa8154d06360f5107ca24aae1be33a4f003c4ffcb2a210f2a48bbf0c5f2fd2034fb6555e72d35ec923b
|
data/bin/jsonapi-grader
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'jsonapi/grader'
|
4
4
|
|
5
|
-
grader =
|
5
|
+
grader =
|
6
|
+
case ARGV[0]
|
7
|
+
when 'serialization'
|
8
|
+
JSONAPI::Grader::SerializationGrader.new('scenarii_serialization.json',
|
9
|
+
implementation_dir: ARGV[1])
|
10
|
+
when 'server'
|
11
|
+
JSONAPI::Grader::ServerGrader.new(host: ARGV[1])
|
12
|
+
else
|
13
|
+
raise 'Unknown arguments'
|
14
|
+
end
|
6
15
|
|
7
16
|
grader.grade
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
module Grader
|
5
|
+
class SerializationGrader
|
6
|
+
def initialize(scenarii_file = 'scenarii_serialization.json', options = {})
|
7
|
+
scenarii_file = File.expand_path("../../../#{scenarii_file}", __dir__)
|
8
|
+
@scenarii = JSON.parse(File.read(scenarii_file))
|
9
|
+
@implementation_dir = options[:implementation_dir]
|
10
|
+
end
|
11
|
+
|
12
|
+
def grade
|
13
|
+
compliance = true
|
14
|
+
score = 0
|
15
|
+
max_score = 0
|
16
|
+
@scenarii.each do |scenario|
|
17
|
+
current_score = score_scenario(scenario)
|
18
|
+
compliance = false if scenario['required'] && current_score == 0
|
19
|
+
max_score += scenario['score']
|
20
|
+
score += current_score
|
21
|
+
end
|
22
|
+
|
23
|
+
STDERR.puts "Compliance: #{compliance}"
|
24
|
+
score_percent = (100.0 * score / max_score).round(2)
|
25
|
+
STDERR.puts "Score: #{score} / #{max_score} (#{score_percent}%)"
|
26
|
+
|
27
|
+
score
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def score_scenario(scenario)
|
33
|
+
document_file = File.expand_path("../../../#{scenario['file']}", __dir__)
|
34
|
+
reference_document = normalize(JSON.parse(File.read(document_file)))
|
35
|
+
implementation = "#{@implementation_dir}/#{scenario['name']}"
|
36
|
+
STDERR.print "Running scenario #{scenario['name']}... "
|
37
|
+
$stderr.flush
|
38
|
+
unless File.exists?(implementation)
|
39
|
+
STDERR.puts "not implemented"
|
40
|
+
return 0
|
41
|
+
end
|
42
|
+
|
43
|
+
actual_document = normalize(JSON.parse(`#{implementation}`))
|
44
|
+
if reference_document == actual_document
|
45
|
+
STDERR.puts "passed"
|
46
|
+
return scenario['score']
|
47
|
+
else
|
48
|
+
STDERR.puts "failed"
|
49
|
+
STDERR.puts "Expected: #{reference_document}"
|
50
|
+
STDERR.puts "Got: #{actual_document}"
|
51
|
+
return 0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def normalize(document)
|
56
|
+
return document unless document.key?('included')
|
57
|
+
|
58
|
+
document['included'].sort do |a, b|
|
59
|
+
[a['type'], a['id']] <=> [b['type'], b['id']]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'jsonapi/grader/server/scenario'
|
3
|
+
|
4
|
+
module JSONAPI
|
5
|
+
module Grader
|
6
|
+
module Server
|
7
|
+
class EmptyCollectionScenario < Scenario
|
8
|
+
def name
|
9
|
+
'empty_collection'
|
10
|
+
end
|
11
|
+
|
12
|
+
def description
|
13
|
+
'The endpoint /empty_collection should return an empty collection.'
|
14
|
+
end
|
15
|
+
|
16
|
+
def score
|
17
|
+
100
|
18
|
+
end
|
19
|
+
|
20
|
+
def required
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(host)
|
25
|
+
uri = URI("#{host}/empty_collection")
|
26
|
+
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
27
|
+
req = Net::HTTP::Get.new(uri)
|
28
|
+
req['Accept'] = 'application/vnd.api+json'
|
29
|
+
|
30
|
+
http.request(req)
|
31
|
+
end
|
32
|
+
|
33
|
+
unless res['Content-Type'] == 'application/vnd.api+json'
|
34
|
+
fail 'Expected Content-Type header to equal application/vnd.api+json'
|
35
|
+
end
|
36
|
+
|
37
|
+
body = JSON.parse(res.body)
|
38
|
+
unless body['data'] == []
|
39
|
+
fail 'Expected empty collection'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'jsonapi/grader/server/scenarii/empty_collection'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module JSONAPI
|
2
|
+
module Grader
|
3
|
+
module Server
|
4
|
+
class Scenario
|
5
|
+
def call(host)
|
6
|
+
raise 'Not implemented'
|
7
|
+
end
|
8
|
+
|
9
|
+
def score
|
10
|
+
raise 'Not implemented'
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
raise 'Not implemented'
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
raise 'Not implemented'
|
19
|
+
end
|
20
|
+
|
21
|
+
def endpoint
|
22
|
+
raise 'Not implemented'
|
23
|
+
end
|
24
|
+
|
25
|
+
def required
|
26
|
+
raise 'Not implemented'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'jsonapi/grader/server/scenarii'
|
2
|
+
|
3
|
+
module JSONAPI
|
4
|
+
module Grader
|
5
|
+
class ServerGrader
|
6
|
+
SCENARII = [Server::EmptyCollectionScenario.new]
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@host = options[:host]
|
10
|
+
end
|
11
|
+
|
12
|
+
def grade
|
13
|
+
compliance = true
|
14
|
+
score = 0
|
15
|
+
max_score = 0
|
16
|
+
SCENARII.each do |scenario|
|
17
|
+
STDERR.print "Running scenario #{scenario.name}... "
|
18
|
+
$stderr.flush
|
19
|
+
|
20
|
+
begin
|
21
|
+
scenario.call(@host)
|
22
|
+
STDERR.puts "passed"
|
23
|
+
score += scenario.score
|
24
|
+
rescue Exception => error
|
25
|
+
STDERR.puts "failed"
|
26
|
+
STDERR.puts scenario.description
|
27
|
+
STDERR.puts ">>> #{error}"
|
28
|
+
compliance = false if scenario.required
|
29
|
+
end
|
30
|
+
max_score += scenario.score
|
31
|
+
end
|
32
|
+
|
33
|
+
STDERR.puts "Compliance: #{compliance}"
|
34
|
+
score_percent = (100.0 * score / max_score).round(2)
|
35
|
+
STDERR.puts "Score: #{score} / #{max_score} (#{score_percent}%)"
|
36
|
+
|
37
|
+
score
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/jsonapi/grader.rb
CHANGED
@@ -1,63 +1,2 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
module JSONAPI
|
4
|
-
class Grader
|
5
|
-
def initialize(implementation_dir)
|
6
|
-
@implementation_dir = implementation_dir
|
7
|
-
scenarii_file = File.dirname(__FILE__) + '/../../scenarii.json'
|
8
|
-
@scenarii = JSON.parse(File.read(scenarii_file))
|
9
|
-
end
|
10
|
-
|
11
|
-
def grade
|
12
|
-
compliance = true
|
13
|
-
score = 0
|
14
|
-
max_score = 0
|
15
|
-
@scenarii.each do |scenario|
|
16
|
-
current_score = score_scenario(scenario)
|
17
|
-
compliance = false if scenario['required'] && current_score == 0
|
18
|
-
max_score += scenario['score']
|
19
|
-
score += current_score
|
20
|
-
end
|
21
|
-
|
22
|
-
STDERR.puts "Compliance: #{compliance}"
|
23
|
-
score_percent = (100.0 * score / max_score).round(2)
|
24
|
-
STDERR.puts "Score: #{score} / #{max_score} (#{score_percent}%)"
|
25
|
-
|
26
|
-
score
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def score_scenario(scenario)
|
32
|
-
document_file = File.dirname(__FILE__) + "/../../#{scenario['file']}"
|
33
|
-
reference_document = normalize(JSON.parse(File.read(document_file)))
|
34
|
-
implementation = "#{@implementation_dir}/#{scenario['name']}"
|
35
|
-
STDERR.print "Running scenario #{scenario['name']}... "
|
36
|
-
$stderr.flush
|
37
|
-
unless File.exists?(implementation)
|
38
|
-
STDERR.puts "not implemented"
|
39
|
-
return 0
|
40
|
-
end
|
41
|
-
|
42
|
-
actual_document = normalize(JSON.parse(`#{implementation}`))
|
43
|
-
if reference_document == actual_document
|
44
|
-
STDERR.puts "passed"
|
45
|
-
return scenario['score']
|
46
|
-
else
|
47
|
-
STDERR.puts "failed"
|
48
|
-
STDERR.puts "Expected: #{reference_document}"
|
49
|
-
STDERR.puts "Got: #{actual_document}"
|
50
|
-
$stderr.flush
|
51
|
-
return 0
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def normalize(document)
|
56
|
-
return document unless document.key?('included')
|
57
|
-
|
58
|
-
document['included'].sort do |a, b|
|
59
|
-
[a['type'], a['id']] <=> [b['type'], b['id']]
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
1
|
+
require 'jsonapi/grader/serialization_grader'
|
2
|
+
require 'jsonapi/grader/server_grader'
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-grader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Hosseini
|
@@ -17,6 +17,12 @@ executables:
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- "./lib/jsonapi/grader.rb"
|
21
|
+
- "./lib/jsonapi/grader/serialization_grader.rb"
|
22
|
+
- "./lib/jsonapi/grader/server/scenarii.rb"
|
23
|
+
- "./lib/jsonapi/grader/server/scenarii/empty_collection.rb"
|
24
|
+
- "./lib/jsonapi/grader/server/scenario.rb"
|
25
|
+
- "./lib/jsonapi/grader/server_grader.rb"
|
20
26
|
- "./scenarii/empty_collection.json"
|
21
27
|
- "./scenarii/null_data.json"
|
22
28
|
- "./scenarii/simple_resource.json"
|
@@ -24,8 +30,7 @@ files:
|
|
24
30
|
- "./scenarii/simple_resource_jsonapi_object.json"
|
25
31
|
- "./scenarii/simple_resource_meta.json"
|
26
32
|
- bin/jsonapi-grader
|
27
|
-
-
|
28
|
-
- scenarii.json
|
33
|
+
- scenarii_serialization.json
|
29
34
|
homepage: https://github.com/beauby/jsonapi-grader
|
30
35
|
licenses:
|
31
36
|
- MIT
|