invoca-utils 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 803af8a0e5807bf4ff18c6d9f3ab1d300dd35b4c
4
- data.tar.gz: 05f62242e46f4804eabbcd80a13d8e8ce31f3e1f
3
+ metadata.gz: 9af5982666a515cac52ec601dcc30bb8be8b473a
4
+ data.tar.gz: ab9b463b80311d295136c72b5df683b959e03579
5
5
  SHA512:
6
- metadata.gz: 239abcd4639fe9964477283066f852fea8d4c45f1bd97b08830239d81b11fe8392cfd52b0fc9505779e8a51e3ff9b1e9a1298d4cdd9f811365f782dc37ffd77f
7
- data.tar.gz: 478e3b36bb18e5df962bb9fd258d7aaca49e908965c7b775a4a64806fe5f87019d89e595d5d945c7aaf3d9030b30d6ebeee63a0f98ea41d53c9213193593e6cd
6
+ metadata.gz: 0b807a493e7bedc3eca0901d3276723d8cadc91cd3a67a2b31b009695f0be4ffd16562254802a9aab4526b29bd463da17b942400e197a122d08a41e0c37b8c8c
7
+ data.tar.gz: 4fcf0da07ac921a2410271dd84c94599ca5ee8893be9db532e41970141fdd35172459f843a32c8cabbc2887b13b4d039991059322a43359090565cbf34a603ea
data/.gitignore CHANGED
@@ -4,7 +4,6 @@
4
4
  .bundle
5
5
  .config
6
6
  .yardoc
7
- Gemfile.lock
8
7
  InstalledFiles
9
8
  _yardoc
10
9
  coverage
@@ -21,3 +20,4 @@ tmp
21
20
  *.o
22
21
  *.a
23
22
  mkmf.log
23
+ .idea/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.4.2
data/Gemfile CHANGED
@@ -2,3 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in invoca-utils.gemspec
4
4
  gemspec
5
+
data/Gemfile.lock ADDED
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ invoca-utils (0.0.3)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (5.1.4)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (~> 0.7)
12
+ minitest (~> 5.1)
13
+ tzinfo (~> 1.1)
14
+ coderay (1.1.2)
15
+ concurrent-ruby (1.0.5)
16
+ hoe (3.16.2)
17
+ rake (>= 0.8, < 13.0)
18
+ i18n (0.9.1)
19
+ concurrent-ruby (~> 1.0)
20
+ method_source (0.9.0)
21
+ minitest (5.11.1)
22
+ pry (0.11.3)
23
+ coderay (~> 1.1.0)
24
+ method_source (~> 0.9.0)
25
+ rake (12.3.0)
26
+ rr (1.1.2)
27
+ ruby-prof (0.17.0)
28
+ shoulda (3.5.0)
29
+ shoulda-context (~> 1.0, >= 1.0.1)
30
+ shoulda-matchers (>= 1.4.1, < 3.0)
31
+ shoulda-context (1.2.2)
32
+ shoulda-matchers (2.8.0)
33
+ activesupport (>= 3.0.0)
34
+ test-unit (1.2.3)
35
+ hoe (>= 1.5.1)
36
+ thread_safe (0.3.6)
37
+ tzinfo (1.2.4)
38
+ thread_safe (~> 0.1)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ bundler (~> 1.6)
45
+ invoca-utils!
46
+ minitest
47
+ pry
48
+ rake
49
+ rr (= 1.1.2)
50
+ ruby-prof
51
+ shoulda (= 3.5.0)
52
+ test-unit (= 1.2.3)
53
+ tzinfo
54
+
55
+ BUNDLED WITH
56
+ 1.16.0
data/Rakefile CHANGED
@@ -2,17 +2,14 @@
2
2
  require "bundler/gem_tasks"
3
3
  require 'rake/testtask'
4
4
 
5
- namespace :test do
6
-
7
- Rake::TestTask.new do |t|
8
- t.name = :unit
9
- t.libs << "test"
10
- t.pattern = 'test/unit/**/*_test.rb'
11
- t.verbose = true
12
- end
13
- Rake::Task['test:unit'].comment = "Run the unit tests"
14
-
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << 'lib'
7
+ t.libs << 'test'
8
+ t.pattern = 'test/**/*_test.rb'
9
+ t.verbose = false
15
10
  end
16
11
 
17
- task :default => 'test:unit'
12
+ task default: :test
13
+
14
+ task :default => 'test'
18
15
 
