application_handle_info_spec.rb 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. require 'rails_helper'
  2. RSpec.describe ApplicationHandleInfo do
  3. shared_context 'safe block execution' do |attribute:|
  4. # This `around` block is identical to ApplicationHandleInfo.use.
  5. #
  6. # Q: So why don't we just use it here to DRY things up?
  7. # A: Because that's the method we're trying to test, dummy!
  8. #
  9. # Q: Why can't we do `before { ApplicationHandleInfo.current = 'foo' }` instead?
  10. # A: Because that would change `ApplicationHandleInfo.current` for all subsequent specs.
  11. # (RSpec uses database transactions to keep test environments clean,
  12. # but `ApplicationHandleInfo.current` lives outside of the database.)
  13. around do |example|
  14. original = described_class.send(attribute)
  15. described_class.send("#{attribute}=", 'foo')
  16. example.run
  17. described_class.send("#{attribute}=", original)
  18. end
  19. end
  20. describe '.use' do
  21. it 'requires a block' do
  22. expect { described_class.use('foo') }
  23. .to raise_error(ArgumentError)
  24. end
  25. context 'for a given starting ApplicationHandleInfo' do
  26. include_examples 'safe block execution', attribute: :current
  27. it 'runs the block using the given ApplicationHandleInfo' do
  28. described_class.use('bar') do
  29. expect(described_class.current).to eq('bar')
  30. end
  31. end
  32. it 'resets ApplicationHandleInfo to its original value' do
  33. described_class.use('bar') { nil }
  34. expect(described_class.current).to eq('foo')
  35. end
  36. context 'when an error is raised in the given block' do
  37. it 'does not rescue the error, and still resets ApplicationHandleInfo' do
  38. expect { described_class.use('bar') { raise } }
  39. .to raise_error(StandardError)
  40. .and not_change(described_class, :current)
  41. end
  42. end
  43. end
  44. end
  45. describe '.in_context' do
  46. it 'requires a block' do
  47. expect { described_class.use('foo') }
  48. .to raise_error(ArgumentError)
  49. end
  50. context 'for a given starting ApplicationHandleInfo' do
  51. include_examples 'safe block execution', attribute: :context
  52. it 'runs the block using the given ApplicationHandleInfo' do
  53. described_class.in_context('bar') do
  54. expect(described_class.context).to eq('bar')
  55. end
  56. end
  57. it 'resets ApplicationHandleInfo to its original value' do
  58. described_class.in_context('bar') { nil }
  59. expect(described_class.context).to eq('foo')
  60. end
  61. context 'when an error is raised in the given block' do
  62. it 'does not rescue the error, and still resets ApplicationHandleInfo' do
  63. expect { described_class.in_context('bar') { raise } }
  64. .to raise_error(StandardError)
  65. .and not_change(described_class, :context)
  66. end
  67. end
  68. end
  69. end
  70. describe '.context_without_custom_attributes?' do
  71. it 'returns false when set to default context' do
  72. expect(described_class).not_to be_context_without_custom_attributes
  73. end
  74. context 'for a given starting ApplicationHandleInfo' do
  75. include_examples 'safe block execution', attribute: :context
  76. it 'returns true when set to context that does not use custom attributes' do
  77. described_class.context = 'merge'
  78. expect(described_class).to be_context_without_custom_attributes
  79. end
  80. it 'returns true when in .in_context block' do
  81. described_class.in_context(:merge) do
  82. expect(described_class).to be_context_without_custom_attributes
  83. end
  84. end
  85. end
  86. end
  87. end