sinatra-schema 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: efba21adbb69d56337bf911bf277b98f99da8781
4
- data.tar.gz: f90d52c93a3dc9207f01a075502c383f02f502b4
3
+ metadata.gz: 7ed53578697a31d2928747c5e315a6bf74e3a5b1
4
+ data.tar.gz: 1c8fabb80b8ee50d14186838d1a29f53d4bc039b
5
5
  SHA512:
6
- metadata.gz: 7eda67c2a0f5d08c9ad7a1b4272c5260c43e96f55cb192e40a1b88f6d0fd3dd9f7c7d9f3fe68cfb1af4daf091e1766bcd75e65cf3cf769ecb83e82a50f3927a2
7
- data.tar.gz: cd59d186c53e8c262309a6eae7ec232f4d878b65bc76081d4defe6702c22e15785d4ed0e4299879e6c668f40ffd830da57406f75d412b1e7011975a662d264fa
6
+ metadata.gz: e3a1e7c20a2737d577391748a479bddb1761183777c4797cf6dfc6009076c4caec7dc408aa174eaab7f382d34abc839f49a01728d99e2753e88e5a42c2c668ec
7
+ data.tar.gz: 7e12db3a44fe1ee3574f5feb3d9fa47c676820d24587a9f85e5d391b7678574288460bd2cef166d6c26055701f147d43fceef2acc5a4ae491f12594af1cf11dd
data/README.md CHANGED
@@ -17,7 +17,7 @@ class MyApi < Sinatra::Base
17
17
  resource("/account") do |res|
18
18
  res.property.text :email
19
19
 
20
- res.link(:get) do |link|
20
+ res.get do |link|
21
21
  link.action do
22
22
  # note per definition above we need to serialize "email"
23
23
  MultiJson.encode(email: current_user.email)
@@ -35,7 +35,7 @@ Links can have properties too:
35
35
  resource("/account") do |res|
36
36
  res.property.text :email
37
37
 
38
- res.link(:post) do |link|
38
+ res.post do |link|
39
39
  link.property.ref :email # reuse the property defined above
40
40
  link.property.text :role, optional: true
41
41
  link.property.bool :admin
@@ -2,12 +2,15 @@ require "active_support/inflector"
2
2
  require "sinatra/base"
3
3
  require "singleton"
4
4
  require "multi_json"
5
+ require "time"
5
6
 
6
7
  require "sinatra/schema/definition"
7
8
  require "sinatra/schema/error"
9
+ require "sinatra/schema/json_schema"
8
10
  require "sinatra/schema/link"
9
11
  require "sinatra/schema/param_parsing"
10
12
  require "sinatra/schema/param_validation"
13
+ require "sinatra/schema/reference"
11
14
  require "sinatra/schema/resource"
12
15
  require "sinatra/schema/root"
13
16
  require "sinatra/schema/utils"
@@ -32,7 +35,7 @@ module Sinatra
32
35
  app.get "/schema" do
33
36
  content_type("application/schema+json")
34
37
  response.headers["Cache-Control"] = "public, max-age=3600"
35
- MultiJson.encode(app.schema_root.to_schema, pretty: true)
38
+ MultiJson.encode(JsonSchema.dump(app.schema_root), pretty: true)
36
39
  end
37
40
  end
38
41
 
@@ -18,6 +18,8 @@ module Sinatra
18
18
  case type
19
19
  when "boolean"
20
20
  %w( t true 1 ).include?(value.to_s)
21
+ when "datetime"
22
+ Time.parse(value.to_s)
21
23
  when "email", "string", "uuid"
22
24
  value.to_s
23
25
  end
@@ -29,6 +31,8 @@ module Sinatra
29
31
  case type
30
32
  when "boolean"
31
33
  [true, false].include?(value)
34
+ when "datetime"
35
+ value.to_s =~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-2][0-9]:[0-5][0-9]:[0-5][0-9](\.[0-9]+)?(Z|[\-+][0-9]{2}:[0-5][0-9])$/
32
36
  when "email"
33
37
  value.to_s =~ /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
