more_ruby 0.2.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b1771efb7dc83fea53e24b2d7b5a2f67fa7d1e2cdca9dec76ef81ad09817c30
4
- data.tar.gz: 46a7e965a7449f3f6e0258f355e414cc2f537ad8f2c2284f06a63fddf515e26b
3
+ metadata.gz: 216485758b0badb8831ccff9952d5f05a8dc2dd96820d3fe378daf544fb07a3b
4
+ data.tar.gz: 41bcb4b845d8961f738da3c316c38fe9cfc855b3fe2c5561c4cf3b92fcd14a82
5
5
  SHA512:
6
- metadata.gz: 6a8b12b7cf3c75568bfbce46433e6b07e315524ffb34d2b37bdf2f3cae73c0919e2f075f9425a88cd55638caa76e85928c04dcb02a42f1503a173dafaba15012
7
- data.tar.gz: 3ad555c95b8f5c8512a6b24522dea8b434539584ecb237c66e56ad9154f26863a168fc16b55df38275cace7ac8e248ca9648e7587c776599ed6f0b0c2cc6aea8
6
+ metadata.gz: f1f9392fef5750e502ab0dfe956e1f9c2fc4d2eebd8debc19d38b8b121052dcfb8eaa9bc62fa02600bef57ec7f89abfc2a868754394f1b114db33c34e5fd6c6f
7
+ data.tar.gz: f24a25df5c7c650cc3ec62d749c6844908b8dfa0c48aa409fe9e1eb1f0e9279453bc2a97380c4565f65aca32b67d69900e9f030760ae95e29e642f402f5ed34c
data/README.md CHANGED
@@ -26,7 +26,7 @@ Simply require the gem ( require "more_ruby" ) and the additional methods will b
26
26
  :format_with_thousands_delimiter
27
27
 
28
28
  ## String
29
- :append, :camelcase, :camelcase_to_snakecase, :capitalize_all, :capitalize_first_letter_only, :escape, :escape_whitespace, :extract_values_from_xml_string, :formatted_number, :index_of_last_capital, :invert_case, :is_hex?, :is_integer?, :join, :pascalcase, :prefix_lines, :random_case, :snakecase, :snakecase_and_downcase, :to_bool, :unindent
29
+ :append, :camelcase, :capitalize_all, :capitalize_first_letter_only, :escape, :escape_whitespace, :extract_values_from_xml_string, :formatted_number, :index_of_last_capital, :invert_case, :is_hex?, :is_integer?, :join, :pascalcase, :prefix_lines, :random_case, :snakecase, :snakecase_and_downcase, :snakecase_non_alpha, :to_bool, :unindent
30
30
 
31
31
  ## Time
32
32
  :is_after?, :is_before?, :is_within?, :remove_subseconds
@@ -59,14 +59,13 @@ class String
59
59
  self.size - reverse_index - 1
60
60
  end
61
61
 
62
- def snakecase
62
+ # Changes every sequence of non-alpha-numeric characters to underscores
63
+ # If you want to convert something looking like camelcase to snakecase,
64
+ # use snakecase
65
+ def snakecase_non_alpha
63
66
  gsub(/[^a-zA-Z0-9]+/, '_')
64
67
  end
65
68
 
66
- def snakecase_and_downcase
67
- downcase.snakecase
68
- end
69
-
70
69
  # Like camelcase but with the first letter also capitalised
71
70
  # Pascalcase is C#'s case convention
72
71
  def pascalcase
@@ -79,27 +78,103 @@ class String
79
78
  end
80
79
 
81
80
  # Converts aStringInCamelCase to a_string_in_camel_case
82
- def camelcase_to_snakecase
81
+ # Also converts SomeStringInPascalCase to some_string_in_pascal_case
82
+ #a << {:raw => "thiNGS-with_stuff", :expected => "thi_ngs_with_stuff"}
83
+ def snakecase
84
+ # Notes :
85
+ # If the entire string contains only uppercase (with or without underscores), return it as it is
86
+ if self =~ /^[A-Z_]+$/
87
+ return self
88
+ end
89
+
90
+ # If the entire string contains only uppercase and numbers, AND has underscores, return it as it is
91
+ # REQ_ID2 -> REQ_ID2 ; REQID2 should not -> REQID2
92
+ if self =~ /^[A-Z0-9_]+$/ && self.include?("_")
93
+ return self
94
+ end
95
+
83
96
  a = []
84
97
 
85
- self =~ /(^[a-z]+)/
86
- a << $1 if $1
87
-
88
- m = self.scan /([A-Z]+[a-z0-9]*)/
89
- m.flatten!
90
- m.each do |fragment|
91
- fragment =~ /([A-Z]+[a-z0-9]*)/
92
- caps = $1
93
- lower = $2
94
- if caps.size > 1
95
- s = "_#{caps.downcase}"
96
- a << s
97
- caps = "" # set to empty string so that the below caps.downcase still works
98
+ before = self.snakecase_non_alpha
99
+ parts = before.split("_")
100
+
101
+ # Process each part, then stitch them back together
102
+ # Each part might itself contain several 'camel humps'
103
+ # Each fragment within each part might be of different 'format'
104
+
105
+ parts.each do |part|
106
+ # If the part is already all lowercase, keep it and move on to the next part
107
+ part =~ /^([a-z0-9]+)$/
108
+ if $1
109
+ a << $1
110
+ next
98
111
  end
