whisperer 0.0.1

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.
Files changed (88) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +7 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +293 -0
  8. data/Rakefile +1 -0
  9. data/TODO.md +47 -0
  10. data/lib/whisperer.rb +102 -0
  11. data/lib/whisperer/config.rb +40 -0
  12. data/lib/whisperer/convertors/hash.rb +39 -0
  13. data/lib/whisperer/convertors/interaction.rb +21 -0
  14. data/lib/whisperer/dsl.rb +19 -0
  15. data/lib/whisperer/dsl/base.rb +47 -0
  16. data/lib/whisperer/dsl/body.rb +33 -0
  17. data/lib/whisperer/dsl/headers.rb +20 -0
  18. data/lib/whisperer/dsl/request.rb +15 -0
  19. data/lib/whisperer/dsl/response.rb +15 -0
  20. data/lib/whisperer/dsl/response/status.rb +10 -0
  21. data/lib/whisperer/generator.rb +43 -0
  22. data/lib/whisperer/helpers.rb +16 -0
  23. data/lib/whisperer/placeholder.rb +14 -0
  24. data/lib/whisperer/preprocessors.rb +19 -0
  25. data/lib/whisperer/preprocessors/base.rb +13 -0
  26. data/lib/whisperer/preprocessors/content_length.rb +17 -0
  27. data/lib/whisperer/preprocessors/response_body.rb +23 -0
  28. data/lib/whisperer/record.rb +48 -0
  29. data/lib/whisperer/record/body.rb +15 -0
  30. data/lib/whisperer/record/headers.rb +22 -0
  31. data/lib/whisperer/record/request.rb +16 -0
  32. data/lib/whisperer/record/response.rb +18 -0
  33. data/lib/whisperer/record/response/status.rb +10 -0
  34. data/lib/whisperer/samples/cassette_builder.rb +24 -0
  35. data/lib/whisperer/serializers/base.rb +24 -0
  36. data/lib/whisperer/serializers/json.rb +33 -0
  37. data/lib/whisperer/serializers/json_multiple.rb +14 -0
  38. data/lib/whisperer/tasks/whisperer.rake +88 -0
  39. data/lib/whisperer/version.rb +3 -0
  40. data/spec/cassette_builders/arya_stark.rb +26 -0
  41. data/spec/cassette_builders/bran_stark.rb +19 -0
  42. data/spec/cassette_builders/empty_robb_stark.rb +20 -0
  43. data/spec/cassette_builders/robb_stark.rb +30 -0
  44. data/spec/cassette_builders/robb_stark_without_content_length.rb +20 -0
  45. data/spec/cassette_builders/sansa_stark.rb +9 -0
  46. data/spec/cassette_builders/starks.rb +31 -0
  47. data/spec/cassette_builders/wolfs.rb +7 -0
  48. data/spec/cassettes/empty_robb_stark.yml +22 -0
  49. data/spec/cassettes/girls/arya_stark.yml +24 -0
  50. data/spec/cassettes/robb_stark.yml +28 -0
  51. data/spec/cassettes/robb_stark_without_content_length.yml +22 -0
  52. data/spec/cassettes/sansa_stark.yml +24 -0
  53. data/spec/cassettes/starks.yml +28 -0
  54. data/spec/cassettes/wolfs.yml +28 -0
  55. data/spec/factories/arya_stark.rb +7 -0
  56. data/spec/factories/bran_stark.rb +7 -0
  57. data/spec/factories/ned_stark.rb +7 -0
  58. data/spec/factories/robb_stark.rb +7 -0
  59. data/spec/factories/sansa_stark.rb +7 -0
  60. data/spec/integration/whisperer_spec.rb +51 -0
  61. data/spec/spec_helper.rb +25 -0
  62. data/spec/spec_integration_helper.rb +6 -0
  63. data/spec/support/cassettes.rb +16 -0
  64. data/spec/support/custom_serializer.rb +5 -0
  65. data/spec/unit/config_spec.rb +94 -0
  66. data/spec/unit/convertors/hash_spec.rb +59 -0
  67. data/spec/unit/convertors/interaction_spec.rb +46 -0
  68. data/spec/unit/dsl/base_spec.rb +99 -0
  69. data/spec/unit/dsl/body_spec.rb +73 -0
  70. data/spec/unit/dsl/headers_spec.rb +31 -0
  71. data/spec/unit/dsl/request_spec.rb +4 -0
  72. data/spec/unit/dsl/response_spec.rb +4 -0
  73. data/spec/unit/dsl/status_spec.rb +4 -0
  74. data/spec/unit/dsl_spec.rb +4 -0
  75. data/spec/unit/generator_spec.rb +77 -0
  76. data/spec/unit/helpers_spec.rb +38 -0
  77. data/spec/unit/preprocessors/content_length_spec.rb +39 -0
  78. data/spec/unit/preprocessors/response_body_spec.rb +55 -0
  79. data/spec/unit/preprocessors_spec.rb +8 -0
  80. data/spec/unit/record/headers_spec.rb +21 -0
  81. data/spec/unit/record/response_spec.rb +11 -0
  82. data/spec/unit/record_spec.rb +77 -0
  83. data/spec/unit/serializers/base_spec.rb +19 -0
  84. data/spec/unit/serializers/json_multiple_spec.rb +24 -0
  85. data/spec/unit/serializers/json_spec.rb +37 -0
  86. data/spec/unit/whisperer_spec.rb +189 -0
  87. data/whisperer.gemspec +28 -0
  88. metadata +277 -0
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ module Test
4
+ class Status
5
+ include Virtus.model
6
+
7
+ attribute :code, Integer
8
+ end
9
+
10
+ class Position
11
+ include Virtus.model
12
+
13
+ attribute :name
14
+ attribute :status, Status
15
+ end
16
+
17
+ class User
18
+ include Virtus.model
19
+
20
+ attribute :name, String
21
+ attribute :position, Test::Position
22
+ end
23
+ end
24
+
25
+ describe Whisperer::Convertors::Hash do
26
+ describe '#convert' do
27
+ let(:attrs) {
28
+ {
29
+ name: 'Tester',
30
+ position: {
31
+ name: 'developer',
32
+ status: {
33
+ code: 1
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ let(:expected_attrs) {
40
+ {
41
+ 'name' => 'Tester',
42
+ 'position' => {
43
+ 'name' => 'developer',
44
+ 'status' => {
45
+ 'code' => 1
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ subject { described_class.new(Test::User.new(attrs)) }
52
+
53
+ it 'returns a hash with all related objects' do
54
+ expect(subject.convert).to eq(
55
+ expected_attrs
56
+ )
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::Convertors::Interaction do
4
+ describe '#convert' do
5
+ let(:obj) { double }
6
+
7
+ let(:hash) {
8
+ {
9
+ 'request' => {
10
+ 'uri' => 'http://google.com',
11
+ 'method' => :get
12
+ },
13
+ 'response' => {
14
+ 'body' => 'test body'
15
+ },
16
+ 'recorded_at' => Time.now.httpdate
17
+ }
18
+ }
19
+
20
+ subject { described_class.new(obj).convert }
21
+
22
+ before do
23
+ allow(Whisperer::Convertors::Hash).to receive(:convert).and_return(hash)
24
+ end
25
+
26
+ it 'converts the given record to hash' do
27
+ expect(Whisperer::Convertors::Hash).to receive(:convert).with(obj).and_return(hash)
28
+
29
+ subject
30
+ end
31
+
32
+ context 'returns the VCR interraction object' do
33
+ it 'has a proper url' do
34
+ expect(subject.request.uri).to eq(hash['request']['uri'])
35
+ end
36
+
37
+ it 'has a proper HTTP method' do
38
+ expect(subject.request.method).to eq(hash['request']['method'])
39
+ end
40
+
41
+ it 'has a proper response body' do
42
+ expect(subject.response.body).to eq(hash['response']['body'])
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::BaseDsl do
4
+ context 'class method' do
5
+ describe '.link_dsl' do
6
+ before :all do
7
+ described_class.link_dsl('headers')
8
+ end
9
+
10
+ context 'using of the generated method for accessing sub DSL' do
11
+ let(:headers_container) { double('headers container') }
12
+
13
+ let(:container) do
14
+ double(
15
+ 'container',
16
+ headers: headers_container
17
+ )
18
+ end
19
+
20
+ let(:headers) { double('Whisperer::Dsl::Headers') }
21
+
22
+ subject { described_class.new(container) }
23
+
24
+ before do
25
+ allow(Whisperer::Dsl::Headers).to receive(:new).and_return(headers)
26
+ end
27
+
28
+ it 'initializes the header dsl object' do
29
+ expect(Whisperer::Dsl::Headers).to receive(:new).with(headers_container)
30
+
31
+ subject.headers {}
32
+ end
33
+
34
+ it 'executes a given block over the header dsl object' do
35
+ expect(headers).to receive(:accept).with('test')
36
+
37
+ subject.headers {
38
+ accept 'test'
39
+ }
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '.build' do
45
+ context 'when there is a linked container class' do
46
+ let(:request) { instance_double('Whisperer::Request') }
47
+
48
+ before do
49
+ described_class.link_container_class(Whisperer::Request)
50
+
51
+ allow(Whisperer::Request).to receive(:new).and_return(request)
52
+ end
53
+
54
+ it 'initializes a new instance of an object for keeping data' do
55
+ expect(Whisperer::Request).to receive(:new)
56
+
57
+ described_class.build
58
+ end
59
+
60
+ it 'initializes a new instance of the dsl' do
61
+ expect(described_class).to receive(:new).with(request)
62
+
63
+ described_class.build
64
+ end
65
+ end
66
+
67
+ context 'when there is not a linked container class' do
68
+ before do
69
+ described_class.instance_variable_set(:@container_class, nil)
70
+ end
71
+
72
+ it 'raises an error' do
73
+ expect { described_class.build }.to raise_error(
74
+ ArgumentError,
75
+ 'You should associate a container (model) with this dsl class, before building it'
76
+ )
77
+ end
78
+ end
79
+ end
80
+
81
+ describe '.add_writer' do
82
+ context 'using of the generated method for writing data to the container' do
83
+ let(:container) { double }
84
+
85
+ before :all do
86
+ described_class.add_writer('some_attr')
87
+ end
88
+
89
+ subject { described_class.new(container) }
90
+
91
+ it 'writes a given value to the container' do
92
+ expect(container).to receive("some_attr=").with('my value')
93
+
94
+ subject.some_attr('my value')
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ TestUser = Class.new(OpenStruct)
4
+
5
+ FactoryGirl.define do
6
+ factory :john_snow, class: TestUser do
7
+ name 'John Snow'
8
+ end
9
+
10
+ factory :eddard_stark, class: TestUser do
11
+ name 'Eddard Stark'
12
+ end
13
+ end
14
+
15
+ describe Whisperer::Dsl::Body do
16
+ let(:serialized_data) { 'serialized data' }
17
+ let(:container) { instance_double('Whisperer::Body', :string= => true) }
18
+ let(:serializer) { double('Serialize', serialize: true) }
19
+
20
+ subject { described_class.new(container) }
21
+
22
+ before do
23
+ allow(Whisperer).to receive(:serializer).and_return(serializer)
24
+ allow(serializer).to receive(:serialize).and_return(serialized_data)
25
+ end
26
+
27
+ describe '#factory' do
28
+ it 'writes a factory' do
29
+ expect(subject).to receive(:raw_data) do |model|
30
+ expect(model.name).to eq('John Snow')
31
+ end
32
+
33
+ subject.factory(:john_snow)
34
+ end
35
+ end
36
+
37
+ describe '#factories' do
38
+ it 'writes factories' do
39
+ expect(subject).to receive(:raw_data) do |model|
40
+ expect(model.first.name).to eq('John Snow')
41
+ expect(model.last.name).to eq('Eddard Stark')
42
+ end
43
+
44
+ subject.factories([:john_snow, :eddard_stark])
45
+ end
46
+ end
47
+
48
+ describe '#raw_data' do
49
+ let(:container) { instance_double('Whisperer::Body', :data_obj= => true, :serializer_opts= => true) }
50
+
51
+ it 'assigns the data object to the container' do
52
+ expect(container).to receive(:data_obj=).with('test obj')
53
+
54
+ subject.raw_data('test obj')
55
+ end
56
+
57
+ it 'assigns the serializer options to the container' do
58
+ expect(container).to receive(:serializer_opts=).with('test options')
59
+
60
+ subject.raw_data(nil, 'test options')
61
+ end
62
+ end
63
+
64
+ describe '#serializer' do
65
+ let(:container) { instance_double('Whisperer::Body', :serializer= => true) }
66
+
67
+ it 'converts the name to the symbol and assigns to the container' do
68
+ expect(container).to receive(:serializer=).with(:test_name)
69
+
70
+ subject.serializer 'test_name'
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::Dsl::Headers do
4
+ let(:container) { Whisperer::Headers.new }
5
+
6
+ subject { described_class.new(container) }
7
+
8
+ describe '#method_missing' do
9
+ it 'defines the accept attribute' do
10
+ subject.accept('text/plain')
11
+
12
+ expect(
13
+ container.respond_to?(:accept)
14
+ ).to be_truthy
15
+ end
16
+
17
+ it 'assigns the value to the newly defined accept method' do
18
+ subject.accept('text/plain')
19
+
20
+ expect(container.accept).to eq('text/plain')
21
+ end
22
+ end
23
+
24
+ describe '#respond_to?' do
25
+ it 'responds to the accept method' do
26
+ subject.accept('text/plain')
27
+
28
+ expect(subject.respond_to?(:accept)).to be_truthy
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::Dsl::Request do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::Dsl::Response do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::Dsl::Status do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::Dsl do
4
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Whisperer::Generator do
4
+ let(:record) { double(sub_path: 'test') }
5
+
6
+ let(:hash) {
7
+ {
8
+ 'request' => {
9
+ 'uri' => 'http://google.com',
10
+ 'method' => :get
11
+ },
12
+ 'response' => {
13
+ 'body' => 'test body'
14
+ },
15
+ 'recorded_at' => Time.now.httpdate
16
+ }
17
+ }
18
+
19
+ let(:interraction) do
20
+ VCR::HTTPInteraction.from_hash(hash)
21
+ end
22
+
23
+ describe '#generate' do
24
+ let(:path_to_cassette_dir) { VCR.configuration.cassette_library_dir + '/test/' }
25
+ let(:path_to_cassette) { path_to_cassette_dir + 'testcassette.yml' }
26
+
27
+ subject { described_class.new(record, 'testcassette') }
28
+
29
+ before do
30
+ allow(Whisperer::Preprocessors).to receive(:process!).and_return(record)
31
+ allow(Whisperer::Convertors::Interaction).to receive(:convert).and_return(interraction)
32
+ end
33
+
34
+ after do
35
+ File.delete(path_to_cassette)
36
+ Dir.delete(path_to_cassette_dir)
37
+ end
38
+
39
+ it 'processes preprocessors' do
40
+ expect(Whisperer::Preprocessors).to receive(:process!).with(record)
41
+
42
+ subject.generate
43
+ end
44
+
45
+ it 'converts the record into VCR http interraction object' do
46
+ expect(Whisperer::Convertors::Interaction).to receive(:convert).with(record).and_return(interraction)
47
+
48
+ subject.generate
49
+ end
50
+
51
+ it 'generates a VCR cassette' do
52
+ subject.generate
53
+
54
+ expect(
55
+ File.exists?(path_to_cassette)
56
+ ).to be_truthy
57
+ end
58
+
59
+ it 'returns a generated cassette' do
60
+ subject.generate
61
+
62
+ expect(subject.generate).to match(/http_interactions:/)
63
+ end
64
+
65
+ it 'removes the duplication' do
66
+ Dir.mkdir(path_to_cassette_dir)
67
+
68
+ f = File.open(path_to_cassette, 'w')
69
+ f.write('mytest')
70
+ f.close
71
+
72
+ subject.generate
73
+
74
+ expect(subject.generate).to_not match(/mytest/)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ FakeClass = Class.new do
4
+ def process; end
5
+ end
6
+
7
+ describe Whisperer::Helpers do
8
+ describe '.add_builder' do
9
+ let(:obj) { 'some simple object' }
10
+
11
+ let(:faker) {
12
+ instance_double('FakeClass', process: true)
13
+ }
14
+
15
+ before(:all) do
16
+ FakeClass.extend(Whisperer::Helpers)
17
+ FakeClass.add_builder(:process)
18
+ end
19
+
20
+ before do
21
+ allow(FakeClass).to receive(:new).and_return(faker)
22
+ end
23
+
24
+ subject { FakeClass.process(obj) }
25
+
26
+ it 'initializes the fake object' do
27
+ expect(FakeClass).to receive(:new).with(obj)
28
+
29
+ subject
30
+ end
31
+
32
+ it 'serializes an object' do
33
+ expect(faker).to receive(:process)
34
+
35
+ subject
36
+ end
37
+ end
38
+ end