34
38
  when "string"
@@ -37,33 +41,6 @@ module Sinatra
37
41
  value.to_s =~ /\A[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}\Z/
38
42
  end
39
43
  end
40
-
41
- def to_schema
42
- schema_type, schema_format = json_schema_type_and_format
43
- attrs = { type: schema_type }
44
- if schema_format
45
- attrs[:format] = schema_format
46
- end
47
- if description
48
- attrs[:description] = description
49
- end
50
- attrs
51
- end
52
-
53
- protected
54
-
55
- def json_schema_type_and_format
56
- case type
57
- when "boolean"
58
- "boolean"
59
- when "email"
60
- ["string", "email"]
61
- when "string"
62
- "string"
63
- when "uuid"
64
- ["string", "uuid"]
65
- end
66
- end
67
44
  end
68
45
  end
69
46
  end
@@ -25,6 +25,11 @@ module Sinatra
25
25
  add Definition.new(options)
26
26
  end
27
27
 
28
+ def datetime(id, options={})
29
+ options.merge!(id: id, type: "datetime")
30
+ add Definition.new(options)
31
+ end
32
+
28
33
  def email(id, options={})
29
34
  options.merge!(id: id, type: "email")
30
35
  add Definition.new(options)
@@ -40,25 +45,16 @@ module Sinatra
40
45
  end
41
46
 
42
47
  def ref(id, ref_to=nil)
43
- ref_to ||= id
44
- unless definition = resource.defs[ref_to] || Sinatra::Schema::Root.instance.find_definition(ref_to)
45
- raise BadReference.new(id)
46
- end
47
- add definition, true, id
48
+ add Reference.new(resource, id, ref_to), true
48
49
  end
49
50
 
50
51
  # TODO support other types
51
52
 
52
53
  protected
53
54
 
54
- def add(definition, reference=false, id=nil)
55
- id ||= definition.id
56
- targets.each_with_index do |hash, i|
57
- # here's the trick, and here's why the first target is always the
58
- # resource def: skip it when adding a reference (eg: it's already)
59
- # in the resource def, just add the property!
60
- next if reference && i == 0
61
- hash[id] = definition
55
+ def add(definition, reference=false)
56
+ targets.each do |target|
57
+ target[definition.id] ||= definition
62
58
  end
63
59
  end
64
60
  end
@@ -17,12 +17,35 @@ module Sinatra
17
17
  DSL::Definitions.new(resource, [resource.defs, resource.properties])
18
18
  end
19
19
 
20
- def link(method, href="/", &blk)
20
+ def delete(href="/", &blk)
21
+ build_link(:delete, href, &blk)
22
+ end
23
+
24
+ def get(href="/", &blk)
25
+ build_link(:get, href, &blk)
26
+ end
27
+
28
+ def patch(href="/", &blk)
29
+ build_link(:patch, href, &blk)
30
+ end
31
+
32
+ def post(href="/", &blk)
33
+ build_link(:post, href, &blk)
34
+ end
35
+
36
+ def put(href="/", &blk)
37
+ build_link(:put, href, &blk)
38
+ end
39
+
40
+ protected
41
+
42
+ def build_link(method, href="/", &blk)
21
43
  dsl = DSL::Links.new(resource: resource, method: method, href: href)
22
- blk.call(dsl)
23
- link = dsl.link
24
- link.register(app)
25
- resource.links << link
44
+ blk.call(dsl) if blk
45
+ dsl.link.tap do |link|
46
+ link.register(app)
47
+ resource.links << link
48
+ end
26
49
  end
27
50
  end
28
51
  end