99
- s = "_#{caps.downcase}#{lower}"
100
- a << s unless s == "_"
101
- end
102
- a.join
112
+
113
+ # ABC -> ABC # if all capitals, leave it as it is
114
+ # If the part is already all uppercase, keep it and move on to the next part
115
+ part =~ /^([A-Z]+)$/
116
+ if $1
117
+ a << $1
118
+ next
119
+ end
120
+
121
+ #
122
+ # The part contains 'camel humps', which need to be processed
123
+ #
124
+
125
+ # Make sure to preserve the leading part of the string before the first 'hump'
126
+ part =~ /^([a-z0-9]+)([A-Z])/
127
+ if $1
128
+ a << $1
129
+ end
130
+
131
+ # This scan-regex will only match from the first 'hump' onwards
132
+ fragments = part.scan /([A-Z]+[a-z0-9]*)/
133
+ fragments.flatten!
134
+ fragments.each do |fragment|
135
+
136
+ # ABCD -> abcd
137
+ fragment =~ /^([A-Z]+)$/
138
+ if $1
139
+ a << $1.downcase
140
+ next
141
+ end
142
+
143
+ # ABCD1234 -> abcd_1234
144
+ fragment =~ /^([A-Z]+)([0-9]+)$/
145
+ if $1
146
+ a << $1.downcase
147
+ a << $2
148
+ next
149
+ end
150
+
151
+ # Abc -> abc
152
+ fragment =~ /^([A-Z][a-z0-9]*)$/
153
+ if $1
154
+ a << $1.downcase
155
+ next
156
+ end
157
+
158
+ # ABCDef -> abc_def
159
+ fragment =~ /^([A-Z]+)([A-Z][a-z0-9]*)$/
160
+ if $1
161
+ a << $1.downcase
162
+ a << $2.downcase
163
+ next
164
+ end
165
+
166
+ end # end fragments
167
+ end # end parts
168
+ s = a.join("_")
169
+
170
+ # Final tidying
171
+ s.gsub!(/[_]+/, "_") # replace continuous underscores with one underscore
172
+ s = s[1 .. -1] if s[0] == "_" # a pascalcase string will cause a leading underscore, which we need to remove
173
+ s
174
+ end
175
+
176
+ def snakecase_and_downcase
177
+ self.snakecase.downcase
103
178
  end
104
179
 
105
180
  def append(s)
data/test/test_string.rb CHANGED
@@ -38,7 +38,7 @@ class TestString < Test::Unit::TestCase
38
38
  assert_nil(re =~ e, ".escape yielded an escaped string that matched its Regexp object")
39
39
  end
40
40
 
41
- def test_snakecase
41
+ def test_snakecase_non_alpha
42
42
  a = []
43
43
  a << {:raw => "thiNGS", :expected => "thiNGS"}
44
44
  a << {:raw => "thiNGS-with_stuff", :expected => "thiNGS_with_stuff"}
@@ -46,22 +46,33 @@ class TestString < Test::Unit::TestCase
46
46
  a << {:raw => "th2i<>n!!!gs", :expected => "th2i_n_gs"}
47
47
 
48
48
  a.each do |x|
49
- actual = x[:raw].snakecase
50
- assert_equal(actual, x[:expected], ".snakecase didn't work properly")
49
+ actual = x[:raw].snakecase_non_alpha
50
+ assert_equal(x[:expected], actual, ".snakecase_non_alpha didn't work properly")
51
51
  end
52
52
 
53
53
  end
54
54
 
55
- def test_snakecase_and_downcase
55
+ def test_snakecase
56
56
  a = []
57
- a << {:raw => "thiNGS", :expected => "things"}
58
- a << {:raw => "thiNGS-with_stuff", :expected => "things_with_stuff"}
57
+ a << {:raw => "things", :expected => "things"}
58
+ a << {:raw => "THINGS", :expected => "THINGS"} # should stay the same if all uppercase
59
+ a << {:raw => "REQ_ID", :expected => "REQ_ID"} # should stay the same if all uppercase
60
+ a << {:raw => "REQ_ID2", :expected => "REQ_ID2"}
61
+ a << {:raw => "REQID2", :expected => "reqid_2"}
62
+ a << {:raw => "req_ID", :expected => "req_ID"}
63
+ a << {:raw => "reqID", :expected => "req_id"}
64
+ a << {:raw => "reqId", :expected => "req_id"}
65
+ a << {:raw => "thi_ngs_yes", :expected => "thi_ngs_yes"}
66
+ a << {:raw => "thiNGSYes", :expected => "thi_ngs_yes"}
67
+ a << {:raw => "thiNGS", :expected => "thi_ngs"}
68
+ a << {:raw => "thiNGS-with_stuff", :expected => "thi_ngs_with_stuff"}
59
69
  a << {:raw => "thi--_-ngs", :expected => "thi_ngs"}
60
70
  a << {:raw => "th2i<>n!!!gs", :expected => "th2i_n_gs"}
71
+ a << {:raw => "THINGS1234STUFF5678", :expected => "things_1234_stuff_5678"}
61
72
 
62
73
  a.each do |x|
63
- actual = x[:raw].snakecase_and_downcase
64
- assert_equal(actual, x[:expected], "snakecase_and_downcase didn't work properly")
74
+ actual = x[:raw].snakecase
75
+ assert_equal(x[:expected], actual, "snakecase didn't work properly")
65
76
  end
66
77
 
67
78
  end
@@ -95,7 +106,7 @@ class TestString < Test::Unit::TestCase
95
106
 
96
107
  a.each do |x|
97
108
  actual = x[:raw].camelcase
98
- assert_equal( x[:expected], actual, ".camelcase didn't work properly")
109
+ assert_equal(x[:expected], actual, ".camelcase didn't work properly")
99
110
  end
100
111
 
101
112
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: more_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Morrisby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-04 00:00:00.000000000 Z
11
+ date: 2019-06-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " A very simple gem that adds some methods to some Ruby standard classes,
14
14
  e.g. <array>.include_any?, <array>.delete_random, etc.\n\n Simply require the gem