data/invoca-utils.gemspec CHANGED
@@ -20,11 +20,11 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.6"
22
22
  spec.add_development_dependency "rake"
23
-
24
23
  spec.add_development_dependency "test-unit", "= 1.2.3"
25
24
  spec.add_development_dependency "rr", "=1.1.2"
26
25
  spec.add_development_dependency "shoulda", "= 3.5.0"
27
26
  spec.add_development_dependency "pry"
28
27
  spec.add_development_dependency "ruby-prof"
29
28
  spec.add_development_dependency "minitest"
29
+ spec.add_development_dependency "tzinfo"
30
30
  end
@@ -87,7 +87,7 @@ class Diff
87
87
  result << " #{format arg}\n" unless arg.nil? || options[:short_description]
88
88
  end
89
89
  if curr_diff && curr_diff[1].first == index
90
- verb, a_range, b_range, del, add = curr_diff
90
+ verb, _a_range, _b_range, del, add = curr_diff
91
91
  result <<
92
92
  case verb
93
93
  when 'd'
@@ -96,8 +96,8 @@ class Diff
96
96
  add.map { |t| "+ #{format t}\n"}.join +
97
97
  (arg.nil? ? '' : " #{format arg}\n")
98
98
  when 'c'
99
- del.map_with_index { |t,index| "- #{format t}\n#{ nested_compare( del, add, index ) }"}.join +
100
- add.map_with_index { |t,index| "+ #{format t}\n"}.join
99
+ del.map_with_index { |t, del_index| "- #{format t}\n#{nested_compare(del, add, del_index)}" }.join +
100
+ add.map { |t| "+ #{format t}\n" }.join
101
101
  end
102
102
  end
103
103
  end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This class expects to be initialized with a string and guarantees that the output of the to_string method is in UTF-8 format and fits in 3 bytes/char or less.