@@ -0,0 +1,73 @@
1
+ module Sinatra
2
+ module Schema
3
+ class JsonSchema
4
+ attr_accessor :root
5
+
6
+ def self.dump(root)
7
+ new(root).dump_root
8
+ end
9
+
10
+ def initialize(root)
11
+ @root = root
12
+ end
13
+
14
+ def dump_root
15
+ {
16
+ "$schema" => "http://json-schema.org/draft-04/hyper-schema",
17
+ "definitions" => root.resources.inject({}) { |result, (id, resource)|
18
+ result.merge(id => dump_resource(resource))
19
+ }
20
+ }
21
+ end
22
+
23
+ def dump_resource(resource)
24
+ {
25
+ title: resource.title,
26
+ description: resource.description,
27
+ type: "object",
28
+ definitions: resource.defs.inject({}) { |h, (id, definition)|
29
+ h.merge(id => dump_definition(definition))
30
+ },
31
+ links: resource.links.map { |link| dump_link(link) }
32
+ }
33
+ end
34
+
35
+ def dump_definition(definition)
36
+ schema_type, schema_format = json_schema_type_and_format(definition.type)
37
+ attrs = { type: schema_type }
38
+ if schema_format
39
+ attrs[:format] = schema_format
40
+ end
41
+ if definition.description
42
+ attrs[:description] = definition.description
43
+ end
44
+ attrs
45
+ end
46
+
47
+ def dump_link(link)
48
+ {
49
+ description: link.description,
50
+ href: link.href,
51
+ method: link.method.to_s.upcase,
52
+ }
53
+ end
54
+
55
+ protected
56
+
57
+ def json_schema_type_and_format(type)
58
+ case type
59
+ when "boolean"
60
+ "boolean"
61
+ when "datetime"
62
+ ["string", "date-time"]
63
+ when "email"
64
+ ["string", "email"]
65
+ when "string"
66
+ "string"
67
+ when "uuid"
68
+ ["string", "uuid"]
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -3,7 +3,7 @@ module Sinatra
3
3
  class Link
4
4
  attr_accessor :action_block, :resource, :title, :description, :href, :method, :properties, :rel
5
5
 
6
- def initialize(options)
6
+ def initialize(options={})
7
7
  @resource = options[:resource]
8
8
  @method = options[:method]
9
9
  @href = options[:href]
@@ -11,7 +11,7 @@ module Sinatra
11
11
  end
12
12
 
13
13
  def register(app)
14
- app.send(method.downcase, href, &handler)
14
+ app.send(method, href, &handler)
15
15
  end
16
16
 
17
17
  def handler
@@ -26,14 +26,6 @@ module Sinatra
26
26
  end
27
27
  end
28
28
  end
29
-
30
- def to_schema
31
- {
32
- description: description,
33
- href: href,
34
- method: method.to_s.upcase,
35
- }
36
- end
37
29
  end
38
30
  end
39
31
  end
@@ -0,0 +1,36 @@
1
+ module Sinatra
2
+ module Schema
3
+ class Reference
4
+ attr_accessor :id, :ref_spec, :referenced_def, :resource
5
+
6
+ # helper to lazily delegate method to the referenced definition
7
+ def self.delegate(attribute)
8
+ define_method(attribute) do |*args|
9
+ resolve!
10
+ referenced_def.send(attribute, *args)
11
+ end
12
+ end
13
+
14
+ def initialize(resource, id, ref_spec=nil)
15
+ @id = id
16
+ @ref_spec = ref_spec || id
17
+ @resource = resource
18
+ end
19
+
20
+ def resolve!
21
+ return if referenced_def
22
+ unless @referenced_def = resource.defs[ref_spec] || Sinatra::Schema::Root.instance.find_definition(ref_spec)
23
+ raise BadReference.new(ref_spec)
24
+ end
25
+ return @referenced_def
26
+ end
27
+
28
+ delegate :cast
29
+ delegate :description
30
+ delegate :example
31
+ delegate :optional
32
+ delegate :type
33
+ delegate :valid?
34
+ end
35
+ end
36
+ end
@@ -31,19 +31,6 @@ module Sinatra
31
31
  Utils.validate_keys!(properties, res)
32
32
  end
33
33
  end
34
-
35
- def to_schema
36
- {
37
- title: title,
38
- description: description,
39
- type: "object",
40
- definitions: defs.inject({}) { |h, (id, definition)|
41
- h[id] = definition.to_schema
42
- h
43
- },
44
- links: links.map(&:to_schema)
45
- }
46
- end
47
34
  end
