pincerna 1.1.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.
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