4
+ module Invoca
5
+ module Utils
6
+ class GuaranteedUTF8String
7
+ def initialize(string)
8
+ if string.is_a?(String) ||
9
+ (string.respond_to?(:to_s) &&
10
+ string.method(:to_s).owner != Kernel) # the lame .to_s from Kernel just calls .inspect :(
11
+ @string = string.to_s
12
+ else
13
+ raise ArgumentError, "#{self.class} must be initialized with a string or an object with a non-Kernel .to_s method but instead was #{string.class} #{string.inspect}"
14
+ end
15
+ end
16
+
17
+ def to_string
18
+ @to_string ||= normalize_string(@string)
19
+ end
20
+
21
+ alias_method :to_s, :to_string
22
+
23
+ private
24
+
25
+ # chosen because this is a 1-byte ASCII character that is not used in any of the popular escaping systems: XML, HTML, HTTP URIs, HTTP Form Post, JSON
26
+ REPLACE_CHARACTER = '~' unless defined?(REPLACE_CHARACTER)
27
+
28
+ def normalize_string(str)
29
+ str = @string.dup
30
+ str.force_encoding('UTF-8')
31
+ if !str.valid_encoding?
32
+ cp1252_to_utf_8(str)
33
+ end
34
+ normalize_newlines(str)
35
+ remove_bom(str)
36
+ replace_unicode_beyond_ffff(str)
37
+ str
38
+ end
39
+
40
+ def normalize_newlines(str)
41
+ str.gsub!(/ \r\n | \r | \n /x, "\n")
42
+ end
43
+
44
+ def cp1252_to_utf_8(str)
45
+ str.force_encoding('CP1252')
46
+ str.encode!(
47
+ 'UTF-8',
48
+ replace: REPLACE_CHARACTER,
49
+ undef: :replace,
50
+ invalid: :replace
51
+ )
52
+ end
53
+
54
+ def remove_bom(str)
55
+ str.sub!(/\A \xEF\xBB\xBF/x, '')
56
+ end
57
+
58
+ # Note MySQL can only store Unicode up to code point U+FFFF in the standard mb3 storage type. There is an option to use mb4 which
59
+ # is needed to hold the code points above that (including emoji) but we haven't enabled that on any columns yet since
60
+ # it would take a data migration and didn't seem that important.
61
+
62
+ def replace_unicode_beyond_ffff(str)
63
+ str.gsub!(/[^\u{0}-\u{ffff}]/x, REPLACE_CHARACTER)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,45 @@
1
+ require 'net/http'
2
+
3
+ if RUBY_VERSION == '1.8.7'
4
+ module ::Net #:nodoc:
5
+ class HTTP < Protocol
6
+ def connect
7
+ D "opening connection to #{conn_address()}..."
8
+ s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
9
+ D "opened"
10
+ if use_ssl?
11
+ unless @ssl_context.verify_mode
12
+ warn "warning: peer certificate won't be verified in this SSL session"
13
+ @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
14
+ end
15
+ s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
16
+ s.sync_close = true
17
+ end
18
+ @socket = BufferedIO.new(s)
19
+ @socket.read_timeout = @read_timeout
20
+ @socket.debug_output = @debug_output
21
+ if use_ssl?
22
+ if proxy?
23
+ @socket.writeline sprintf('CONNECT %s:%s HTTP/%s',
24
+ @address, @port, HTTPVersion)
25
+ @socket.writeline "Host: #{@address}:#{@port}"
26
+ if proxy_user
27
+ credential = ["#{proxy_user}:#{proxy_pass}"].pack('m')
28
+ credential.delete!("\r\n")
29
+ @socket.writeline "Proxy-Authorization: Basic #{credential}"
30
+ end
31
+ @socket.writeline ''
32
+ HTTPResponse.read_new(@socket).value
33
+ end
34
+ # NOTE: Change here. This was just s.connect, now we have added a timeout.
35
+ timeout(@open_timeout) { s.connect }
36
+ if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
37
+ s.post_connection_check(@address)
38
+ end
39
+ end
40
+ on_connect
41
+ end
42
+ private :connect
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,10 @@
1
+ module ::Enumerable
2
+ def map_compact
3
+ result = []
4
+ each do |item|
5
+ selected = yield(item)
6
+ result << selected unless selected.nil?
7
+ end
8
+ result
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module ::Math
2
+ def self.min *args
3
+ args.min
4
+ end
5
+
6
+ def self.max *args
7
+ args.max
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ module ::Enumerable
2
+
3
+ # A stable sort will preserve the original order of two elements if their sort keys are identical.
4
+
5
+ def stable_sort
6
+ n = -1
7
+ if block_given?
8
+ collect {|x| n += 1; [x, n]
9
+ }.sort! {|a, b|
10
+ c = yield a[0], b[0]
11
+ if c.nonzero? then c else a[1] <=> b[1] end
12
+ }.collect! {|x| x[0]}
13
+ else
14
+ sort_by {|x| n += 1; [x, n]}
15
+ end
16
+ end
17
+
18
+ def stable_sort_by
19
+ block_given? or return enum_for(:stable_sort_by)
20
+ n = -1
21
+ sort_by {|x| n += 1; [(yield x), n]}
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # Invoca ::Time extensions
2
+ class ::Time
3
+ def to_ms
4
+ @to_ms ||= (self.to_f * 1000).to_i
5
+ end
6
+
7
+ #rfc3339ms is like rfc3339 but with milliseconds
8
+ if RUBY_VERSION < "1.9.3"
9
+ def rfc3339ms
10
+ strftime("%Y-%m-%dT%H:%M:%S.#{ms_for_3339}%z")
11
+ end
12
+
13
+ def ms_for_3339
14
+ @ms_for_3339 ||= ("%03.3d" % (self.to_ms % 1000))
15
+ end
16
+ private :ms_for_3339
17
+ else
18
+ def rfc3339ms
19
+ strftime("%Y-%m-%dT%H:%M:%S.%L%z")
20
+ end
21
+ end
22
+
23
+ def beginning_of_hour
24
+ change(:min => 0, :sec => 0, :usec => 0)
25
+ end
26
+
27
+ def end_of_day_whole_sec # usec can be bad because it isn't preserved by MySQL
28
+ change(:hour => 23, :min => 59, :sec => 59, :usec => 0)
29
+ end
30
+
31
+ def whole_sec
32
+ change(:usec => 0)
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Invoca
2
2
  module Utils
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
data/lib/invoca/utils.rb CHANGED
@@ -1,9 +1,13 @@
1
- require "invoca/utils/version"
2
-
3
1
  require "invoca/utils/diff"
2
+ require "invoca/utils/http"
3
+ require "invoca/utils/map_compact"
4
+ require "invoca/utils/min_max"
5
+ require "invoca/utils/stable_sort"
6
+ require "invoca/utils/time"
7
+ require "invoca/utils/guaranteed_utf8_string"
8
+ require "invoca/utils/version"
4
9
 
5
10
  module Invoca
6
11
  module Utils
7
-
8
12
  end