48
35
  end
49
36
  end
@@ -18,16 +18,6 @@ module Sinatra
18
18
  return unless resource = resources[resource_id.to_sym]
19
19
  resource.defs[def_id.to_sym]
20
20
  end
21
-
22
- def to_schema
23
- {
24
- "$schema" => "http://json-schema.org/draft-04/hyper-schema",
25
- "definitions" => resources.inject({}) { |result, (id, resource)|
26
- result[id] = resource.to_schema
27
- result
28
- }
29
- }
30
- end
31
21
  end
32
22
  end
33
23
  end
@@ -1,5 +1,5 @@
1
1
  module Sinatra
2
2
  module Schema
3
- VERSION = "0.0.5"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -13,6 +13,19 @@ describe Sinatra::Schema::Definition do
13
13
  assert_equal false, definition.cast("false")
14
14
  end
15
15
 
16
+ it "casts datetime" do
17
+ definition.type = "datetime"
18
+ t = definition.cast("2014-05-01T12:13:14.15Z")
19
+ assert_equal 2014, t.year
20
+ assert_equal 5, t.month
21
+ assert_equal 1, t.day
22
+ assert_equal 12, t.hour
23
+ assert_equal 13, t.min
24
+ assert_equal 14, t.sec
25
+ assert_equal 150000, t.usec
26
+ assert_equal "UTC", t.zone
27
+ end
28
+
16
29
  it "casts text" do
17
30
  definition.type = "string"
18
31
  assert_equal "123", definition.cast(123)
@@ -20,45 +33,35 @@ describe Sinatra::Schema::Definition do
20
33
  end
21
34
 
22
35
  describe "#valid?" do
23
- it "detects booleans" do
36
+ it "validates booleans" do
24
37
  definition.type = "boolean"
25
38
  assert definition.valid?(true)
26
39
  assert definition.valid?(false)
27
40
  refute definition.valid?("true")
28
41
  end
29
42
 
30
- it "detects emails" do
43
+ it "validates emails" do
31
44
  definition.type = "email"
32
45
  assert definition.valid?("foo@bar.com")
33
46
  refute definition.valid?("foobar.com")
34
47
  end
35
48
 
36
- it "detects text" do
49
+ it "validates text" do
37
50
  definition.type = "string"
38
51
  assert definition.valid?("foo")
39
52
  refute definition.valid?(123)
40
53
  end
41
54
 
42
- it "detects uuids" do
55
+ it "validates uuids" do
43
56
  definition.type = "uuid"
44
57
  assert definition.valid?(SecureRandom.uuid)
45
58
  refute definition.valid?("wrong")
46
59
  end
47
- end
48
60
 
49
- describe "#to_schema" do
50
- it "dumps emails" do
51
- definition.type = "email"
52
- schema = definition.to_schema
53
- assert_equal "string", schema[:type]
54
- assert_equal "email", schema[:format]
55
- end
56
-
57
- it "dumps uuids" do
58
- definition.type = "uuid"
59
- schema = definition.to_schema
60
- assert_equal "string", schema[:type]
61
- assert_equal "uuid", schema[:format]
61
+ it "validates date+time fields" do
62
+ definition.type = "datetime"
63
+ assert definition.valid?("1985-04-12T23:20:50.52Z")
64
+ refute definition.valid?("12/4/1985 23:20:50")
62
65
  end
63
66
  end
64
67
  end
@@ -17,6 +17,12 @@ describe Sinatra::Schema::DSL::Definitions do
17
17
  assert_equal "boolean", resource.defs[:foobar].type
18
18
  end
19
19
 
20
+ it "adds a datetime definition to the resource" do
21
+ dsl.datetime(:foobar)
22
+ assert_equal 1, resource.defs.size
23
+ assert_equal "datetime", resource.defs[:foobar].type
24
+ end
25
+
20
26
  it "adds nested definitions" do
21
27
  dsl[:user].text :email
22
28
  dsl[:user].bool :admin
