sinatra-schema 0.0.5 → 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 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