json-rigs 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b948986d7f1dda5f386391f83ce52c3d342a8194
4
+ data.tar.gz: b51936d4af268f96f9e406765ceee41e3ad6853b
5
+ SHA512:
6
+ metadata.gz: 5cc7e5c4611ea393849553308c28f2d4aea01a7b9ffa2bed214d984325db825f6c2cf249a99ea2c280aba04510a4ead2881a6e4b94b05215b32522728510297f
7
+ data.tar.gz: aecb7b4a6f6f41317b14ad83bcafc86e0abc12d75822ee29e534012a66a29af5c24def2d6662943dfc9b2e9b56288ef0caff984ef00004500e9c13a134cc00b5
data/bin/jrigs ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'daemons'
4
+ require 'json-rigs/server'
5
+
6
+ OPTIONS = {
7
+ app_name: 'json-rigs',
8
+ dir: '/tmp/',
9
+ dir_mode: :normal
10
+ }
11
+ cwd = File.join(Dir.pwd, 'fixtures')
12
+
13
+ Daemons.run_proc('json-rigs', OPTIONS) do
14
+ JsonRigs::FixtureServerRunner.start(cwd)
15
+ end
16
+
data/lib/json-rigs.rb ADDED
File without changes
@@ -0,0 +1,72 @@
1
+ require 'net/http'
2
+ require 'spec/fixture_server/constants'
3
+
4
+ module JsonRigs
5
+ module FixtureClient
6
+ class << self
7
+ FIXTURE_URI = '/fixtures'
8
+
9
+ def clear_active_fixtures
10
+ data = {
11
+ :fixture_action => 'clear'
12
+ }
13
+ post_fixture(data)
14
+ end
15
+
16
+ def set_fixture url, method, action, fixture
17
+ data = {
18
+ :url => url,
19
+ :method => method,
20
+ :action => action,
21
+ :fixture => fixture,
22
+ :fixture_action => 'set'
23
+ }
24
+ response = post_fixture(data)
25
+
26
+ if response.body.length > 0
27
+ puts "Fixture server error: #{response.body}"
28
+ end
29
+ end
30
+
31
+ def fixtures
32
+ data = {
33
+ :fixture_action => 'get'
34
+ }
35
+ response = get_fixture(data)
36
+
37
+ if response.body.length > 0
38
+ puts "Fixture server error: #{response.body}"
39
+ end
40
+
41
+ puts response.body
42
+
43
+ JSON.parse(response.body)
44
+ end
45
+
46
+ private
47
+
48
+ def get_conn
49
+ begin
50
+ Net::HTTP.new('localhost', File.read(JsonRigs::PORT_FILE).to_i)
51
+ rescue Errno::ENOENT
52
+ fail "Failed to find fixture server port file #{JsonRigs::PORT_FILE}. Maybe your fixture server is down."
53
+ end
54
+ end
55
+
56
+ def get_fixture(data)
57
+ path = FIXTURE_URI.dup
58
+ path << '?' << data.map { |k, v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
59
+ request = Net::HTTP::Get.new(path)
60
+
61
+ get_conn.request(request)
62
+ end
63
+
64
+ def post_fixture(data)
65
+ request = Net::HTTP::Post.new(FIXTURE_URI)
66
+ request.set_form_data(data)
67
+
68
+ get_conn.request(request)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,22 @@
1
+ module JsonRigs
2
+ module FixtureTemplates
3
+ def basic_post_fixture
4
+ fixture :success do
5
+ respond_with %q(
6
+ {
7
+ "success": true
8
+ }
9
+ )
10
+ end
11
+
12
+ fixture :failure do
13
+ respond_with %q(
14
+ {
15
+ "error_code": 0,
16
+ "success": false
17
+ }
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,51 @@
1
+ require 'json-rigs/fixture-templates'
2
+
3
+ module JsonRigs
4
+ class Fixture
5
+
6
+ attr_accessor :pause_time
7
+ attr_reader :response
8
+
9
+ def respond_with response
10
+ JSON.parse(response)
11
+ @response = response
12
+ end
13
+
14
+ alias_method :delay, :pause_time=
15
+ end
16
+
17
+ class FixturedAction
18
+ include JsonRigs::FixtureTemplates
19
+
20
+ attr_reader :fixtures, :url
21
+ attr_accessor :active_fixture_name
22
+
23
+ def initialize(url, method)
24
+ @active_fixture_name = nil
25
+ @url = url
26
+ @method = method
27
+ @fixtures = {}
28
+ end
29
+
30
+ def fixture fixture_name, &block
31
+ fixture = Fixture.new
32
+ @fixtures[fixture_name.to_s] = fixture
33
+ fixture.instance_eval &block
34
+ @active_fixture_name = ''
35
+ end
36
+
37
+ def active_fixture; @fixtures[@active_fixture_name] end
38
+ def active_fixture?; !@active_fixture_name.empty? end
39
+
40
+ def to_hash
41
+ fixture_hash = @fixtures.keys.each_with_object({}) do |fixture_name, hash|
42
+ hash[fixture_name] = @active_fixture_name == fixture_name
43
+ end
44
+
45
+ {
46
+ method: @method,
47
+ fixtures: fixture_hash
48
+ }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,72 @@
1
+ require 'json'
2
+
3
+ require 'json-rigs/fixture'
4
+
5
+ module JsonRigs
6
+ module Fixtures
7
+ FixturedActionKey = Struct.new(:url, :method)
8
+ ACTIVE_FIXTURE_FILE = 'tmp/active_fixtures.json'
9
+
10
+ def self.fixture_action(url, method, &block)
11
+ method = method.to_s
12
+ @actions ||= {}
13
+
14
+ key = _key(url, method)
15
+ fixture_action = @actions[key] || FixturedAction.new(url, method)
16
+ @actions[key] = fixture_action
17
+ fixture_action.instance_eval &block
18
+ end
19
+
20
+ def self.find_action(url, method)
21
+ method = method.to_s
22
+ @actions ||= {}
23
+ @actions[_key(url, method)]
24
+ end
25
+
26
+ def self.clear_active_fixtures
27
+ @actions.values.each do |action|
28
+ action.active_fixture_name = ''
29
+ end
30
+ end
31
+
32
+ def self.save_active_fixtures
33
+ active_fixtures = @actions.map { |key, action|
34
+ [ key.url, key.method, action.active_fixture_name ]
35
+ }
36
+ FileUtils.mkdir_p(File.dirname(ACTIVE_FIXTURE_FILE))
37
+ File.open(ACTIVE_FIXTURE_FILE, 'w') { |io| io.write(active_fixtures.to_json) }
38
+ end
39
+
40
+ def self.load_active_fixtures
41
+ begin
42
+ active_fixtures = JSON.parse(File.read(ACTIVE_FIXTURE_FILE))
43
+ rescue Errno::ENOENT, Errno::ESRCH
44
+ return
45
+ end
46
+
47
+ active_fixtures.each do |fixture|
48
+ url, method, active_fixture = fixture
49
+ action = find_action(url, method)
50
+ if action
51
+ action.active_fixture_name = active_fixture
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.clear_all!
57
+ @actions = {}
58
+ end
59
+
60
+ def self.fixtures
61
+ json = @actions.values.group_by(&:url)
62
+ json.each do |url, actions|
63
+ json[url] = actions.map(&:to_hash)
64
+ end
65
+ json
66
+ end
67
+
68
+ def self._key(url, method)
69
+ FixturedActionKey.new(url, method)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,205 @@
1
+ require 'listen'
2
+ require 'sinatra/base'
3
+ require 'socket'
4
+ require 'haml'
5
+ require 'pathname'
6
+
7
+ require 'json-rigs/fixture'
8
+ require 'json-rigs/fixtures'
9
+
10
+ module JsonRigs
11
+ class FixtureServer < Sinatra::Base
12
+ configure :production, :development do
13
+ enable :logging
14
+ end
15
+
16
+ def self.load_fixtures
17
+ puts "Loading fixtures from #{settings.fixture_path}..."
18
+ Dir[File.join(settings.fixture_path, '**/*.json')].each do |f|
19
+ load_fixture(f)
20
+ end
21
+ end
22
+
23
+ def self.load_fixture(f)
24
+ puts "Loading #{f}..."
25
+ relevant_path = f.sub(/\A#{settings.fixture_path}/, '')
26
+ pieces = Pathname(relevant_path).each_filename.to_a
27
+
28
+ unless pieces.length >= 2
29
+ error_message = %Q(
30
+ Fixtures are not structured correctly.
31
+ Please place .json files inside #{settings.fixture_path} as /[url]/[HTTP method]/[response type].json, e.g. /users/GET/success.json
32
+ )
33
+ logger.error error_message
34
+ halt error_message
35
+ end
36
+
37
+ url = pieces[0...-2].join('/')
38
+ method = pieces[-2]
39
+ response_name = File.basename(pieces[-1], ".*")
40
+ contents = File.read(f)
41
+ JsonRigs::Fixtures::fixture_action url, method do
42
+ fixture response_name.to_sym do
43
+ respond_with(contents)
44
+ end
45
+ end
46
+ end
47
+
48
+ helpers do
49
+ def serve_request(servlet_url, method)
50
+ action = JsonRigs::Fixtures::find_action(servlet_url, method)
51
+ halt "unknown action '#{servlet_url} #{method}'" unless action
52
+
53
+ logger.info "Responding to #{servlet_url} #{method}"
54
+
55
+ if action.active_fixture?
56
+ logger.info "Using fixture #{action.active_fixture_name.inspect}"
57
+
58
+ fixture = action.active_fixture
59
+ halt 'action has no associated fixture' unless fixture
60
+
61
+ if fixture.pause_time
62
+ logger.info "Sleeping #{fixture.pause_time} seconds.."
63
+ sleep(fixture.pause_time)
64
+ end
65
+
66
+ content_type 'application/json'
67
+ return fixture.response
68
+ else
69
+ logger.info 'No fixture specified, using stub response.'
70
+ return '{ "success": false, "error_code": 0 }'
71
+ end
72
+ end
73
+
74
+ def clear_fixtures
75
+ JsonRigs::Fixtures::clear_active_fixtures
76
+ logger.info 'Fixture clear successful.'
77
+ return 200
78
+ end
79
+
80
+ def get_fixtures
81
+ JsonRigs::Fixtures::fixtures.to_json
82
+ end
83
+
84
+ def set_active_fixture
85
+ %w{url method fixture}.each do |arg|
86
+ value = params[arg]
87
+ unless value
88
+ logger.error "missing #{arg} param"
89
+ halt "missing #{arg} param"
90
+ end
91
+ end
92
+
93
+ action = JsonRigs::Fixtures::find_action(params[:url], params[:method])
94
+
95
+ action_str = "#{params[:url]} #{params[:method]}"
96
+ unless action
97
+ logger.error "unknown action #{action_str}"
98
+ halt "unknown action #{action_str}"
99
+ end
100
+ action.active_fixture_name = params[:fixture]
101
+
102
+ JsonRigs::Fixtures::save_active_fixtures
103
+
104
+ logger.info "Setting fixture for #{action_str} to #{params[:fixture]}"
105
+
106
+ return 200
107
+ end
108
+ end
109
+
110
+ get '/test-panel' do
111
+ @fixtures = JsonRigs::Fixtures::fixtures
112
+ haml :test_panel, locals: {fixtures: @fixtures}
113
+ end
114
+
115
+ get '/test-fixtures' do
116
+ fixture_action = params[:fixture_action]
117
+ case fixture_action
118
+ when 'get', nil
119
+ get_fixtures
120
+ else
121
+ halt "unknown fixture action #{fixture_action.inspect}"
122
+ end
123
+ end
124
+
125
+ post '/test-fixtures' do
126
+ fixture_action = params[:fixture_action]
127
+ case fixture_action
128
+ when 'clear'
129
+ clear_fixtures
130
+ when 'set'
131
+ set_active_fixture
132
+ else
133
+ halt "unknown fixture action #{fixture_action.inspect}"
134
+ end
135
+ end
136
+
137
+ get '/*' do |servlet_url|
138
+ serve_request(servlet_url, :GET)
139
+ end
140
+
141
+ post '/*' do |servlet_url|
142
+ serve_request(servlet_url, :POST)
143
+ end
144
+
145
+ put '/*' do |servlet_url|
146
+ serve_request(servlet_url, :PUT)
147
+ end
148
+
149
+ delete '/*' do |servlet_url|
150
+ serve_request(servlet_url, :DELETE)
151
+ end
152
+ end
153
+
154
+ module FixtureServerRunner
155
+ class << self
156
+ STARTING_PORT = 3000
157
+
158
+ def start(fixture_path)
159
+ puts 'Starting fixture server...'
160
+
161
+ port = choose_port()
162
+
163
+ FixtureServer.set(:port, port)
164
+ FixtureServer.set(:fixture_path, fixture_path)
165
+ FixtureServer::load_fixtures
166
+ JsonRigs::Fixtures::load_active_fixtures
167
+
168
+ # Start listener on fixture path to reload fixtures if necessary.
169
+ listener = Listen.to(fixture_path, only: /\.json$/) { |modified, added, removed|
170
+ on_fixture_change(modified, added, removed)
171
+ }
172
+ listener.start
173
+
174
+ FixtureServer.run!
175
+ end
176
+
177
+ private
178
+
179
+ def on_fixture_change(modified, added, removed)
180
+ puts 'Reloading fixtures...'
181
+
182
+ JsonRigs::Fixtures::clear_all!
183
+ FixtureServer::load_fixtures
184
+ JsonRigs::Fixtures::load_active_fixtures
185
+
186
+ puts 'Fixtures reloaded.'
187
+ end
188
+
189
+ def choose_port
190
+ port = STARTING_PORT
191
+
192
+ begin
193
+ server = TCPServer.new(port)
194
+ rescue Errno::EADDRINUSE
195
+ port += 1
196
+ retry
197
+ ensure
198
+ server.close if server
199
+ end
200
+
201
+ port
202
+ end
203
+ end
204
+ end
205
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: json-rigs
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Clinkle
8
+ - David Kettler
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: daemons
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.2'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.2'
28
+ - !ruby/object:Gem::Dependency
29
+ name: json
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.8'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.8'
42
+ - !ruby/object:Gem::Dependency
43
+ name: listen
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '2.9'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '2.9'
56
+ - !ruby/object:Gem::Dependency
57
+ name: sinatra
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.4'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.4'
70
+ - !ruby/object:Gem::Dependency
71
+ name: haml
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '4.0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '4.0'
84
+ description: An easy way to serve fixtures in response to web requests.Use a handy
85
+ panel to choose which fixtures to serve. Great for QA and fast prototyping.
86
+ email:
87
+ - alex@clinkle.com
88
+ - 21echoes@gmail.com
89
+ executables:
90
+ - jrigs
91
+ extensions: []
92
+ extra_rdoc_files: []
93
+ files:
94
+ - bin/jrigs
95
+ - lib/json-rigs.rb
96
+ - lib/json-rigs/client.rb
97
+ - lib/json-rigs/fixture-templates.rb
98
+ - lib/json-rigs/fixture.rb
99
+ - lib/json-rigs/fixtures.rb
100
+ - lib/json-rigs/server.rb
101
+ homepage: https://github.com/21echoes/json-rigs
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.2.2
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: "~~ set sail with json-rigs ~~"
125
+ test_files: []