@@ -25,43 +31,14 @@ describe Sinatra::Schema::DSL::Definitions do
25
31
  assert_equal "boolean", resource.defs[:user][:admin].type
26
32
  end
27
33
 
34
+ it "adds references" do
35
+ dsl.ref(:another_property)
36
+ assert_equal 1, resource.defs.size
37
+ assert_instance_of Sinatra::Schema::Reference, resource.defs[:another_property]
38
+ end
39
+
28
40
  it "sets other options" do
29
41
  dsl.text(:foobar, optional: true)
30
42
  assert_equal true, resource.defs[:foobar].optional
31
43
  end
32
-
33
- describe "#ref" do
34
- let(:definition) { Sinatra::Schema::Definition.new(id: :foobar) }
35
-
36
- it "adds a reference to another definition in the resource" do
37
- resource.defs[:foobar] = definition
38
- dsl.ref :foobar
39
- assert_equal 1, resource.defs.size
40
- assert_equal 1, resource.properties.size
41
- end
42
-
43
- it "adds a reference to a definition in a different resource" do
44
- other = Sinatra::Schema::Resource.new(path: "/others")
45
- root.add_resource(other)
46
- other.defs[:foobar] = definition
47
- dsl.ref "other/foobar"
48
- assert_equal 1, other.defs.size
49
- assert_equal 1, resource.properties.size
50
- end
51
-
52
- it "raises when we can't resolve the ref" do
53
- assert_raises(Sinatra::Schema::BadReference) do
54
- dsl.ref :foobar
55
- end
56
- end
57
-
58
- it "allows references to have a different id" do
59
- other = Sinatra::Schema::Resource.new(path: "/others")
60
- root.add_resource(other)
61
- other.defs[:foobar] = definition
62
- dsl.ref :my_foobar, "other/foobar"
63
- assert resource.properties.has_key?(:my_foobar)
64
- assert_equal :foobar, resource.properties[:my_foobar].id
65
- end
66
- end
67
44
  end
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Sinatra::Schema::DSL::Resources do
4
- let(:app) { Sinatra::Application.new }
4
+ let(:app) { Sinatra.new {} }
5
5
  let(:dsl) { described_class.new(app, "/foobar") }
6
6
 
7
7
  it "sets the resource description" do
@@ -28,4 +28,31 @@ describe Sinatra::Schema::DSL::Resources do
28
28
  assert_equal 2, dsl.resource.properties[:user].size
29
29
  end
30
30
  end
31
+
32
+ describe "building links" do
33
+ it "builds a DELETE" do
34
+ link = dsl.delete
35
+ assert_equal :delete, link.method
36
+ end
37
+
38
+ it "builds a GET" do
39
+ link = dsl.get
40
+ assert_equal :get, link.method
41
+ end
42
+
43
+ it "builds a PATCH" do
44
+ link = dsl.patch
45
+ assert_equal :patch, link.method
46
+ end
47
+
48
+ it "builds a POST" do
49
+ link = dsl.post
50
+ assert_equal :post, link.method
51
+ end
52
+
53
+ it "builds a PUT" do
54
+ link = dsl.put
55
+ assert_equal :put, link.method
56
+ end
57
+ end
31
58
  end
@@ -1,24 +1,55 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Sinatra::Schema do
4
- it "still works as a regular sinatra app" do
5
- get "/regular"
6
- assert_equal 200, last_response.status
7
- assert_equal "hi", last_response.body
8
- end
4
+ describe "resource access" do
5
+ it "still works as a regular sinatra app" do
6
+ get "/regular"
7
+ assert_equal 200, last_response.status
8
+ assert_equal "hi", last_response.body
9
+ end
10
+
11
+ it "support resource gets" do
12
+ get "/accounts"
13
+ assert_equal 200, last_response.status
14
+ assert_equal({ "email" => "foo@bar.com" },
15
+ MultiJson.decode(last_response.body))
16
+ end
9
17
 
