pincerna 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rubocop.yml +77 -0
  4. data/.travis-gemfile +17 -0
  5. data/.travis.yml +7 -0
  6. data/.yardopts +1 -0
  7. data/CHANGELOG.md +3 -0
  8. data/Gemfile +23 -0
  9. data/LICENSE.md +21 -0
  10. data/README.md +211 -0
  11. data/Rakefile +45 -0
  12. data/bin/pincernad +56 -0
  13. data/docs/Pincerna.html +130 -0
  14. data/docs/Pincerna/Base.html +3051 -0
  15. data/docs/Pincerna/Bookmark.html +523 -0
  16. data/docs/Pincerna/Cache.html +767 -0
  17. data/docs/Pincerna/ChromeBookmark.html +308 -0
  18. data/docs/Pincerna/CurrencyConversion.html +589 -0
  19. data/docs/Pincerna/FirefoxBookmark.html +328 -0
  20. data/docs/Pincerna/Ip.html +1017 -0
  21. data/docs/Pincerna/Map.html +399 -0
  22. data/docs/Pincerna/SafariBookmark.html +308 -0
  23. data/docs/Pincerna/Server.html +673 -0
  24. data/docs/Pincerna/Translation.html +517 -0
  25. data/docs/Pincerna/UnitConversion.html +1042 -0
  26. data/docs/Pincerna/Version.html +189 -0
  27. data/docs/Pincerna/Vpn.html +561 -0
  28. data/docs/Pincerna/Weather.html +837 -0
  29. data/docs/_index.html +298 -0
  30. data/docs/class_list.html +54 -0
  31. data/docs/css/common.css +1 -0
  32. data/docs/css/full_list.css +57 -0
  33. data/docs/css/style.css +338 -0
  34. data/docs/file.README.html +327 -0
  35. data/docs/file_list.html +56 -0
  36. data/docs/frames.html +28 -0
  37. data/docs/index.html +327 -0
  38. data/docs/js/app.js +214 -0
  39. data/docs/js/full_list.js +178 -0
  40. data/docs/js/jquery.js +4 -0
  41. data/docs/method_list.html +389 -0
  42. data/docs/top-level-namespace.html +112 -0
  43. data/icon.png +0 -0
  44. data/images/chrome.png +0 -0
  45. data/images/currency.png +0 -0
  46. data/images/firefox.png +0 -0
  47. data/images/map.png +0 -0
  48. data/images/network.png +0 -0
  49. data/images/safari.png +0 -0
  50. data/images/translate.png +0 -0
  51. data/images/unit.png +0 -0
  52. data/images/vpn.png +0 -0
  53. data/images/weather.png +0 -0
  54. data/info.plist +961 -0
  55. data/it.cowtech.pincernad.plist +19 -0
  56. data/lib/pincerna.rb +30 -0
  57. data/lib/pincerna/base.rb +258 -0
  58. data/lib/pincerna/bookmark.rb +80 -0
  59. data/lib/pincerna/cache.rb +61 -0
  60. data/lib/pincerna/chrome_bookmark.rb +40 -0
  61. data/lib/pincerna/currency_conversion.rb +134 -0
  62. data/lib/pincerna/firefox_bookmark.rb +92 -0
  63. data/lib/pincerna/ip.rb +135 -0
  64. data/lib/pincerna/map.rb +30 -0
  65. data/lib/pincerna/safari_bookmark.rb +40 -0
  66. data/lib/pincerna/server.rb +85 -0
  67. data/lib/pincerna/translation.rb +67 -0
  68. data/lib/pincerna/unit_conversion.rb +120 -0
  69. data/lib/pincerna/version.rb +24 -0
  70. data/lib/pincerna/vpn.rb +74 -0
  71. data/lib/pincerna/weather.rb +188 -0
  72. data/pincerna.alfredworkflow +0 -0
  73. data/pincerna.gemspec +36 -0
  74. data/pincerna.sh +9 -0
  75. data/spec/cassettes/Pincerna_CurrencyConversion/_perform_filtering/should_return_valid_values.yml +38 -0
  76. data/spec/cassettes/Pincerna_Ip/_get_local_addresses/should_return_a_list_of_addresses.yml +47 -0
  77. data/spec/cassettes/Pincerna_Ip/_get_public_address/should_return_public_IP_address.yml +44 -0
  78. data/spec/cassettes/Pincerna_Translation/_perform_filtering/should_default_from_English_to_the_given_language_when_only_one_is_present.yml +124 -0
  79. data/spec/cassettes/Pincerna_Translation/_perform_filtering/should_query_Google_Translate_for_sentences_returning_no_alternatives.yml +51 -0
  80. data/spec/cassettes/Pincerna_Translation/_perform_filtering/should_query_Google_Translate_for_single_words.yml +71 -0
  81. data/spec/cassettes/Pincerna_Weather/_get_forecast/should_append_name.yml +177 -0
  82. data/spec/cassettes/Pincerna_Weather/_get_forecast/should_get_correct_forecasts.yml +339 -0
  83. data/spec/cassettes/Pincerna_Weather/_lookup_places/should_return_an_existing_WOEID_without_making_any_request.yml +56 -0
  84. data/spec/cassettes/Pincerna_Weather/_lookup_places/should_search_for_places.yml +189 -0
  85. data/spec/cassettes/Pincerna_Weather/_perform_filtering/should_get_forecast.yml +56 -0
  86. data/spec/coverage_helper.rb +44 -0
  87. data/spec/pincerna/base_spec.rb +166 -0
  88. data/spec/pincerna/bookmark_spec.rb +65 -0
  89. data/spec/pincerna/cache_spec.rb +88 -0
  90. data/spec/pincerna/chrome_bookmark_spec.rb +114 -0
  91. data/spec/pincerna/currency_conversion_spec.rb +46 -0
  92. data/spec/pincerna/firefox_bookmark_spec.rb +46 -0
  93. data/spec/pincerna/ip_spec.rb +194 -0
  94. data/spec/pincerna/map_spec.rb +24 -0
  95. data/spec/pincerna/safari_bookmark_spec.rb +237 -0
  96. data/spec/pincerna/server_spec.rb +108 -0
  97. data/spec/pincerna/translation_spec.rb +55 -0
  98. data/spec/pincerna/unit_conversion_spec.rb +98 -0
  99. data/spec/pincerna/vpn_spec.rb +68 -0
  100. data/spec/pincerna/weather_spec.rb +131 -0
  101. data/spec/spec_helper.rb +48 -0
  102. metadata +283 -0