9
13
  end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../test_helper'
4
+
5
+ class GuaranteedUTF8StringTest < Minitest::Test
6
+ class HasNoTo_sMethod
7
+ undef :to_s
8
+ end
9
+
10
+ class BasicObjectWithKernelMethods
11
+ end
12
+
13
+ class ConvertibleToString
14
+ attr_reader :to_s
15
+
16
+ def initialize(string)
17
+ @to_s = string
18
+ end
19
+ end
20
+
21
+ should "raise an error if initialized with an object with no to_s method" do
22
+ assert_raises ArgumentError, /GuaranteedUTF8String must be initialized with a string or an object with a non-Kernel \.to_s method but instead was GuaranteedUTF8StringTest::HasNoTo_sMethod/ do
23
+ Invoca::Utils::GuaranteedUTF8String.new(HasNoTo_sMethod.new)
24
+ end
25
+ end
26
+
27
+ should "raise an error if initialized with a basic Ruby object" do
28
+ assert_raises ArgumentError, /GuaranteedUTF8String must be initialized with a string or an object with a non-Kernel \.to_s method but instead was GuaranteedUTF8StringTest::BasicObjectWithKernelMethods/ do
29
+ Invoca::Utils::GuaranteedUTF8String.new(BasicObjectWithKernelMethods.new)
30
+ end
31
+ end
32
+
33
+ should "convert to a string with to_s if possible" do
34
+ result = Invoca::Utils::GuaranteedUTF8String.new(ConvertibleToString.new("test string"))
35
+ assert_equal "test string", result.to_string
36
+ end
37
+
38
+ context "#to_string" do
39
+ should "not mutate the original string" do
40
+ ascii_string = "new string".encode("ASCII")
41
+ utf8_string_instance = Invoca::Utils::GuaranteedUTF8String.new(ascii_string)
42
+ encoded_string = utf8_string_instance.to_string
43
+
44
+ assert_equal ascii_string, encoded_string
45
+ assert_equal Encoding::ASCII, ascii_string.encoding
46
+ assert_equal Encoding::UTF_8, encoded_string.encoding
47
+ end
48
+
49
+ should "return UTF-8 encoded string" do
50
+ original_string = "this,is,a,valid,utf-8,csv,string\none,two,three,four,five,six,seven\n"
51
+
52
+ encoded_string = Invoca::Utils::GuaranteedUTF8String.new(original_string).to_string
53
+
54
+ assert_equal original_string, encoded_string
55
+ assert_equal Encoding::UTF_8, encoded_string.encoding
56
+ end
57
+
58
+ should "return UTF-8 encoded string without BOM" do
59
+ original_string = "\xEF\xBB\xBFthis,is,a,valid,utf-8,csv,string\none,two,three,four,five,six,seven\n"
60
+
61
+ encoded_string = Invoca::Utils::GuaranteedUTF8String.new(original_string).to_string
62
+
63
+ assert_equal "this,is,a,valid,utf-8,csv,string\none,two,three,four,five,six,seven\n", encoded_string
64
+ assert_equal Encoding::UTF_8, encoded_string.encoding
65
+ end
66
+
67
+ should "return UTF-8 encoded string using to_s alias" do
68
+ original_string = "this,is,a,valid,utf-8,csv,string\none,two,three,four,five,six,seven\n"
69
+
70
+ encoded_string = Invoca::Utils::GuaranteedUTF8String.new(original_string).to_s
71
+
72
+ assert_equal original_string, encoded_string
73
+ assert_equal Encoding::UTF_8, encoded_string.encoding
74
+ end
75
+
76
+ should "return UTF-8 encoded string after falling back to CP1252 encoding" do
77
+ string = "This,is,NOT,a,valid,utf-8,csv,string\r\none,two,three,four,\x81five\xF6,six,seven,eight\n"
78
+ expected_string = "This,is,NOT,a,valid,utf-8,csv,string\none,two,three,four,~fiveö,six,seven,eight\n"
79
+
80
+ encoded_string = Invoca::Utils::GuaranteedUTF8String.new(string).to_string
81
+
82
+ assert_equal expected_string, encoded_string
83
+ assert_equal Encoding::UTF_8, encoded_string.encoding
84
+ end
85
+
86
+ should "return UTF-8 encoded string with normalized return chars" do
87
+ string = "This string\n\n\n has line feeds\ncarriage\r\r returns\rand Windows\r\n\r\n new line chars\r\nend of \n\r\r\r\nstring"
88
+ expected_string = "This string\n\n\n has line feeds\ncarriage\n\n returns\nand Windows\n\n new line chars\nend of \n\n\n\nstring"
89
+
90
+ encoded_string = Invoca::Utils::GuaranteedUTF8String.new(string).to_string
91
+
92
+ assert_equal expected_string, encoded_string
93
+ assert_equal Encoding::UTF_8, encoded_string.encoding
94
+ end
95
+
96
+ should "encode all 255 UTF-8 characters, returning ~ when the character isn't mapped in CP1252" do
97
+ all_8_bit_characters = (1..255).map { |char| char.chr }.join
98
+
99
+ final_utf_8_string = Invoca::Utils::GuaranteedUTF8String.new(all_8_bit_characters.dup).to_s
100
+ expected_string = "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000A\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F !\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007F€~‚ƒ„…†‡ˆ‰Š‹Œ~Ž~~‘’“”•–—˜™š›œ~žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
101
+
102
+ assert_equal expected_string, final_utf_8_string
103
+ end
104
+
105
+ should "consider UTF-8 code points that take > 3 bytes (above U+FFFF) to be invalid (since MySQL can't store them unless column is declared mb4) and encode them as ~" do
106
+ string = "This string has some ✓ valid UTF-8 but also some 😹 emoji \xf0\x9f\x98\xb9 that are > U+FFFF"
107
+ expected_string = "This string has some ✓ valid UTF-8 but also some ~ emoji ~ that are > U+FFFF"
108
+
109
+ encoded_string = Invoca::Utils::GuaranteedUTF8String.new(string).to_string
110
+
111
+ assert_equal expected_string, encoded_string
112
+ assert_equal Encoding::UTF_8, encoded_string.encoding
113
+ end
114
+ end
115
+ end
116
+
@@ -0,0 +1,23 @@
1
+ require_relative '../test_helper'
2
+
3
+ class MapCompactTest < Minitest::Test
4
+ should "map_compact" do
5
+ assert_equal [1, 9], [1, 2, nil, 3, 4].map_compact { |item| item**2 if (nil == item ? nil : item.odd?) }
6
+ end
7
+
8
+ should "map_compact to empty if nothing matches" do
9
+ assert_equal [], {:a => 'aaa', :b => 'bbb'}.map_compact { |key, value| value if key == :c }
10
+ end
11
+
12
+ should "map_compact a hash" do
13
+ assert_equal ['bbb'], {:a => 'aaa', :b => 'bbb'}.map_compact { |key, value| value if key == :b }
14
+ end
15
+
16
+ should "map_compact empty collection" do
17
+ assert_equal [], [].map_compact { |item| true }
18
+ end
19
+
20
+ should "not map_compact false" do
21
+ assert_equal [false], [nil, false].map_compact { |a| a }
22
+ end
23
+ end
@@ -0,0 +1,52 @@
1
+ require_relative '../test_helper'
2
+
3
+ class StableSortTest < Minitest::Test
4
+ context "#stable_sort_by" do
5
+ should "preserve the original order if all sort the same" do
6
+ list_to_sort = [:b, :d, :c, :a, :e, :f]
7
+
8
+ assert_equal list_to_sort, list_to_sort.stable_sort_by { |c| 0 }
9
+ end
10
+
11
+ should "order by keys first and then position" do
12
+ list_to_sort = [:b, :d, :c, :a, :e, :f]
13
+ order = [:a, :b, :c]
14
+
15
+ result = list_to_sort.stable_sort_by { |c| order.index(c) || order.length }
16
+ assert_equal [:a, :b, :c, :d, :e, :f], result
17
+ end
18
+
19
+ should "order by keys only if needed" do
20
+ list_to_sort = [:b, :d, :c, :a, :e, :f]
21
+ result = list_to_sort.stable_sort_by { |c| c.to_s }
22
+ assert_equal [:a, :b, :c, :d, :e, :f], result
23
+ end
24
+ end
25
+
26
+ context "stable_sort" do
27
+ should "preserve the original order if all sort the same" do
28
+ list_to_sort = [:b, :d, :c, :a, :e, :f]
29
+
30
+ assert_equal list_to_sort, list_to_sort.stable_sort { |first, second| 0 }
31
+ end
32
+
33
+ should "order by keys first and then position" do
34
+ list_to_sort = [:b, :d, :c, :a, :e, :f]
35
+ order = [:a, :b, :c]
36
+
37
+ result = list_to_sort.stable_sort do |first, second|
38
+ first_pos = order.index(first) || order.length
39
+ second_pos = order.index(second) || order.length
40
+ first_pos <=> second_pos
41
+ end
42
+
43
+ assert_equal [:a, :b, :c, :d, :e, :f], result
44
+ end
45
+
46
+ should "order by keys only if needed" do
47
+ list_to_sort = [:b, :d, :c, :a, :e, :f]
48
+ result = list_to_sort.stable_sort{ |first, second| first.to_s <=> second.to_s }
49
+ assert_equal [:a, :b, :c, :d, :e, :f], result
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../test_helper'
2
+ require 'active_support/all'
3
+
4
+ class TimeCalculationsTest < Minitest::Test
5
+ context "beginning_of_hour" do
6
+ Time.zone = 'Pacific Time (US & Canada)'
7
+ [
8
+ Time.now,
9
+ Time.zone.now,
10
+ Time.local(2009),
11
+ Time.local(2009,3,4,5),
12
+ Time.local(2001,12,31,23,59),
13
+ Time.local(1970,1,1)
14
+ ].each_with_index do |time, index|
15
+ should "give back a time with no minutes, seconds, or msec: #{time} (#{index})" do
16
+ t = time.beginning_of_hour
17
+ assert_equal t.year, time.year
18
+ assert_equal t.month, time.month
19
+ assert_equal t.day, time.day
20
+ assert_equal t.hour, time.hour
21
+ assert_equal 0, t.min
22
+ assert_equal 0, t.sec
23
+ assert_equal 0, t.usec
24
+ end
25
+ end
26
+ end
27
+
28
+ context "end_of_day_whole_sec" do
29
+ should "return the end of day with whole_sec" do
30
+ t = Time.now
31
+ end_of_day = t.end_of_day
32
+ end_whole_sec = t.end_of_day_whole_sec
33
+ assert_equal 0.0, end_whole_sec.usec
34
+ assert_equal end_of_day.to_i, end_whole_sec.to_i
35
+ assert_equal end_of_day.sec, end_whole_sec.sec
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
- require File.expand_path('../../test_helper', __FILE__)
1
+ require_relative ('../test_helper')
2
2
 