10
- it "support resource gets" do
11
- get "/accounts"
12
- assert_equal 200, last_response.status
13
- assert_equal({ "email" => "foo@bar.com" },
14
- MultiJson.decode(last_response.body))
18
+ it "support resource posts" do
19
+ post "/accounts", email: "omg"
20
+ assert_equal 200, last_response.status
21
+ assert_equal({ "email" => "omg" },
22
+ MultiJson.decode(last_response.body))
23
+ end
15
24
  end
16
25
 
17
- it "support resource posts" do
18
- post "/accounts", email: "omg"
19
- assert_equal 200, last_response.status
20
- assert_equal({ "email" => "omg" },
21
- MultiJson.decode(last_response.body))
26
+ describe "GET /schema" do
27
+ before do
28
+ get "/schema"
29
+ @schema = MultiJson.decode(last_response.body)
30
+ end
31
+
32
+ it "renders a 200" do
33
+ assert_equal 200, last_response.status
34
+ end
35
+
36
+ it "sets the appropriate content-type" do
37
+ assert_equal "application/schema+json",
38
+ last_response.headers["Content-Type"]
39
+ end
40
+
41
+ it "sets $schema to hyper-schema" do
42
+ assert_equal "http://json-schema.org/draft-04/hyper-schema",
43
+ @schema["$schema"]
44
+ end
45
+
46
+ it "generates definitions" do
47
+ assert_equal Hash, @schema["definitions"].class
48
+ assert_equal Hash, @schema["definitions"]["account"].class
49
+ assert_equal "Account", @schema["definitions"]["account"]["title"]
50
+ assert_equal "An account represents an individual signed up to use the service",
51
+ @schema["definitions"]["account"]["description"]
52
+ end
22
53
  end
23
54
 
24
55
  describe "error handling" do
@@ -1,30 +1,60 @@
1
1
  require "spec_helper"
2
2
 
3
- describe "JSON Schema" do
4
- before do
5
- get "/schema"
6
- @schema = MultiJson.decode(last_response.body)
7
- end
3
+ describe Sinatra::Schema::JsonSchema do
4
+ let(:json_schema) { described_class.new(root) }
5
+ let(:root) { Sinatra::Schema::Root.instance }
6
+ let(:schema) { json_schema.dump_root }
8
7
 
9
- it "renders a 200" do
10
- assert_equal 200, last_response.status
11
- end
8
+ describe "#dump_root" do
9
+ it "sets $schema" do
10
+ assert_equal "http://json-schema.org/draft-04/hyper-schema",
11
+ schema["$schema"]
12
+ end
12
13
 
13
- it "sets the appropriate content-type" do
14
- assert_equal "application/schema+json",
15
- last_response.headers["Content-Type"]
14
+ it "adds a definition hash" do
15
+ assert_instance_of Hash, schema["definitions"]
16
+ end
16
17
  end
17
18
 
18
- it "sets $schema to hyper-schema" do
19
- assert_equal "http://json-schema.org/draft-04/hyper-schema",
20
- @schema["$schema"]
19
+ describe "#dump_definition" do
20
+ let(:definition) { Sinatra::Schema::Definition.new }
21
+
22
+ it "handles simple string format" do
23
+ definition.type = "string"
24
+ schema = json_schema.dump_definition(definition)
25
+ assert_equal "string", schema[:type]
26
+ assert_nil schema[:format]
27
+ end
28
+
29
+ it "handles the datetime format" do
30
+ definition.type = "datetime"
31
+ schema = json_schema.dump_definition(definition)
32
+ assert_equal "string", schema[:type]
33
+ assert_equal "date-time", schema[:format]
34
+ end
35
+
36
+ it "handles the email format" do
37
+ definition.type = "email"
38
+ schema = json_schema.dump_definition(definition)
39
+ assert_equal "string", schema[:type]
40
+ assert_equal "email", schema[:format]
41
+ end
42
+
43
+ it "handles the uuid format" do
44
+ definition.type = "uuid"
45
+ schema = json_schema.dump_definition(definition)
46
+ assert_equal "string", schema[:type]
47
+ assert_equal "uuid", schema[:format]
48
+ end
21
49
  end
22
50
 
