olag 0.1.16 → 0.1.17

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.
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ 2012-01-15 Oren Ben-Kiki <github-oren@ben-kiki.org>
2
+
3
+ * Add WithTempdir mix-in module.
4
+
1
5
  2012-01-07 Oren Ben-Kiki <github-oren@ben-kiki.org>
2
6
 
3
7
  * Improve HAskell configuration comment.
@@ -2025,7 +2025,7 @@ number of Git commits by running <tt>rake version</tt>.
2025
2025
  </tr>
2026
2026
  </table>
2027
2027
  <pre class='ruby code syntax'>
2028
- <span class="Type">VERSION</span> = <span class="Special">&quot;</span><span class="Constant">0.1.16</span><span class="Special">&quot;</span>
2028
+ <span class="Type">VERSION</span> = <span class="Special">&quot;</span><span class="Constant">0.1.17</span><span class="Special">&quot;</span>
2029
2029
 
2030
2030
  end
2031
2031
  </pre>
@@ -2725,6 +2725,274 @@ end
2725
2725
  </div>
2726
2726
  </div>
2727
2727
  </p>
2728
+ <h3>Sorting Hash tables YAML keys</h3>
2729
+ <p>
2730
+ In order to get deterministic test results, and for general
2731
+ hukman-friendlyness, it is often desirable to sort hash table keys when dumping
2732
+ it to YAML. In Ruby 1.8.x, this isn't the default. It is possible to introduce
2733
+ this behavior using the following hack:
2734
+ </p>
2735
+ <p>
2736
+ <div class="named_with_containers chunk">
2737
+ <div class="chunk name">
2738
+ <a name="lib-olag-hash-sorted-yaml-rb">
2739
+ <span>lib/olag/hash_sorted_yaml.rb</span>
2740
+ </a>
2741
+ </div>
2742
+ <div class="chunk html">
2743
+ <pre class='ruby code syntax'>
2744
+ <span class="PreProc">require</span> <span class="Special">&quot;</span><span class="Constant">yaml</span><span class="Special">&quot;</span>
2745
+
2746
+ <span class="Statement">if</span> <span class="Identifier">RUBY_VERSION</span>.include?(<span class="Special">&quot;</span><span class="Constant">1.8</span><span class="Special">&quot;</span>)
2747
+
2748
+ </pre>
2749
+ <table class='layout'>
2750
+ <tr>
2751
+ <td class='indentation'>
2752
+ <pre> </pre>
2753
+ </td>
2754
+ <td class='html'>
2755
+ <div class='rdoc comment markup'>
2756
+ <p>
2757
+ Modify the hash class to emit YAML sorted keys. This is an ugly hack,
2758
+ specifically for Ruby 1.8.*.
2759
+ </p>
2760
+ </div>
2761
+ </td>
2762
+ </tr>
2763
+ </table>
2764
+ <pre class='ruby code syntax'>
2765
+ <span class="PreProc">class</span> <span class="Type">Hash</span>
2766
+
2767
+ </pre>
2768
+ <table class='layout'>
2769
+ <tr>
2770
+ <td class='indentation'>
2771
+ <pre> </pre>
2772
+ </td>
2773
+ <td class='html'>
2774
+ <div class='rdoc comment markup'>
2775
+ <p>
2776
+ Provide access to the old, unsorted implementation.
2777
+ </p>
2778
+ </div>
2779
+ </td>
2780
+ </tr>
2781
+ </table>
2782
+ <pre class='ruby code syntax'>
2783
+ <span class="PreProc">alias</span> <span class="Constant">:unsorted_to_yaml</span> <span class="Constant">:to_yaml</span>
2784
+
2785
+ </pre>
2786
+ <table class='layout'>
2787
+ <tr>
2788
+ <td class='indentation'>
2789
+ <pre> </pre>
2790
+ </td>
2791
+ <td class='html'>
2792
+ <div class='rdoc comment markup'>
2793
+ <p>
2794
+ Return the hash in YAML format with sorted keys.
2795
+ </p>
2796
+ </div>
2797
+ </td>
2798
+ </tr>
2799
+ </table>
2800
+ <pre class='ruby code syntax'>
2801
+ <span class="PreProc">def</span> <span class="Identifier">to_yaml</span>(opts = {})
2802
+ <span class="Type">YAML</span>::quick_emit(<span class="Constant">self</span>, opts) <span class="Statement">do</span> |<span class="Identifier">out</span>|
2803
+ out.map(taguri, to_yaml_style) <span class="Statement">do</span> |<span class="Identifier">map</span>|
2804
+ to_yaml_sorted_keys.each <span class="Statement">do</span> |<span class="Identifier">key</span>|
2805
+ map.add(key, fetch(key))
2806
+ <span class="Statement">end</span>
2807
+ <span class="Statement">end</span>
2808
+ <span class="Statement">end</span>
2809
+ <span class="PreProc">end</span>
2810
+
2811
+ </pre>
2812
+ <table class='layout'>
2813
+ <tr>
2814
+ <td class='indentation'>
2815
+ <pre> </pre>
2816
+ </td>
2817
+ <td class='html'>
2818
+ <div class='rdoc comment markup'>
2819
+ <p>
2820
+ Return the hash keys, sorted for emitting into YAML.
2821
+ </p>
2822
+ </div>
2823
+ </td>
2824
+ </tr>
2825
+ </table>
2826
+ <pre class='ruby code syntax'>
2827
+ <span class="PreProc">def</span> <span class="Identifier">to_yaml_sorted_keys</span>
2828
+ <span class="Statement">begin</span>
2829
+ <span class="Statement">return</span> keys.sort
2830
+ <span class="Statement">rescue</span>
2831
+ <span class="Statement">return</span> to_yaml_lexicographically_sorted_keys
2832
+ <span class="Statement">end</span>
2833
+ <span class="PreProc">end</span>
2834
+
2835
+ </pre>
2836
+ <table class='layout'>
2837
+ <tr>
2838
+ <td class='indentation'>
2839
+ <pre> </pre>
2840
+ </td>
2841
+ <td class='html'>
2842
+ <div class='rdoc comment markup'>
2843
+ <p>
2844
+ Return the hash keys, sorted lexicographically for emitting into YAML.
2845
+ </p>
2846
+ </div>
2847
+ </td>
2848
+ </tr>
2849
+ </table>
2850
+ <pre class='ruby code syntax'>
2851
+ <span class="PreProc">def</span> <span class="Identifier">to_yaml_lexicographically_sorted_keys</span>
2852
+ <span class="Statement">begin</span>
2853
+ <span class="Statement">return</span> keys.sort_by {|<span class="Identifier">key</span>| key.to_s}
2854
+ <span class="Statement">rescue</span>
2855
+ <span class="Statement">return</span> keys
2856
+ <span class="Statement">end</span>
2857
+ <span class="PreProc">end</span>
2858
+
2859
+ end
2860
+
2861
+ end
2862
+ </pre>
2863
+ </div>
2864
+ </div>
2865
+ </p>
2866
+ <p>
2867
+ Here is a simple test demonstrating using it:
2868
+ </p>
2869
+ <p>
2870
+ <div class="named_with_containers chunk">
2871
+ <div class="chunk name">
2872
+ <a name="test-sorted-keys-rb">
2873
+ <span>test/sorted_keys.rb</span>
2874
+ </a>
2875
+ </div>
2876
+ <div class="chunk html">
2877
+ <pre class='ruby code syntax'>
2878
+ <span class="PreProc">require</span> <span class="Special">&quot;</span><span class="Constant">olag/hash_sorted_yaml</span><span class="Special">&quot;</span>
2879
+ <span class="PreProc">require</span> <span class="Special">&quot;</span><span class="Constant">test/spec</span><span class="Special">&quot;</span>
2880
+
2881
+ </pre>
2882
+ <table class='layout'>
2883
+ <tr>
2884
+ <td class='indentation'>
2885
+ <pre></pre>
2886
+ </td>
2887
+ <td class='html'>
2888
+ <div class='rdoc comment markup'>
2889
+ <p>
2890
+ An uncomparable class. Keys of this class will cause the Hash to be emitted
2891
+ in string sort order.
2892
+ </p>
2893
+ </div>
2894
+ </td>
2895
+ </tr>
2896
+ </table>
2897
+ <pre class='ruby code syntax'>
2898
+ <span class="PreProc">class</span> <span class="Type">Uncomparable</span>
2899
+
2900
+ <span class="PreProc">def</span> <span class="Identifier">initialize</span>(value)
2901
+ <span class="Identifier">@value</span> = value
2902
+ <span class="PreProc">end</span>
2903
+
2904
+ <span class="PreProc">def</span> <span class="Identifier">to_yaml</span>(opts = {})
2905
+ <span class="Statement">return</span> <span class="Identifier">@value</span>.to_yaml(opts)
2906
+ <span class="PreProc">end</span>
2907
+
2908
+ <span class="PreProc">def</span> <span class="Identifier">to_s</span>
2909
+ <span class="Statement">return</span> <span class="Identifier">@value</span>.to_s
2910
+ <span class="PreProc">end</span>
2911
+
2912
+ <span class="Special">%w(</span><span class="Constant">&lt;=&gt; &lt; &lt;= &gt;= &gt;</span><span class="Special">)</span>.each <span class="Statement">do</span> |<span class="Identifier">operator</span>|
2913
+ define_method(operator) { <span class="Statement">raise</span> <span class="Special">&quot;</span><span class="Constant">Prevent operator: </span><span class="Special">#{</span>operator<span class="Special">}</span><span class="Special">&quot;</span> }
2914
+ <span class="Statement">end</span>
2915
+
2916
+ <span class="PreProc">end</span>
2917
+
2918
+ </pre>
2919
+ <table class='layout'>
2920
+ <tr>
2921
+ <td class='indentation'>
2922
+ <pre></pre>
2923
+ </td>
2924
+ <td class='html'>
2925
+ <div class='rdoc comment markup'>
2926
+ <p>
2927
+ An uncomparable class that can’t be converted to a string. Keys of this
2928
+ class will cause the Hash to be emitted in unsorted order.
2929
+ </p>
2930
+ </div>
2931
+ </td>
2932
+ </tr>
2933
+ </table>
2934
+ <pre class='ruby code syntax'>
2935
+ <span class="PreProc">class</span> <span class="Type">Unsortable</span> &lt; <span class="Type">Uncomparable</span>
2936
+
2937
+ <span class="PreProc">def</span> <span class="Identifier">to_s</span>
2938
+ <span class="Statement">raise</span> <span class="Special">&quot;</span><span class="Constant">Prevent conversion to string as well.</span><span class="Special">&quot;</span>
2939
+ <span class="PreProc">end</span>
2940
+
2941
+ <span class="PreProc">end</span>
2942
+
2943
+ </pre>
2944
+ <table class='layout'>
2945
+ <tr>
2946
+ <td class='indentation'>
2947
+ <pre></pre>
2948
+ </td>
2949
+ <td class='html'>
2950
+ <div class='rdoc comment markup'>
2951
+ <p>
2952
+ Test sorting keys of YAML generated from Hash tables.
2953
+ </p>
2954
+ </div>
2955
+ </td>
2956
+ </tr>
2957
+ </table>
2958
+ <pre class='ruby code syntax'>
2959
+ <span class="PreProc">class</span> <span class="Type">TestSortedKeys</span> &lt; ::<span class="Type">Test</span>::<span class="Type">Unit</span>::<span class="Type">TestCase</span>
2960
+
2961
+ <span class="Type">SORTED_NUMERICALLY</span> = &lt;&lt;-<span class="Special">EOF</span>.unindent
2962
+ <span class="Constant"> ---</span>
2963
+ <span class="Constant"> 2: 2</span>
2964
+ <span class="Constant"> 4: 4</span>
2965
+ <span class="Constant"> 11: 1</span>
2966
+ <span class="Constant"> 33: 3</span>
2967
+ <span class="Constant"> </span><span class="Special">EOF</span>
2968
+
2969
+ <span class="Type">SORTED_LEXICOGRAPHICALLY</span> = &lt;&lt;-<span class="Special">EOF</span>.unindent
2970
+ <span class="Constant"> ---</span>
2971
+ <span class="Constant"> 11: 1</span>
2972
+ <span class="Constant"> 2: 2</span>
2973
+ <span class="Constant"> 33: 3</span>
2974
+ <span class="Constant"> 4: 4</span>
2975
+ <span class="Constant"> </span><span class="Special">EOF</span>
2976
+
2977
+ <span class="PreProc">def</span> <span class="Identifier">test_sortable_keys</span>
2978
+ { <span class="Constant">2</span> =&gt; <span class="Constant">2</span>, <span class="Constant">4</span> =&gt; <span class="Constant">4</span>, <span class="Constant">11</span> =&gt; <span class="Constant">1</span>, <span class="Constant">33</span> =&gt; <span class="Constant">3</span> }.to_yaml.gsub(<span class="Special">/</span><span class="Constant"> </span><span class="Special">+</span><span class="Special">$</span><span class="Special">/</span>, <span class="Special">&quot;&quot;</span>).should == <span class="Type">SORTED_NUMERICALLY</span>
2979
+ <span class="PreProc">end</span>
2980
+
2981
+ <span class="PreProc">def</span> <span class="Identifier">test_uncomparable_keys</span>
2982
+ { <span class="Type">Uncomparable</span>.new(<span class="Constant">11</span>) =&gt; <span class="Constant">1</span>, <span class="Constant">2</span> =&gt; <span class="Constant">2</span>, <span class="Constant">33</span> =&gt; <span class="Constant">3</span>, <span class="Constant">4</span> =&gt; <span class="Constant">4</span> }.to_yaml.gsub(<span class="Special">/</span><span class="Constant"> </span><span class="Special">+</span><span class="Special">$</span><span class="Special">/</span>, <span class="Special">&quot;&quot;</span>).should == <span class="Type">SORTED_LEXICOGRAPHICALLY</span>
2983
+ <span class="PreProc">end</span>
2984
+
2985
+ <span class="PreProc">def</span> <span class="Identifier">test_unsortable_keys</span>
2986
+ yaml_should_not = { <span class="Type">Unsortable</span>.new(<span class="Constant">11</span>) =&gt; <span class="Constant">1</span>, <span class="Constant">2</span> =&gt; <span class="Constant">2</span>, <span class="Constant">33</span> =&gt; <span class="Constant">3</span>, <span class="Constant">4</span> =&gt; <span class="Constant">4</span> }.to_yaml.gsub(<span class="Special">/</span><span class="Constant"> </span><span class="Special">+</span><span class="Special">$</span><span class="Special">/</span>, <span class="Special">&quot;&quot;</span>).should.not
2987
+ yaml_should_not == <span class="Type">SORTED_NUMERICALLY</span>
2988
+ yaml_should_not == <span class="Type">SORTED_LEXICOGRAPHICALLY</span>
2989
+ <span class="PreProc">end</span>
2990
+
2991
+ <span class="PreProc">end</span>
2992
+ </pre>
2993
+ </div>
2994
+ </div>
2995
+ </p>
2728
2996
  <h3>Collecting errors</h3>
2729
2997
  <p>
2730
2998
  In library code, it is bad practice to terminate the program on an error.
@@ -197,6 +197,19 @@ And here is the implementation:
197
197
 
198
198
  [[lib/olag/hash_struct.rb|named_chunk_with_containers]]
199
199
 
200
+ ### Sorting Hash tables YAML keys ###
201
+
202
+ In order to get deterministic test results, and for general
203
+ hukman-friendlyness, it is often desirable to sort hash table keys when dumping
204
+ it to YAML. In Ruby 1.8.x, this isn't the default. It is possible to introduce
205
+ this behavior using the following hack:
206
+
207
+ [[lib/olag/hash_sorted_yaml.rb|named_chunk_with_containers]]
208
+
209
+ Here is a simple test demonstrating using it:
210
+
211
+ [[test/sorted_keys.rb|named_chunk_with_containers]]
212
+
200
213
  ### Collecting errors ###
201
214
 
202
215
  In library code, it is bad practice to terminate the program on an error.
@@ -0,0 +1,43 @@
1
+ require "yaml"
2
+
3
+ if RUBY_VERSION.include?("1.8")
4
+
5
+ # Modify the hash class to emit YAML sorted keys. This is an ugly hack,
6
+ # specifically for Ruby 1.8.*.
7
+ class Hash
8
+
9
+ # Provide access to the old, unsorted implementation.
10
+ alias :unsorted_to_yaml :to_yaml
11
+
12
+ # Return the hash in YAML format with sorted keys.
13
+ def to_yaml(opts = {})
14
+ YAML::quick_emit(self, opts) do |out|
15
+ out.map(taguri, to_yaml_style) do |map|
16
+ to_yaml_sorted_keys.each do |key|
17
+ map.add(key, fetch(key))
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ # Return the hash keys, sorted for emitting into YAML.
24
+ def to_yaml_sorted_keys
25
+ begin
26
+ return keys.sort
27
+ rescue
28
+ return to_yaml_lexicographically_sorted_keys
29
+ end
30
+ end
31
+
32
+ # Return the hash keys, sorted lexicographically for emitting into YAML.
33
+ def to_yaml_lexicographically_sorted_keys
34
+ begin
35
+ return keys.sort_by {|key| key.to_s}
36
+ rescue
37
+ return keys
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -3,6 +3,6 @@ module Olag
3
3
 
4
4
  # This version number. The third number is automatically updated to track the
5
5
  # number of Git commits by running <tt>rake version</tt>.
6
- VERSION = "0.1.16"
6
+ VERSION = "0.1.17"
7
7
 
8
8
  end
@@ -0,0 +1,69 @@
1
+ require "olag/hash_sorted_yaml"
2
+ require "test/spec"
3
+
4
+ # An uncomparable class. Keys of this class will cause the Hash to be emitted
5
+ # in string sort order.
6
+ class Uncomparable
7
+
8
+ def initialize(value)
9
+ @value = value
10
+ end
11
+
12
+ def to_yaml(opts = {})
13
+ return @value.to_yaml(opts)
14
+ end
15
+
16
+ def to_s
17
+ return @value.to_s
18
+ end
19
+
20
+ %w(<=> < <= >= >).each do |operator|
21
+ define_method(operator) { raise "Prevent operator: #{operator}" }
22
+ end
23
+
24
+ end
25
+
26
+ # An uncomparable class that can't be converted to a string. Keys of this class
27
+ # will cause the Hash to be emitted in unsorted order.
28
+ class Unsortable < Uncomparable
29
+
30
+ def to_s
31
+ raise "Prevent conversion to string as well."
32
+ end
33
+
34
+ end
35
+
36
+ # Test sorting keys of YAML generated from Hash tables.
37
+ class TestSortedKeys < ::Test::Unit::TestCase
38
+
39
+ SORTED_NUMERICALLY = <<-EOF.unindent
40
+ ---
41
+ 2: 2
42
+ 4: 4
43
+ 11: 1
44
+ 33: 3
45
+ EOF
46
+
47
+ SORTED_LEXICOGRAPHICALLY = <<-EOF.unindent
48
+ ---
49
+ 11: 1
50
+ 2: 2
51
+ 33: 3
52
+ 4: 4
53
+ EOF
54
+
55
+ def test_sortable_keys
56
+ { 2 => 2, 4 => 4, 11 => 1, 33 => 3 }.to_yaml.gsub(/ +$/, "").should == SORTED_NUMERICALLY
57
+ end
58
+
59
+ def test_uncomparable_keys
60
+ { Uncomparable.new(11) => 1, 2 => 2, 33 => 3, 4 => 4 }.to_yaml.gsub(/ +$/, "").should == SORTED_LEXICOGRAPHICALLY
61
+ end
62
+
63
+ def test_unsortable_keys
64
+ yaml_should_not = { Unsortable.new(11) => 1, 2 => 2, 33 => 3, 4 => 4 }.to_yaml.gsub(/ +$/, "").should.not
65
+ yaml_should_not == SORTED_NUMERICALLY
66
+ yaml_should_not == SORTED_LEXICOGRAPHICALLY
67
+ end
68
+
69
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: olag
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
4
+ hash: 57
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 16
10
- version: 0.1.16
9
+ - 17
10
+ version: 0.1.17
11
11
  platform: ruby
12
12
  authors:
13
13
  - Oren Ben-Kiki
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-15 00:00:00 Z
18
+ date: 2012-01-17 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: Saikuro
@@ -174,6 +174,7 @@ files:
174
174
  - lib/olag/errors.rb
175
175
  - lib/olag/gem_specification.rb
176
176
  - lib/olag/globals.rb
177
+ - lib/olag/hash_sorted_yaml.rb
177
178
  - lib/olag/hash_struct.rb
178
179
  - lib/olag/rake.rb
179
180
  - lib/olag/string_unindent.rb
@@ -193,6 +194,7 @@ files:
193
194
  - test/collect_errors.rb
194
195
  - test/missing_keys.rb
195
196
  - test/run_application.rb
197
+ - test/sorted_keys.rb
196
198
  - test/unindent_text.rb
197
199
  - README.rdoc
198
200
  - LICENSE
@@ -203,7 +205,7 @@ licenses: []
203
205
  post_install_message:
204
206
  rdoc_options:
205
207
  - --title
206
- - Olag 0.1.16
208
+ - Olag 0.1.17
207
209
  - --main
208
210
  - README.rdoc
209
211
  - --line-numbers
@@ -241,4 +243,5 @@ test_files:
241
243
  - test/collect_errors.rb
242
244
  - test/missing_keys.rb
243
245
  - test/run_application.rb
246
+ - test/sorted_keys.rb
244
247
  - test/unindent_text.rb