hateoas 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -4,3 +4,4 @@ Gemfile.lock
4
4
  pkg/*
5
5
  *.swp
6
6
  .rbx/
7
+ docs/
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use 1.9.3@hateoas
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ script: "true" #lolz
2
+ rvm:
3
+ - rbx-18mode
4
+ - rbx-19mode
5
+ - jruby
6
+ - 1.9.3
7
+ - 1.9.2
8
+ - 1.8.7
data/README.md CHANGED
@@ -1,120 +1,31 @@
1
+ # Hateoas
1
2
 
2
- About
3
- =====
3
+ This is a Ruby gem that lets you interact with hypermedia APIs.
4
4
 
5
- HATEOAS helps you build hypermedia API clients, by providing a simple
6
- interface to navigate through pages, submitting forms, and caching local
7
- responses.
5
+ It's very much in development. You shouldn't use it for anything other than giggles. And maybe Unicorns.
8
6
 
9
- The current version is 0.0.1.
7
+ ## Installation
10
8
 
11
- **THIS CODE IS TERRIBLE AND EXPERIMENTAL!!!!!1 CONSIDER IT A BRAIN DUMP. THERE ARE NO TESTS. THERE ARE NO COMMENTS. THE CODE IS HORRIBLE. PLEASE DON'T USE THIS FOR ANYTHING YET.**
9
+ Add this line to your application's Gemfile:
12
10
 
13
- Find out more at [the hateoas homepage][homepage].
11
+ gem 'hateoas'
14
12
 
15
- Installing
16
- ==========
13
+ And then execute:
17
14
 
18
- Become a HATEr by using Rubygems:
15
+ $ bundle
19
16
 
20
- ```
21
- gem install hateoas
22
- ```
17
+ Or install it yourself as:
23
18
 
24
- Usage
25
- =====
19
+ $ gem install hateoas
26
20
 
27
- Primarily, you'll use HATEOAS to help create your own gem to interact with your
28
- API. We'll pretend that you're writing an API to your own blogging
29
- software, since blogs are the Rails "Hello world" project.
21
+ ## Usage
30
22
 
31
- Right now, HATEOAS assumes that you use XHTML5 to drive your API.
23
+ Read the code. More to come when I feel like _anything_ is stable.
32
24
 
33
- Configuration
34
- -------------
25
+ ## Contributing
35
26
 
36
- The first thing you need to do is configure HATEOAS. Congratulations on
37
- creating a hypermedia API; it means the configuration is minimal! Simply
38
- assign your root URI like this:
39
-
40
- ```
41
- Hateoas.base_uri = "http://api.hackety-hack.com"
42
- ```
43
-
44
- HATEOAS has environment variables that make it easy to hit your local copy in
45
- development mode. By default, HATEOAS assumes you're using pow, and so it will
46
- append '.dev' onto the end of your `base_uri` when it is in development
47
- mode. To use something else, set the `development_base_uri`:
48
-
49
- ```
50
- HATEOAS.develoment_base_uri = "http://localhost:9292"
51
- ```
52
-
53
- The `HATEOAS_ENV` variable will control which configuration is used. Just like
54
- Rails, there are development, test, and production modes.
55
-
56
- In my own APIs, I prefer to use URIs for my rel attributes. If you also do
57
- this, there's an optional variable that makes using URIs simpler. Without it,
58
- here's how you navigate to the 'new post' page, then the 'new comments'
59
- page:
60
-
61
- ```
62
- Hateoas::DSL.click_link("/rels/new-post")
63
- Hateoas::DSL.click_link("/rels/new-comments")
64
- ```
65
-
66
- And with it:
67
-
68
- ```
69
- Hateoas.rel_namespace = "rels"
70
-
71
- Hateoas::DSL.click_link("new-post")
72
- Hateoas::DSL.click_link("new-comments")
73
- ```
74
-
75
- Groovy?
76
-
77
- DSL
78
- ---
79
-
80
- HATEOAS provides a `DSL` module with all of the DSL methods you'll need. You
81
- can use these methods in two ways: One is to reference them by using their fully
82
- qualified names:
83
-
84
- ```
85
- Hateoas::DSL.click_link("new-post")
86
- ```
87
-
88
- Optionally, if you're building your own infrastructure around all of this, you
89
- can include the module inside your own class:
90
-
91
- ```
92
- class MyApi
93
- include Hateoas::DSL
94
-
95
- def navigate(path)
96
- click_link(path)
97
- end
98
- end
99
- ```
100
-
101
- The rest of this documentation will simply use `visit` rather than
102
- `Hateoas::DSL.visit`.
103
-
104
- Navigation
105
- ----------
106
-
107
- If you read the previous section, you've got this one figured out: simply give
108
- a rel to the `click_link` method:
109
-
110
- ```
111
- click_link("new-post")
112
- ```
113
-
114
- Getting Data Back
115
- -----------------
116
-
117
- You can access the data on the current page by using the `current_page`
118
- method.
119
-
120
- [homepage]: http://steveklabnik.github.com/cereal
27
+ 1. Fork it
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile CHANGED
@@ -1 +1,48 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/clean'
3
+
4
+ begin
5
+ # Bring in Rocco tasks
6
+ require 'rocco/tasks'
7
+ Rocco::make 'docs/'
8
+
9
+ desc 'Build rocco docs'
10
+ task :docs => :rocco
11
+ directory 'docs/'
12
+
13
+ file 'docs/index.html' => 'docs/lib/hateoas.html' do |f|
14
+ cp 'docs/lib/hateoas.html', 'docs/index.html', :preserve => true
15
+ end
16
+ task :docs => 'docs/index.html'
17
+ CLEAN.include 'docs/index.html'
18
+
19
+ # Alias for docs task
20
+ task :doc => :docs
21
+
22
+ # GITHUB PAGES ===============================================================
23
+
24
+ desc 'Update gh-pages branch'
25
+ task :pages => ['docs/.git', :docs] do
26
+ rev = `git rev-parse --short HEAD`.strip
27
+ Dir.chdir 'docs' do
28
+ sh "git add *.html"
29
+ sh "git commit -m 'rebuild pages from #{rev}'" do |ok,res|
30
+ if ok
31
+ verbose { puts "gh-pages updated" }
32
+ sh "git push -q o HEAD:gh-pages"
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ # Update the pages/ directory clone
39
+ file 'docs/.git' => ['docs/', '.git/refs/heads/gh-pages'] do |f|
40
+ sh "cd docs && git init -q && git remote add o ../.git" if !File.exist?(f.name)
41
+ sh "cd docs && git fetch -q o && git reset -q --hard o/gh-pages && touch ."
42
+ end
43
+ CLOBBER.include 'docs/.git'
44
+
45
+ rescue LoadError => e
46
+ puts "Something with rocco didn't load, you can't build the docs! Try bundle install?"
47
+ end
48
+
data/hateoas.gemspec CHANGED
@@ -19,4 +19,6 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency "mechanize"
20
20
 
21
21
  s.add_development_dependency "rspec"
22
+ s.add_development_dependency "rake"
23
+ s.add_development_dependency "pygmentize"
22
24
  end
data/lib/hateoas.rb CHANGED
@@ -1,43 +1,74 @@
1
- require 'hateoas/version'
2
- require 'open-uri'
3
- require 'mechanize'
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'forwardable'
4
+ require 'nokogiri'
4
5
 
5
6
  module Hateoas
6
- class << self
7
- attr_accessor :rel_namespace
8
- attr_writer :base_uri, :current_state
9
-
10
- def base_uri
11
- if ENV['HATEOAS_ENV'] == "development"
12
- development_base_uri || "#{@base_uri}.dev"
13
- else
14
- @base_uri
7
+ module MediaType
8
+ def self.included(including_class)
9
+ including_class.class_eval do
10
+ def self.media_type(type)
11
+ @media_type = type
12
+ end
13
+
14
+ def self.serialization(type)
15
+ end
16
+
17
+ def self.element(*elements)
18
+ end
19
+
20
+ def self.attribute(*attributes)
21
+ end
22
+
23
+ def self.relation(*relations)
24
+ end
25
+
26
+ def self.action(*actions)
27
+ @actions = actions
28
+ end
29
+
30
+ def self.actions
31
+ @actions
32
+ end
15
33
  end
16
34
  end
17
35
 
18
- def current_page
19
- current_state.body
20
- end
36
+ class Request
37
+ extend Forwardable
38
+ def_delegators :@uri, :request_uri, :hostname, :port
21
39
 
22
- def current_state
23
- @current_state ||= user_agent.get(base_uri)
24
- end
40
+ def initialize(url, media_type)
41
+ @uri = URI(url)
42
+ @media_type = media_type
43
+ end
25
44
 
26
- def user_agent
27
- @user_agent ||= Mechanize.new
45
+ def get
46
+ req = Net::HTTP::Get.new(request_uri)
47
+ req['Accept'] = @media_type
48
+
49
+ Net::HTTP.start(hostname, port) {|http| http.request(req) }.body
50
+ end
28
51
  end
29
52
 
30
- end
53
+ def media_type; @media_type; end
54
+ def data; @data; end
55
+
56
+ def actions
57
+ self.class.actions.select{|rel| relation_exists?(rel) }
58
+ end
31
59
 
32
- module DSL
33
- extend self
60
+ def initialize(uri)
61
+ @data = Nokogiri::XML(Request.new(uri, @media_type).get)
62
+ end
34
63
 
35
- def click_link(rel)
36
- if Hateoas.rel_namespace
37
- rel = "/#{Hateoas.rel_namespace}/#{rel}"
38
- end
64
+ def relation_exists?(rel)
65
+ @data.xpath("//*[@rel='#{rel}']").first
66
+ end
39
67
 
40
- Hateoas.current_state = Hateoas.user_agent.click(Hateoas.current_state.links.find{|l| l.attributes["rel"] == rel })
68
+ def transition(rel)
69
+ node = @data.xpath("//*[@rel='#{rel}']").first
70
+ return unless node
71
+ @data = Nokogiri::XML(Request.new(node[:href], @media_type).get)
41
72
  end
42
73
  end
43
74
  end
@@ -1,3 +1,3 @@
1
1
  module Hateoas
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,100 +1,98 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: hateoas
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Steve Klabnik
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-11-06 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-02-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: mechanize
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70282849544420 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
32
22
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
23
+ prerelease: false
24
+ version_requirements: *70282849544420
25
+ - !ruby/object:Gem::Dependency
35
26
  name: rspec
27
+ requirement: &70282849543940 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
36
34
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
35
+ version_requirements: *70282849543940
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &70282849543520 !ruby/object:Gem::Requirement
38
39
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 3
43
- segments:
44
- - 0
45
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
46
44
  type: :development
47
- version_requirements: *id002
45
+ prerelease: false
46
+ version_requirements: *70282849543520
47
+ - !ruby/object:Gem::Dependency
48
+ name: pygmentize
49
+ requirement: &70282849543100 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70282849543100
48
58
  description: A set of tools to help build clients for Hypermedia APIs.
49
- email:
59
+ email:
50
60
  - steve@steveklabnik.com
51
61
  executables: []
52
-
53
62
  extensions: []
54
-
55
63
  extra_rdoc_files: []
56
-
57
- files:
64
+ files:
58
65
  - .gitignore
66
+ - .rvmrc
67
+ - .travis.yml
59
68
  - Gemfile
60
69
  - README.md
61
70
  - Rakefile
62
- - SPEC.md
63
71
  - hateoas.gemspec
64
72
  - lib/hateoas.rb
65
73
  - lib/hateoas/version.rb
66
74
  homepage: http://steveklabnik.github.com/hateoas
67
75
  licenses: []
68
-
69
76
  post_install_message:
70
77
  rdoc_options: []
71
-
72
- require_paths:
78
+ require_paths:
73
79
  - lib
74
- required_ruby_version: !ruby/object:Gem::Requirement
80
+ required_ruby_version: !ruby/object:Gem::Requirement
75
81
  none: false
76
- requirements:
77
- - - ">="
78
- - !ruby/object:Gem::Version
79
- hash: 3
80
- segments:
81
- - 0
82
- version: "0"
83
- required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
87
  none: false
85
- requirements:
86
- - - ">="
87
- - !ruby/object:Gem::Version
88
- hash: 3
89
- segments:
90
- - 0
91
- version: "0"
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
92
  requirements: []
93
-
94
93
  rubyforge_project:
95
- rubygems_version: 1.8.10
94
+ rubygems_version: 1.8.16
96
95
  signing_key:
97
96
  specification_version: 3
98
97
  summary: Build easy clients for Hypermedia APIs.
99
98
  test_files: []
100
-
data/SPEC.md DELETED
@@ -1,146 +0,0 @@
1
-
2
- About
3
- =====
4
-
5
- HATEOAS helps you build hypermedia API clients, by providing a simple
6
- interface to navigate through pages, submitting forms, and caching local
7
- responses.
8
-
9
- The current version is 0.0.1.
10
-
11
- Find out more at [the hateoas homepage][homepage].
12
-
13
- Installing
14
- ==========
15
-
16
- Become a HATEr by using Rubygems:
17
-
18
- ```
19
- gem install hateoas
20
- ```
21
-
22
- Usage
23
- =====
24
-
25
- Primarily, you'll use HATEOAS to help create your own gem to interact with your
26
- API. We'll pretend that you're writing an API to your own blogging
27
- software, since blogs are the Rails "Hello world" project.
28
-
29
- Right now, HATEOAS assumes that you use XHTML5 to drive your API.
30
-
31
- Configuration
32
- -------------
33
-
34
- The first thing you need to do is configure HATEOAS. Congratulations on
35
- creating a hypermedia API; it means the configuration is minimal! Simply
36
- assign your root URI like this:
37
-
38
- ```
39
- Hateoas.base_uri = "http://api.hackety-hack.com"
40
- ```
41
-
42
- HATEOAS has environment variables that make it easy to hit your local copy in
43
- development mode. By default, HATEOAS assumes you're using pow, and so it will
44
- append '.dev' onto the end of your `base_uri` when it is in development
45
- mode. To use something else, set the `development_base_uri`:
46
-
47
- ```
48
- HATEOAS.develoment_base_uri = "http://localhost:9292"
49
- ```
50
-
51
- The `HATEOAS_ENV` variable will control which configuration is used. Just like
52
- Rails, there are development, test, and production modes.
53
-
54
- In my own APIs, I prefer to use URIs for my rel attributes. If you also do
55
- this, there's an optional variable that makes using URIs simpler. Without it,
56
- here's how you navigate to the 'new post' page, then the 'new comments'
57
- page:
58
-
59
- ```
60
- Hateoas::DSL.click_link("/rels/new-post")
61
- Hateoas::DSL.click_link("/rels/new-comments")
62
- ```
63
-
64
- And with it:
65
-
66
- ```
67
- Hateoas.rel_namespace = "rels"
68
-
69
- Hateoas::DSL.click_link("new-post")
70
- Hateoas::DSL.click_link("new-comments")
71
- ```
72
-
73
- Groovy?
74
-
75
- DSL
76
- ---
77
-
78
- HATEOAS provides a `DSL` module with all of the DSL methods you'll need. You
79
- can use these methods in two ways: One is to reference them by using their fully
80
- qualified names:
81
-
82
- ```
83
- Hateoas::DSL.click_link("new-post")
84
- ```
85
-
86
- Optionally, if you're building your own infrastructure around all of this, you
87
- can include the module inside your own class:
88
-
89
- ```
90
- class MyApi
91
- include Hateoas::DSL
92
-
93
- def navigate(path)
94
- click_link(path)
95
- end
96
- end
97
- ```
98
-
99
- The rest of this documentation will simply use `visit` rather than
100
- `Hateoas::DSL.visit`.
101
-
102
- Navigation
103
- ----------
104
-
105
- If you read the previous section, you've got this one figured out: simply give
106
- a rel to the `click_link` method:
107
-
108
- ```
109
- click_link("new-post")
110
- ```
111
-
112
- Getting Data Back
113
- -----------------
114
-
115
- You can access the data on the current page by using the `current_page`
116
- method.
117
-
118
- Forms
119
- -----
120
-
121
- There are a few methods to interact with forms:
122
-
123
- ```
124
- fill_in('First Name', :with => 'John')
125
- fill_in('Password', :with => 'Seekrit')
126
- fill_in('Description', :with => 'Really Long Text...')
127
- choose('A Radio Button')
128
- check('A Checkbox')
129
- uncheck('A Checkbox')
130
- attach_file('Image', '/path/to/image.jpg')
131
- select('Option', :from => 'Select Box')
132
- ```
133
-
134
- Caching
135
- -------
136
-
137
- HATEOAS includes a client-side cache, and respects HTTP caching directives.
138
- This helps with performance, and keeps network connections down.
139
-
140
- Authorization
141
- -------------
142
-
143
- Authentication
144
- --------------
145
-
146
- [homepage]: http://steveklabnik.github.com/cereal