api_hammer 0.0.2 → 0.0.3

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: d45ffaa15ffd8ab1a5de56bfb6dbae6db3e91889
4
- data.tar.gz: 1e8305cd7ce714d558c7968680c25ab0bde0e450
3
+ metadata.gz: b422b307a5753a8315b2bce549a2a18966c78ede
4
+ data.tar.gz: 9f23c48f532e57c59105da808f373879037640ff
5
5
  SHA512:
6
- metadata.gz: fc16d15d0b8ca08659f067752fca417d1acaf6495ab4801b689b869661e37620f5d4a65ae4b60760af02fddcae171d5a7ad1a34342ecad7cc4c51ed0b4bb6e3a
7
- data.tar.gz: f39a2705188c3ad4cd8ae5a77339e248e207b42470f19266c290eed55fbf7f326e5a72657dbe91d179fdfb3845a5bbd90acb384d1ec799207ae68c8d9c48399d
6
+ metadata.gz: 6edf87fe1bcac33ef5d2e74af2e93e366804d964a4f3ca0c6e581ab2e576b4698940eef276366e1aa728262fcdc7bd4ce00c406343f5d77597f7ebcd5957132d
7
+ data.tar.gz: 4bfd01db70492fc17227e38bfac2f5dc622e6b4ebec1e228573a8ca23fd354e0f2f1fa7b95a52c764f46174d208ced4fb4ad99c963e11639553991580ac4741b
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --main README.md --markup=markdown {lib}/**/*.rb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.0.3
2
+ - rake cucumber:pretty_json
3
+ - Rails#find_or_halt
4
+
1
5
  # 0.0.2
2
6
 
3
7
  - Weblink#to_s
@@ -48,51 +48,27 @@ module ApiHammer::Rails
48
48
  halt(status, {'errors' => errors}, render_options)
49
49
  end
50
50
 
