diff --git a/.travis.yml b/.travis.yml index 156c2e3..484dbae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,3 +4,5 @@ rvm: - 2.0.0-p576 - 2.1.3 script: bundle exec rspec spec +before_install: + - gem install bundler diff --git a/CHANGELOG.md b/CHANGELOG.md index d685c1e..933f78a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.9.1 + +* Added `convert_na_to_nil=true/false` option to Client#execute + # 0.9.0 * Added support for Github R repos through OpenCPU diff --git a/lib/opencpu/client.rb b/lib/opencpu/client.rb index 80c0ca0..e0ec4da 100644 --- a/lib/opencpu/client.rb +++ b/lib/opencpu/client.rb @@ -8,12 +8,29 @@ def initialize end def execute(package, function, options = {}) - user = options.fetch :user, :system - data = options.fetch :data, {} - format = options.fetch :format, :json - github_remote = options.fetch :github_remote, false + user = options.fetch :user, :system + data = options.fetch :data, {} + format = options.fetch :format, :json + github_remote = options.fetch :github_remote, false + should_convert_na_to_nil = options.fetch :convert_na_to_nil, false + process_query package_url(package, function, user, github_remote, :json), data, format do |response| - JSON.parse(response.body) + output = JSON.parse(response.body) + output = convert_na_to_nil(output) if should_convert_na_to_nil + output + end + end + + def convert_na_to_nil(data) + case data + when 'NA' + nil + when Hash + data.each { |k, v| data[k] = convert_na_to_nil(v) } + when Array + data.map! { |v| convert_na_to_nil(v) } + else + data end end diff --git a/spec/fixtures/vcr_cassettes/animation_flip_coin.yml b/spec/fixtures/vcr_cassettes/animation_flip_coin.yml index 659cdec..c3ef592 100644 --- a/spec/fixtures/vcr_cassettes/animation_flip_coin.yml +++ b/spec/fixtures/vcr_cassettes/animation_flip_coin.yml @@ -3004,4 +3004,3 @@ http_interactions: \ \n" http_version: recorded_at: Tue, 14 Oct 2014 18:51:02 GMT -recorded_with: VCR 2.9.3 diff --git a/spec/fixtures/vcr_cassettes/response_with_na_values.yml b/spec/fixtures/vcr_cassettes/response_with_na_values.yml new file mode 100644 index 0000000..340010b --- /dev/null +++ b/spec/fixtures/vcr_cassettes/response_with_na_values.yml @@ -0,0 +1,61 @@ +--- +http_interactions: +- request: + method: post + uri: https://public.opencpu.org/ocpu/library/base/R/identity/json + body: + encoding: UTF-8 + string: x=data.frame(x%3D1%2Cy%3D1) + headers: {} + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx/1.4.6 (Ubuntu) + Date: + - Tue, 14 Oct 2014 19:01:39 GMT + Content-Type: + - application/json + Location: + - https://public.opencpu.org/ocpu/tmp/x0c19f32080/ + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Cache-Control: + - max-age=300, public + X-Ocpu-Session: + - x0c19f32080 + Access-Control-Allow-Origin: + - "*" + Access-Control-Allow-Headers: + - Origin, Content-Type, Accept, Accept-Encoding, Cache-Control + Access-Control-Expose-Headers: + - Location, X-ocpu-session, Content-Type, Cache-Control + X-Ocpu-R: + - R version 3.1.1 (2014-07-10) + X-Ocpu-Locale: + - en_US.UTF-8 + X-Ocpu-Time: + - 2014-10-14 12:01:39 PDT + X-Ocpu-Version: + - 1.4.4 + X-Ocpu-Server: + - rApache + X-Ocpu-Cache: + - MISS + body: + encoding: UTF-8 + string: |+ + [ + { + "x": "NA", + "y": "not_na" + } + ] + + http_version: + recorded_at: Tue, 14 Oct 2014 19:01:39 GMT +recorded_with: VCR 2.9.3 diff --git a/spec/lib/opencpu/client_spec.rb b/spec/lib/opencpu/client_spec.rb index 4d30fb8..7835959 100644 --- a/spec/lib/opencpu/client_spec.rb +++ b/spec/lib/opencpu/client_spec.rb @@ -105,6 +105,15 @@ end end + context 'na_to_nil = true option is given' do + it 'converts "na" values to nil' do + VCR.use_cassette :response_with_na_values do |cassette| + response = client.execute(:base, :identity, format: nil, data: {}, convert_na_to_nil: true) + expect(response).to eq [{"x"=>nil, "y"=>"not_na"}] + end + end + end + context 'multipart form / file uploads' do it "works" do skip # vcr is broken for file uploads https://github.com/vcr/vcr/issues/441 @@ -190,6 +199,25 @@ end end + describe "#convert_na_to_nil" do + let(:client) { described_class.new } + + it "converts 'NA' values in hashes in arrays" do + res = client.convert_na_to_nil([4, {foo: 'NA'}]) + expect(res[1][:foo]).to be_nil + end + + it "converts 'NA' values in arrays in hashes" do + res = client.convert_na_to_nil(foo: [1, 'NA']) + expect(res[:foo][1]).to be_nil + end + + it 'leaves other values alone' do + res = client.convert_na_to_nil(foo: [1, 'NOTNA']) + expect(res[:foo][1]).to eq 'NOTNA' + end + end + describe '#request_options' do it 'uses verify_ssl setting' do expect(described_class.new.send(:request_options, {}, nil)[:verify]).to be_truthy