23
- it "generates definitions" do
24
- assert_equal Hash, @schema["definitions"].class
25
- assert_equal Hash, @schema["definitions"]["account"].class
26
- assert_equal "Account", @schema["definitions"]["account"]["title"]
27
- assert_equal "An account represents an individual signed up to use the service",
28
- @schema["definitions"]["account"]["description"]
51
+ describe "#dump_link" do
52
+ let(:link) { Sinatra::Schema::Link.new }
53
+
54
+ it "renders the method in upcase" do
55
+ link.method = :get
56
+ schema = json_schema.dump_link(link)
57
+ assert_equal "GET", schema[:method]
58
+ end
29
59
  end
30
60
  end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ describe Sinatra::Schema::Reference do
4
+ let(:resource) { Sinatra::Schema::Root.instance.resources[:account] }
5
+ let(:ref) { described_class.new(resource, :foo, :email) }
6
+ let(:definition) { resource.defs[:email] }
7
+
8
+ describe "#resolve!" do
9
+ it "finds other properties in the same resource" do
10
+ ref.ref_spec = :foo
11
+ resource.defs[:foo] = definition
12
+ assert_equal definition, ref.resolve!
13
+ end
14
+
15
+ it "finds other properties elsewhere in the schema" do
16
+ ref.ref_spec = "account/email"
17
+ assert_equal definition, ref.resolve!
18
+ end
19
+
20
+ it "raises when it cannot resolve" do
21
+ ref.ref_spec = "does-not-exist"
22
+ assert_raises(Sinatra::Schema::BadReference) do
23
+ ref.resolve!
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "delegated attributes" do
29
+ it "#cast" do
30
+ assert_equal definition.cast("foo"), ref.cast("foo")
31
+ end
32
+
33
+ it "#description" do
34
+ assert_equal definition.description, ref.description
35
+ end
36
+
37
+ it "#example" do
38
+ assert_equal definition.example, ref.example
39
+ end
40
+
41
+ it "#optional" do
42
+ assert_equal definition.optional, ref.optional
43
+ end
44
+
45
+ it "#type" do
46
+ assert_equal definition.type, ref.type
47
+ end
48
+
49
+ it "#valid?" do
50
+ assert_equal definition.valid?("foo"), ref.valid?("foo")
51
+ end
52
+ end
53
+ end
@@ -13,7 +13,7 @@ class TestApp < Sinatra::Base
13
13
  example: "username@example.com",
14
14
  format: "email"
15
15
 
16
- res.link(:get) do |link|
16
+ res.get do |link|
17
17
  link.title "Info"
18
18
  link.rel "self"
19
19
  link.description "Info for account"
@@ -22,7 +22,7 @@ class TestApp < Sinatra::Base
22
22
  end
23
23
  end
24
24
 
25
- res.link(:post) do |link|
25
+ res.post do |link|
26
26
  link.title "Create"
27
27
  link.rel "create"
28
28
  link.description "Create a new account"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pedro Belo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-09 00:00:00.000000000 Z
11
+ date: 2014-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -139,9 +139,11 @@ files:
139
139
  - lib/sinatra/schema/dsl/links.rb
140
140
  - lib/sinatra/schema/dsl/resources.rb
141
141
  - lib/sinatra/schema/error.rb
142
+ - lib/sinatra/schema/json_schema.rb
142
143
  - lib/sinatra/schema/link.rb
143
144
  - lib/sinatra/schema/param_parsing.rb
144
145
  - lib/sinatra/schema/param_validation.rb
146
+ - lib/sinatra/schema/reference.rb
145
147
  - lib/sinatra/schema/resource.rb
146
148
  - lib/sinatra/schema/root.rb
147
149
  - lib/sinatra/schema/tasks/schema.rake
@@ -155,6 +157,7 @@ files:
155
157
  - spec/json_schema_spec.rb
156
158
  - spec/param_parsing_spec.rb
157
159
  - spec/param_validation_spec.rb
160
+ - spec/reference_spec.rb
158
161
  - spec/resource_spec.rb
159
162
  - spec/spec_helper.rb
160
163
  - spec/support/last_json.rb