51
- module HaltMethods
52
- =begin
53
- # these methods are generated with the following script
54
-
55
- require 'nokogiri'
56
- require 'faraday'
57
- wpcodes = Nokogiri::HTML(Faraday.get('https://en.wikipedia.org/wiki/List_of_HTTP_status_codes').body)
58
- dts = wpcodes.css('dt')
59
- puts(dts.map do |dt|
60
- if dt.text =~ /\A\s*(\d+)\s+([a-z0-9 \-']+)/i
61
- status = $1.to_i
62
- name = $2.strip
63
- underscore = name.split(/[\s-]/).map{|word| word.downcase.gsub(/\W/, '') }.join('_')
64
- if ([100..199, 490..499, 520..599].map(&:to_a).inject([], &:+) + [306, 420, 440, 449, 450]).include?(status)
65
- # exclude these. 1xx isn't really a thing that makes sense at this level and the others are
66
- # nonstandard or particular particular web servers or such
67
- nil
68
- elsif [204, 205, 304].include?(status)
69
- # ones with no body
70
- %Q(
71
- # halt with status #{status} #{name}
72
- def halt_#{underscore}(render_options = {})
73
- halt(#{status}, '', render_options)
51
+ # attempts to find and return the given model (an ActiveRecord::Base subclass) with the given attributes.
52
+ # halts with 404 (does not return) if that fails. options[:status] may specify a different status if that
53
+ # is required.
54
+ #
55
+ # e.g.:
56
+ #
57
+ # find_or_halt(User, :email => 'user@example.com')
58
+ #
59
+ def find_or_halt(model, find_attrs, options={})
60
+ options = {:status => 404}.merge(options)
61
+ record = model.where(find_attrs).first
62
+ unless record
63
+ attributes = find_attrs.map{|attr, val| "#{attr}: #{val}" }.join(", ")
64
+ model_name = model.table_name
65
+ model_name = model_name.singularize if model_name.respond_to?(:singularize)
66
+ halt_error(options[:status], {model_name => ["Unknown #{model_name}! #{attributes}"]})
67
+ end
68
+ record
74
69
  end
75
- )
76
- elsif (400..599).include?(status)
77
- # body goes on an errors object
78
- %Q(
79
- # halt with status #{status} #{name}, responding with the given errors object on the 'errors' key
80
- def halt_#{underscore}(errors, render_options = {})
81
- halt_error(#{status}, errors, render_options)
82
- end
83
- )
84
- else
85
- %Q(
86
- # halt with status #{status} #{name}, responding with the given body object
87
- def halt_#{underscore}(body, render_options = {})
88
- halt(#{status}, body, render_options)
89
- end
90
- )
91
- end
92
- end
93
- end.compact.join)
94
70
 
95
- =end
71
+ module HaltMethods
96
72
  # halt with status 200 OK, responding with the given body object
97
73
  def halt_ok(body, render_options = {})
98
74
  halt(200, body, render_options)
@@ -397,6 +373,50 @@ end.compact.join)
397
373
  def halt_network_authentication_required(errors, render_options = {})
398
374
  halt_error(511, errors, render_options)
399
375
  end
376
+ =begin
377
+ # the above methods are generated with the following script
378
+
379
+ require 'nokogiri'
380
+ require 'faraday'
381
+ wpcodes = Nokogiri::HTML(Faraday.get('https://en.wikipedia.org/wiki/List_of_HTTP_status_codes').body)
382
+ dts = wpcodes.css('dt')
383
+ puts(dts.map do |dt|
384
+ if dt.text =~ /\A\s*(\d+)\s+([a-z0-9 \-']+)/i
385
+ status = $1.to_i
386
+ name = $2.strip
387
+ underscore = name.split(/[\s-]/).map{|word| word.downcase.gsub(/\W/, '') }.join('_')
388
+ if ([100..199, 490..499, 520..599].map(&:to_a).inject([], &:+) + [306, 420, 440, 449, 450]).include?(status)
389
+ # exclude these. 1xx isn't really a thing that makes sense at this level and the others are
390
+ # nonstandard or particular particular web servers or such
391
+ nil
392
+ elsif [204, 205, 304].include?(status)
393
+ # ones with no body
394
+ %Q(
395
+ # halt with status #{status} #{name}
396
+ def halt_#{underscore}(render_options = {})
397
+ halt(#{status}, '', render_options)
398
+ end
399
+ )
400
+ elsif (400..599).include?(status)
401
+ # body goes on an errors object
402
+ %Q(
403
+ # halt with status #{status} #{name}, responding with the given errors object on the 'errors' key
404
+ def halt_#{underscore}(errors, render_options = {})
405
+ halt_error(#{status}, errors, render_options)
406
+ end
407
+ )
408
+ else
409
+ %Q(
410
+ # halt with status #{status} #{name}, responding with the given body object
411
+ def halt_#{underscore}(body, render_options = {})
412
+ halt(#{status}, body, render_options)
413
+ end
414
+ )
415
+ end
416
+ end
417
+ end.compact.join)
418
+
419
+ =end
400
420
  end
401
421
 
402
422
  include HaltMethods
@@ -0,0 +1,54 @@
1
+ namespace :cucumber do
2
+ desc "replaces json in pystrings in feature files with pretty-printed json"
3
+ task :pretty_json do
4
+ require 'json'
5
+
6
+ features = Dir['features/**/*.feature']
7
+
8
+ features.each do |feature_file|
9
+ any_changes = false
10
+ feature = File.read(feature_file)
11
+ line_blocks = [[]]
12
+ feature.split("\n", -1).each do |line|
13
+ triq = line =~ /\A\s*"""\s*\z/
14
+ line_blocks << [] if triq
15
+ line_blocks.last << line
16
+ line_blocks << [] if triq
17
+ end
18
+
19
+ line_blocks.each_slice(4) do |steps, triq1, quoted_string_parts, triq2|
20
+ next unless triq1 # last one
21
+ quoted_string = quoted_string_parts.join("\n")
22
+ ws = triq1.first[/\A\s*/]
23
+ ws += ' '
24
+
25
+ begin
26
+ object = JSON.parse(quoted_string)
27
+ # I don't like how JSON prettifies empty arrays and objects - special case these
28
+ if object == []
29
+ pretty_json = '[]'
30
+ elsif object == {}
31
+ pretty_json = '{}'
32
+ else
33
+ pretty_json = JSON.pretty_generate(object)
34
+ end
35
+ pretty_quoted_string_parts = pretty_json.split("\n", -1).grep(/\S/).map{|jline| "#{ws}#{jline}" }
36
+ unless pretty_quoted_string_parts == quoted_string_parts
37
+ quoted_string_parts.replace(pretty_quoted_string_parts)
38
+ any_changes = true
39
+ end
40
+ rescue JSON::ParserError
41
+ # that wasn't json. leave it alone.
42
+ end
43
+
44
+ end
45
+
46
+ if any_changes
47
+ STDERR.puts "prettifying json: #{feature_file}"
48
+ File.open(feature_file, 'w') do |f|
49
+ f.write(line_blocks.inject([], &:+).join("\n"))
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,4 @@
1
+ require 'pathname'
2
+ Pathname.new(__FILE__).dirname.join('tasks').children.select { |c| c.to_s =~ /\.rb\z/ }.each do |taskfile|
3
+ require taskfile
4
+ end
@@ -1,3 +1,3 @@
1
1
  module ApiHammer
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/test/halt_test.rb CHANGED
@@ -31,6 +31,31 @@ describe 'ApiHammer::Rails#halt' do
31
31
  assert_equal(422, haltex.render_options[:status])
32
32
  end
33
33
  end
34
+
35
+ describe 'find_or_halt' do
36
+ it 'returns a record if it exists' do
37
+ record = Object.new
38
+ model = Class.new do
39
+ (class << self; self; end).class_eval do
40
+ define_method(:where) { |attrs| [record] }
41
+ define_method(:table_name) { 'records' }
42
+ end
43
+ end
44
+ assert_equal record, FakeController.new.find_or_halt(model, {:id => 'anid'})
45
+ end
46
+ it 'it halts with 404 if not' do
47
+ record = Object.new
48
+ model = Class.new do
49
+ (class << self; self; end).class_eval do
50
+ define_method(:where) { |attrs| [] }
51
+ define_method(:table_name) { 'record' }
52
+ end
53
+ end
54
+ haltex = assert_raises(ApiHammer::Halt) { FakeController.new.find_or_halt(model, {:id => 'anid'}) }
55
+ assert_equal({'errors' => {'record' => ['Unknown record! id: anid']}}, haltex.body)
56
+ assert_equal(404, haltex.render_options[:status])
57
+ end
58
+ end
34
59
  end
35
60
 
36
61
  describe 'ApiHammer::Rails#handle_halt' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_hammer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-01 00:00:00.000000000 Z
11
+ date: 2014-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -145,6 +145,7 @@ extensions: []
145
145
  extra_rdoc_files: []
146
146
  files:
147
147
  - ".simplecov"
148
+ - ".yardopts"
148
149
  - CHANGELOG.md
149
150
  - LICENSE.txt
150
151
  - README.md
@@ -155,6 +156,8 @@ files:
155
156
  - lib/api_hammer/rails.rb
156
157
  - lib/api_hammer/request_logger.rb
157
158
  - lib/api_hammer/show_text_exceptions.rb
159
+ - lib/api_hammer/tasks.rb
160
+ - lib/api_hammer/tasks/cucumber_pretty.rb
158
161
  - lib/api_hammer/tasks/gem_available_updates.rb
159
162
  - lib/api_hammer/trailing_newline.rb
160
163
  - lib/api_hammer/version.rb