@@ -0,0 +1,108 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the pincerna gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
+ # Licensed under the MIT license, which can be found at https://choosealicense.com/licenses/mit.
5
+ #
6
+
7
+ require "goliath/test_helper"
8
+ require "spec_helper"
9
+ require "pincerna/server"
10
+
11
+ describe Pincerna::Server do
12
+ include Goliath::TestHelper
13
+
14
+ subject{ ::Pincerna::Server.new }
15
+
16
+ before(:each) do
17
+ allow(subject).to receive(:params).and_return({})
18
+ allow(EM::Synchrony).to receive(:sleep)
19
+ end
20
+
21
+ describe ".enqueue_request" do
22
+ before(:each) do
23
+ allow(Time).to receive(:now).and_return(1)
24
+ expect(EM::Synchrony).to receive(:sleep).with(Pincerna::Server::DELAY)
25
+ end
26
+
27
+ it "should enqueue a request" do
28
+ Pincerna::Server.enqueue_request
29
+ expect(Pincerna::Server.instance_variable_get(:@requests).pop).to eq(1)
30
+ end
31
+ end
32
+
33
+ describe ".perform_request?" do
34
+ it "should check if the request must be performed" do
35
+ queue = Queue.new
36
+ Pincerna::Server.instance_variable_set(:@requests, queue)
37
+ queue << 1
38
+ expect(Pincerna::Server.perform_request?).to be_true
39
+ queue << 2
40
+ queue << 3
41
+ expect(Pincerna::Server.perform_request?).to be_false
42
+ end
43
+ end
44
+
45
+ describe "#handle_request" do
46
+ before(:each) do
47
+ @queue = Queue.new
48
+ Pincerna::Server.instance_variable_set(:@requests, @queue)
49
+ end
50
+
51
+ it "should handle valid requests" do
52
+ expect(Pincerna::Base).to receive(:execute!).with("map", "Campobasso", "YML", "NO").and_call_original
53
+ allow_any_instance_of(Pincerna::Base).to receive(:output).and_return("RESPONSE")
54
+ expect(subject.handle_request("map", {"q" => "Campobasso ", "format" => "YML", "debug" => "NO"})).to eq([200, {"Content-Type" => "text/x-yaml"}, "RESPONSE"])
55
+ end
56
+
57
+ it "should handle invalid requests" do
58
+ expect(subject.handle_request("mappa", {"q" => "Campobasso ", "format" => "YML", "debug" => "NO"})).to eq([404, {"Content-Type" => "text/plain"}, ""])
59
+ end
60
+
61
+ it "should handle outdated requests" do
62
+ @queue << 1
63
+
64
+ expect(Pincerna::Base).not_to receive(:execute!)
65
+ expect(subject.handle_request("mappa", {"q" => "Campobasso ", "format" => "YML", "debug" => "NO"})).to eq([429, {"Content-Type" => "text/plain"}, ""])
66
+ end
67
+ end
68
+
69
+ describe "#handle_stop" do
70
+ it "should setup a callback and return 200" do
71
+ expect(EM).to receive(:add_timer).with(0.1)
72
+ expect(subject.handle_stop).to eq([200, {}, ""])
73
+ end
74
+ end
75
+
76
+ describe "#stop_server" do
77
+ it "should destroy the cache and stop EM in the callback" do
78
+ allow_any_instance_of(EventMachine::PeriodicTimer).to receive(:schedule)
79
+ expect(Pincerna::Cache.instance).to receive(:destroy).and_call_original
80
+ expect(EM).to receive(:stop)
81
+ subject.send(:stop_server)
82
+ end
83
+ end
84
+
85
+ describe "#response" do
86
+ before(:each) do
87
+ allow(subject).to receive(:handle_request).and_return([1, {}, ""])
88
+ allow(subject).to receive(:handle_stop).and_return([2, {}, ""])
89
+ allow(subject).to receive(:handle_install).and_return([3, {}, ""])
90
+ allow(subject).to receive(:handle_uninstall).and_return([4, {}, ""])
91
+ end
92
+
93
+ it "should return the response" do
94
+ expect(subject.response({"REQUEST_PATH" => "/"})).to eq([1, {}, ""])
95
+ expect(subject.response({"REQUEST_PATH" => "foo/quit"})).to eq([1, {}, ""])
96
+ expect(subject.response({"REQUEST_PATH" => "/quit"})).to eq([2, {}, ""])
97
+ expect(subject.response({"REQUEST_PATH" => "/install"})).to eq([3, {}, ""])
98
+ expect(subject.response({"REQUEST_PATH" => "/uninstall"})).to eq([4, {}, ""])
99
+ end
100
+
101
+ it "should handle exceptions" do
102
+ allow(subject).to receive(:handle_request).and_raise(RuntimeError.new("NO"))
103
+ response = subject.response({"REQUEST_PATH" => "/"})
104
+ expect(response[0]).to eq(500)
105
+ expect(response[1]).to eq({"X-Error" => "RuntimeError", "X-Error-Message" => "NO", "Content-Type" => "text/plain"})
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the pincerna gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
+ # Licensed under the MIT license, which can be found at https://choosealicense.com/licenses/mit.
5
+ #
6
+
7
+ require "spec_helper"
8
+
9
+ describe Pincerna::Translation do
10
+ subject { Pincerna::Translation.new("QUERY", "yml") }
11
+
12
+ describe "matching" do
13
+ it "should match valid queries" do
14
+ allow_any_instance_of(Pincerna::Translation).to receive(:perform_filtering) { |*args| args }
15
+ allow_any_instance_of(Pincerna::Translation).to receive(:process_results) { |*args| args }
16
+
17
+ expect(Pincerna::Translation.new("zh-cn en FOO", "yml").filter).to eq_as_yaml([["zh-cn", "en", "FOO"]])
18
+ expect(Pincerna::Translation.new("IT to EN FOO", "yml").filter).to eq_as_yaml([["it", "en", "FOO"]])
19
+ end
20
+
21
+ it "should not match invalid queries" do
22
+ expect_any_instance_of(Pincerna::Translation).not_to receive(:perform_filtering)
23
+ expect_any_instance_of(Pincerna::Translation).not_to receive(:process_results)
24
+
25
+ expect(Pincerna::Translation.new("abc", "yml").filter).to eq_as_yaml([])
26
+ end
27
+ end
28
+
29
+ describe "#perform_filtering", :vcr, :synchronous do
30
+ before(:each) do
31
+ cache = Object.new
32
+ allow(cache).to receive(:use).and_yield
33
+ allow(Pincerna::Cache).to receive(:instance).and_return(cache)
34
+ end
35
+
36
+ it "should query Google Translate for single words" do
37
+ expect(subject.perform_filtering("it", "en", "Ciao")).to eq({main: "Hello!", alternatives: ["Hi!", "Bye-Bye!", "Bye!", "So long!", "Cheerio!", "Hallo!", "Hullo!"]})
38
+ end
39
+
40
+ it "should query Google Translate for sentences, returning no alternatives" do
41
+ expect(subject.perform_filtering("it", "en", "Ciao, come stai?")).to eq({main: "Hello, how are you?"})
42
+ end
43
+
44
+ it "should default from English to the given language when only one is present" do
45
+ expect(subject.perform_filtering("it", nil, "do")).to eq({main: "fare", alternatives: ["eseguire", "compiere", "agire", "operare", "comportarsi", "commettere", "stare", "bastare", "causare", "finire", "andare bene", "andar bene", "portare a termine", "procurare", "imbrogliare", "ingannare", "passarsela", "visitare", "combinare", "concludere"]})
46
+ end
47
+ end
48
+
49
+ describe "#process_results" do
50
+ it "should correctly prepare results" do
51
+ expect(subject.process_results({main: "fare", alternatives: ["eseguire", "compiere"]})).to eq([{title: "fare", arg: "fare", subtitle: "Alternatives: eseguire, compiere", icon: Pincerna::Translation::ICON}])
52
+ expect(subject.process_results({main: "Hello, how are you?"})).to eq([{title: "Hello, how are you?", arg: "Hello, how are you?", subtitle: "Action this item to copy the translation on the clipboard.", icon: Pincerna::Translation::ICON}])
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the pincerna gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
+ # Licensed under the MIT license, which can be found at https://choosealicense.com/licenses/mit.
5
+ #
6
+
7
+ require "spec_helper"
8
+
9
+ describe Pincerna::UnitConversion do
10
+ subject { Pincerna::UnitConversion.new("QUERY", "yml") }
11
+
12
+ describe ".define_unit" do
13
+ before(:each) do
14
+ unit = Object.new
15
+ expect(RubyUnits::Unit).to receive(:define).with("UNIT").and_call_original
16
+ end
17
+
18
+ it "should define a new unit" do
19
+ expect {
20
+ Pincerna::UnitConversion.define_unit("UNIT", "1 m", ["UNIT", "UU"])
21
+ Unit.new("3 UNIT")
22
+ Unit.new("3 UU")
23
+ }.not_to raise_error
24
+ end
25
+ end
26
+
27
+ describe "matching" do
28
+ it "should match valid queries" do
29
+ allow_any_instance_of(Pincerna::UnitConversion).to receive(:perform_filtering) { |*args| args }
30
+ allow_any_instance_of(Pincerna::UnitConversion).to receive(:process_results) { |*args| args }
31
+
32
+ expect(Pincerna::UnitConversion.new("123 m to F", "yml").filter).to eq_as_yaml([[123.0, "m", "F", false, false]])
33
+ expect(Pincerna::UnitConversion.new("-123.45 oz kg split units", "yml").filter).to eq_as_yaml([[-123.45, "oz", "kg", false, true]])
34
+ expect(Pincerna::UnitConversion.new("123 m to yd with rate", "yml").filter).to eq_as_yaml([[123.0, "m", "yd", true, false]])
35
+ end
36
+
37
+ it "should not match invalid queries" do
38
+ expect_any_instance_of(Pincerna::UnitConversion).not_to receive(:perform_filtering)
39
+ expect_any_instance_of(Pincerna::UnitConversion).not_to receive(:process_results)
40
+
41
+ expect(Pincerna::UnitConversion.new("12A3 EUR to GBP", "yml").filter).to eq_as_yaml([])
42
+ end
43
+ end
44
+
45
+ describe "#perform_filtering" do
46
+ it "should return valid values" do
47
+ converted = subject.perform_filtering(123, "mi", "km", "RATE", "SPLIT")
48
+ expect(converted.delete(:value)).to eq_as_unit(Unit.new("123 mi"))
49
+ expect(converted.delete(:unit)).to eq_as_unit(Unit.new("1 mi"))
50
+ expect(converted.delete(:result)).to eq_as_unit(Unit.new("197.949312 km"))
51
+ expect(converted.delete(:rate)).to eq_as_unit(Unit.new("1.609344 km"))
52
+ expect(converted).to eq({from: "mi", to: "km", with_rate: "RATE", multiple: "SPLIT"})
53
+ end
54
+ end
55
+
56
+ describe "#process_results" do
57
+ before(:each) do
58
+ @value = {value: Unit.new("123 kg"), from: "kg", to: "oz", unit: Unit.new("1 kg"), result: Unit.new("4338.69 oz"), rate: Unit.new("35.278 oz"), with_rate: nil, multiple: nil}
59
+ end
60
+
61
+ it "should correctly prepare results" do
62
+ expect(subject.process_results(@value)).to eq([{title: "123 kg = 4338.690 oz", arg: 4338.69, subtitle: "Action this item to copy the converted amount on the clipboard.", icon: Pincerna::UnitConversion::ICON}])
63
+ expect(subject.process_results(@value.merge(with_rate: true))).to eq([{title: "123 kg = 4338.690 oz (1 kg = 35.278 oz)", arg: 4338.69, subtitle: "Action this item to copy the converted amount on the clipboard.", icon: Pincerna::UnitConversion::ICON}])
64
+ expect(subject.process_results(@value.merge(multiple: true))).to eq([{title: "123 kg = 271 lbs 2 oz", arg: 4338.69, subtitle: "Action this item to copy the converted amount on the clipboard.", icon: Pincerna::UnitConversion::ICON}])
65
+ expect(subject.process_results(@value.merge(with_rate: true, multiple: true))).to eq([{title: "123 kg = 271 lbs 2 oz (1 kg = 2 lbs 3 oz)", arg: 4338.69, subtitle: "Action this item to copy the converted amount on the clipboard.", icon: Pincerna::UnitConversion::ICON}])
66
+ end
67
+ end
68
+
69
+ describe "#check_temperature" do
70
+ it "should correctly convert a temperature unit" do
71
+ expect(subject.check_temperature("C")).to eq("tempC")
72
+ expect(subject.check_temperature("c")).to eq("tempC")
73
+ expect(subject.check_temperature("F")).to eq("tempF")
74
+ expect(subject.check_temperature("°K")).to eq("tempK")
75
+ expect(subject.check_temperature("m")).to eq("m")
76
+ end
77
+ end
78
+
79
+ describe "#convert_value" do
80
+ it "should correctly convert units" do
81
+ expect(subject.convert_value(1, "mi", "km")).to eq_as_unit(Unit.new("1.609344 mi"))
82
+ expect(subject.convert_value(1, "gal", "L")).to eq_as_unit(Unit.new("3.785411784 L"))
83
+ end
84
+ end
85
+
86
+ describe "#format_value" do
87
+ it "should correctly format values" do
88
+ expect(subject.format_value(Unit.new("123.456789 oz"))).to eq("123.457 oz")
89
+ expect(subject.format_value(Unit.new("123.456789 oz"), nil, 1)).to eq("123.5 oz")
90
+ expect(subject.format_value(Unit.new("123.456789 oz"), :raw)).to eq(123.457)
91
+ expect(subject.format_value(Unit.new("123.456789 oz"), :raw, 6)).to eq(123.456789)
92
+ expect(subject.format_value(Unit.new("123.456789 oz"), true)).to eq("7 lbs 11 oz")
93
+ expect(subject.format_value(Unit.new("123.456789 oz"), true, 6)).to eq("7 lbs 11 oz")
94
+ expect(subject.format_value(Unit.new("123.00000 oz"))).to eq("123 oz")
95
+ expect(subject.format_value(Unit.new("123.000123 oz"))).to eq("123 oz")
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the pincerna gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
+ # Licensed under the MIT license, which can be found at https://choosealicense.com/licenses/mit.
5
+ #
6
+
7
+ require "spec_helper"
8
+
9
+ describe Pincerna::Vpn do
10
+ subject { Pincerna::Vpn.new("QUERY", "yml") }
11
+
12
+ describe "#perform_filtering" do
13
+ before(:each) do
14
+ allow(subject).to receive(:vpn_connected?) {|name| name == "VPN 2" }
15
+
16
+ allow(subject).to receive(:execute_command).with("/usr/sbin/networksetup", "-listnetworkserviceorder").and_return(<<EOVPN
17
+ An asterisk (*) denotes that a network service is disabled.
18
+ (1) Bluetooth DUN
19
+ (Hardware Port: Bluetooth DUN, Device: Bluetooth-Modem)
20
+
21
+ (2) Ethernet
22
+ (Hardware Port: Ethernet, Device: en0)
23
+
24
+ (3) VPN 1
25
+ (Hardware Port: IPSec, Device: )
26
+
27
+ (4) VPN 2
28
+ (Hardware Port: IPSec, Device: )
29
+
30
+ (5) VPAN 3
31
+ (Hardware Port: L2TP, Device: )
32
+ EOVPN
33
+ )
34
+ end
35
+
36
+ describe "should return the correct list of the VPN and their statuses" do
37
+ it "with no query" do
38
+ expect(subject.perform_filtering("")).to eq([{name: "VPN 1", connected: false}, {name: "VPN 2", connected: true}, {name: "VPAN 3", connected: false}])
39
+ end
40
+
41
+ it "with query" do
42
+ expect(subject.perform_filtering("VPN")).to eq([{name: "VPN 1", connected: false}, {name: "VPN 2", connected: true}])
43
+ expect(subject.perform_filtering("3")).to eq([{name: "VPAN 3", connected: false}])
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "#process_results" do
49
+ it "should correctly prepare results" do
50
+ expect(subject.process_results([{name: "VPN 1", connected: true}, {name: "VPN 2", connected: false}])).to eq([
51
+ {title: "Disconnect from VPN 1", arg: "disconnect service \"VPN 1\"", subtitle: "Action this item to disconnect from the VPN service.", icon: Pincerna::Vpn::ICON},
52
+ {title: "Connect to VPN 2", arg: "connect service \"VPN 2\"", subtitle: "Action this item to connect to the VPN service.", icon: Pincerna::Vpn::ICON}
53
+ ])
54
+ end
55
+ end
56
+
57
+ describe "#vpn_connected" do
58
+ it "should return the correct connected status" do
59
+ expect(subject).to receive(:execute_command).with("/usr/sbin/networksetup", "-showpppoestatus", "\"VPN\"").and_return("connected")
60
+ expect(subject.vpn_connected?("VPN")).to be_true
61
+ end
62
+
63
+ it "should return false for other status" do
64
+ expect(subject).to receive(:execute_command).with("/usr/sbin/networksetup", "-showpppoestatus", "\"VPN\"").and_return("other")
65
+ expect(subject.vpn_connected?("VPN")).to be_false
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,131 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the pincerna gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
+ # Licensed under the MIT license, which can be found at https://choosealicense.com/licenses/mit.
5
+ #
6
+
7
+ require "spec_helper"
8
+
9
+ describe Pincerna::Weather do
10
+ subject { Pincerna::Weather.new("QUERY", "yml") }
11
+
12
+ describe "matching" do
13
+ it "should match valid queries" do
14
+ allow_any_instance_of(Pincerna::Weather).to receive(:perform_filtering) { |*args| args }
15
+ allow_any_instance_of(Pincerna::Weather).to receive(:process_results) { |*args| args }
16
+
17
+ expect(Pincerna::Weather.new("Campobasso", "yml").filter).to eq_as_yaml([["Campobasso", "c"]])
18
+ expect(Pincerna::Weather.new("Campobasso in c", "yml").filter).to eq_as_yaml([["Campobasso", "c"]])
19
+ expect(Pincerna::Weather.new("Campobasso in F", "yml").filter).to eq_as_yaml([["Campobasso", "f"]])
20
+ end
21
+ end
22
+
23
+ describe "#perform_filtering", :vcr do
24
+ before(:each) do
25
+ allow(subject).to receive(:lookup_places).with("Campobasso") { |*args| [{woeid: 12345, name: "Campobasso, Molise, Italy"}] }
26
+ allow(subject).to receive(:get_forecast).with([{woeid: 12345, name: "Campobasso, Molise, Italy"}], "c") { |*args|
27
+ [{name: "Campobasso, Molise, Italy", image: "IMAGE", link: "LINK", current: {description: "TEXT", temperature: "29 C", wind: {speed: "29 kmh", direction: "W"}}, forecast: { description: "TEXT", high: "29 C", low: "13 C"}}]
28
+ }
29
+ end
30
+
31
+ it "should get forecast" do
32
+ expect(subject.perform_filtering("Campobasso", "c")).to eq([{name: "Campobasso, Molise, Italy", image: "IMAGE", link: "LINK", current: { description: "TEXT", temperature: "29 C", wind: {speed: "29 kmh", direction: "W"}}, forecast: { description: "TEXT", high: "29 C", low: "13 C"}}])
33
+ end
34
+ end
35
+
36
+ describe "#process_results" do
37
+ before(:each) do
38
+ @value = [{name: "Campobasso, Molise, Italy", image: "IMAGE", link: "LINK", current: { description: "CURRENT", temperature: "29 C", wind: {speed: "29 kmh", direction: "W"}}, forecast: { description: "NEXT", high: "29 C", low: "13 C"}}]
39
+ end
40
+
41
+ it "should correctly prepare results" do
42
+ expect(subject.process_results(@value)).to eq([{
43
+ title: "Campobasso, Molise, Italy", arg: "LINK",
44
+ subtitle: "29 C, Current, wind 29 kmh W - Next: 29 C / 13 C, NEXT",
45
+ icon: "IMAGE"
46
+ }])
47
+ end
48
+ end
49
+
50
+ describe "#lookup_places", :vcr, :synchronous do
51
+ before(:each) do
52
+ cache = Object.new
53
+ allow(cache).to receive(:use).and_yield
54
+ allow(Pincerna::Cache).to receive(:instance).and_return(cache)
55
+ end
56
+
57
+ it "should search for places" do
58
+ expect(subject.lookup_places("Campobasso")).to eq([{woeid: 711892, name: "Campobasso, Molise, Italy"}])
59
+ expect(subject.lookup_places("San Mateo")).to eq([{woeid: 2488142, name: "San Mateo, California, United States"}, {woeid: 2488139, name: "San Mateo, Putnam, Florida, United States"}, {woeid: 775977, name: "San Mateo, Sant Mateu, Castellon, Valencia, Spain"}, {woeid: 2488141, name: "San Mateo, Cibola, New Mexico, United States"}, {woeid: 2488150, name: "Jacksonville, Duval, Florida, United States"}])
60
+ expect(subject.lookup_places("asdfghjkl")).to eq([])
61
+ end
62
+
63
+ it "should return an existing WOEID without making any request" do
64
+ expect(subject.lookup_places("123")).to eq([{woeid: "123"}])
65
+ end
66
+ end
67
+
68
+ describe "#get_forecast", vcr: true do
69
+ before(:each) do
70
+ cache = Object.new
71
+ allow(cache).to receive(:use).and_yield
72
+ allow(Pincerna::Cache).to receive(:instance).and_return(cache)
73
+
74
+ @cache_dir = "/tmp/pincerna-weather"
75
+ subject.instance_variable_set("@cache_dir", @cache_dir)
76
+ FileUtils.rm_rf(@cache_dir)
77
+ end
78
+
79
+ after(:each) do
80
+ FileUtils.rm_rf(@cache_dir)
81
+ end
82
+
83
+ it "should get correct forecasts" do
84
+ expect(subject.get_forecast([{woeid: 711892, name: "Campobasso, Molise, Italy"}, {woeid: 2488142, name: "San Mateo, California, United States"}])).to eq([
85
+ {
86
+ woeid: 711892,
87
+ name: "Campobasso, Molise, Italy",
88
+ image: @cache_dir + "/weather/32.gif",
89
+ link: "http://us.rd.yahoo.com/dailynews/rss/weather/Campobasso__IT/*http://weather.yahoo.com/forecast/ITXX0112_c.html",
90
+ current: {description: "Sunny", temperature: "34 °C", wind: {speed: "1.61 km/h", direction: "W"}},
91
+ forecast: {description: "Thunderstorms Early", high: "31 °C", low: "23 °C"}
92
+ },
93
+ {
94
+ woeid: 2488142,
95
+ name: "San Mateo, California, United States",
96
+ image: @cache_dir + "/weather/26.gif",
97
+ link: "http://us.rd.yahoo.com/dailynews/rss/weather/San_Mateo__CA/*http://weather.yahoo.com/forecast/USCA1005_c.html",
98
+ current: {description: "Cloudy", temperature: "16 °C", wind: {speed: "9.66 km/h", direction: "W"}},
99
+ forecast: {description: "AM Clouds/PM Sun", high: "21 °C", low: "14 °C"},
100
+ }
101
+ ])
102
+ end
103
+
104
+ it "should append name" do
105
+ expect(subject.get_forecast([{woeid: 2488139}])).to eq([{
106
+ woeid: 2488139,
107
+ name: "San Mateo, FL, United States",
108
+ image: @cache_dir + "/weather/30.gif",
109
+ link: "http://us.rd.yahoo.com/dailynews/rss/weather/San_Mateo__FL/*http://weather.yahoo.com/forecast/USFL0538_c.html",
110
+ current: {description: "Partly Cloudy", temperature: "31 °C", wind: {speed: "14.48 km/h", direction: "E"}},
111
+ forecast: {description: "Scattered Thunderstorms", high: "32 °C", low: "24 °C"}
112
+ }])
113
+ end
114
+ end
115
+
116
+ describe "#get_wind_direction" do
117
+ it "should correctly calculate directions" do
118
+ results = [
119
+ "N",
120
+ "N", "NE", "NE", "NE", "NE", "E", "E", "E", "E", # 90
121
+ "E", "SE", "SE", "SE", "SE", "S", "S", "S", "S", #180
122
+ "S", "SW", "SW", "SW", "SW", "W", "W", "W", "W", # 240
123
+ "W", "NW", "NW", "NW", "NW", "N", "N", "N", "N"
124
+ ]
125
+
126
+ 37.times do |deg|
127
+ expect(subject.get_wind_direction(deg * 10)).to eq(results[deg])
128
+ end
129
+ end
130
+ end
131
+ end