3
3
  class UtilsTest < Minitest::Test
4
4
  require 'invoca/utils'
5
- end
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invoca-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cary Penniman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-04 00:00:00.000000000 Z
11
+ date: 2018-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: tzinfo
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: A public collection of helpers used in multiple projects
126
140
  email:
127
141
  - cpenniman@invoca.com
@@ -130,15 +144,27 @@ extensions: []
130
144
  extra_rdoc_files: []
131
145
  files:
132
146
  - ".gitignore"
147
+ - ".ruby-version"
133
148
  - Gemfile
149
+ - Gemfile.lock
134
150
  - LICENSE.txt
135
151
  - README.md
136
152
  - Rakefile
137
153
  - invoca-utils.gemspec
138
154
  - lib/invoca/utils.rb
139
155
  - lib/invoca/utils/diff.rb
156
+ - lib/invoca/utils/guaranteed_utf8_string.rb
157
+ - lib/invoca/utils/http.rb
158
+ - lib/invoca/utils/map_compact.rb
159
+ - lib/invoca/utils/min_max.rb
160
+ - lib/invoca/utils/stable_sort.rb
161
+ - lib/invoca/utils/time.rb
140
162
  - lib/invoca/utils/version.rb
141
163
  - test/test_helper.rb
164
+ - test/unit/guaranteed_utf8_string_test.rb
165
+ - test/unit/map_compact_test.rb
166
+ - test/unit/stable_sort_test.rb
167
+ - test/unit/time_calculations_test.rb
142
168
  - test/unit/utils_test.rb
143
169
  homepage: ''
144
170
  licenses:
@@ -160,10 +186,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
186
  version: '0'
161
187
  requirements: []
162
188
  rubyforge_project:
163
- rubygems_version: 2.2.2
189
+ rubygems_version: 2.6.13
164
190
  signing_key:
165
191
  specification_version: 4
166
192
  summary: A public collection of helpers used in multiple projects
167
193
  test_files:
168
194
  - test/test_helper.rb
195
+ - test/unit/guaranteed_utf8_string_test.rb
196
+ - test/unit/map_compact_test.rb
197
+ - test/unit/stable_sort_test.rb
198
+ - test/unit/time_calculations_test.rb
169
199
  - test/unit/utils_test.rb