aipp 0.2.5 → 0.2.6
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +8 -0
- data/README.md +40 -14
- data/exe/aip2aixm +1 -1
- data/exe/aip2ofmx +1 -1
- data/lib/aipp.rb +2 -0
- data/lib/aipp/aip.rb +17 -12
- data/lib/aipp/downloader.rb +1 -1
- data/lib/aipp/executable.rb +15 -12
- data/lib/aipp/parser.rb +58 -43
- data/lib/aipp/pdf.rb +1 -1
- data/lib/aipp/regions/LF/AD-1.3.rb +7 -6
- data/lib/aipp/regions/LF/AD-1.6.rb +7 -5
- data/lib/aipp/regions/LF/AD-2.rb +16 -9
- data/lib/aipp/regions/LF/AD-3.1.rb +6 -6
- data/lib/aipp/regions/LF/ENR-2.1.rb +81 -6
- data/lib/aipp/regions/LF/ENR-4.1.rb +3 -1
- data/lib/aipp/regions/LF/ENR-4.3.rb +2 -3
- data/lib/aipp/regions/LF/ENR-5.1.rb +15 -2
- data/lib/aipp/regions/LF/ENR-5.4.rb +90 -0
- data/lib/aipp/regions/LF/ENR-5.5.rb +12 -10
- data/lib/aipp/regions/LF/fixtures/AD-1.3.yml +2 -2
- data/lib/aipp/regions/LF/helpers/base.rb +17 -9
- data/lib/aipp/regions/LF/helpers/radio_AD.rb +21 -13
- data/lib/aipp/t_hash.rb +3 -3
- data/lib/aipp/version.rb +1 -1
- data/lib/core_ext/enumerable.rb +7 -7
- data/lib/core_ext/string.rb +9 -4
- metadata +156 -168
- metadata.gz.sig +1 -0
- data/.github/workflows/test.yml +0 -26
- data/.gitignore +0 -8
- data/.ruby-version +0 -1
- data/.yardopts +0 -3
- data/Guardfile +0 -7
- data/TODO.md +0 -6
- data/aipp.gemspec +0 -45
- data/gems.rb +0 -3
- data/rakefile.rb +0 -12
- data/spec/fixtures/border.geojson +0 -201
- data/spec/fixtures/document.pdf +0 -0
- data/spec/fixtures/document.pdf.json +0 -1
- data/spec/fixtures/new.html +0 -6
- data/spec/fixtures/new.pdf +0 -0
- data/spec/fixtures/new.txt +0 -1
- data/spec/fixtures/source.zip +0 -0
- data/spec/lib/aipp/airac_spec.rb +0 -98
- data/spec/lib/aipp/border_spec.rb +0 -135
- data/spec/lib/aipp/downloader_spec.rb +0 -81
- data/spec/lib/aipp/patcher_spec.rb +0 -46
- data/spec/lib/aipp/pdf_spec.rb +0 -124
- data/spec/lib/aipp/t_hash_spec.rb +0 -44
- data/spec/lib/aipp/version_spec.rb +0 -7
- data/spec/lib/core_ext/enumberable_spec.rb +0 -76
- data/spec/lib/core_ext/hash_spec.rb +0 -27
- data/spec/lib/core_ext/integer_spec.rb +0 -15
- data/spec/lib/core_ext/nil_class_spec.rb +0 -11
- data/spec/lib/core_ext/string_spec.rb +0 -112
- data/spec/sounds/failure.mp3 +0 -0
- data/spec/sounds/success.mp3 +0 -0
- data/spec/spec_helper.rb +0 -29
| @@ -1,135 +0,0 @@ | |
| 1 | 
            -
            require_relative '../../spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            describe AIPP::Border::Position do
         | 
| 4 | 
            -
              subject do
         | 
| 5 | 
            -
                AIPP::Border::Position.new(
         | 
| 6 | 
            -
                  geometries: [
         | 
| 7 | 
            -
                    [AIXM.xy(long: 0, lat: 0), AIXM.xy(long: 1, lat: 1), AIXM.xy(long: 2, lat: 2)],
         | 
| 8 | 
            -
                    [AIXM.xy(long: 10, lat: 10), AIXM.xy(long: 11, lat: 11), AIXM.xy(long: 12, lat: 12)]
         | 
| 9 | 
            -
                  ],
         | 
| 10 | 
            -
                  geometry_index: 0,
         | 
| 11 | 
            -
                  coordinates_index: 0
         | 
| 12 | 
            -
                )
         | 
| 13 | 
            -
              end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
              describe :xy do
         | 
| 16 | 
            -
                it "returns the coordinates" do
         | 
| 17 | 
            -
                  _(subject.xy).must_equal AIXM.xy(long: 0, lat: 0)
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                it "returns nil if the geometry index is out of bounds" do
         | 
| 21 | 
            -
                  _(subject.tap { |s| s.geometry_index = 2 }.xy).must_be_nil
         | 
| 22 | 
            -
                end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                it "returns nil if the coordinates index is out of bounds" do
         | 
| 25 | 
            -
                  _(subject.tap { |s| s.coordinates_index = 3 }.xy).must_be_nil
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
            end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            describe AIPP::Border do
         | 
| 31 | 
            -
              let :fixtures_dir do
         | 
| 32 | 
            -
                Pathname(__FILE__).join('..', '..', '..', 'fixtures')
         | 
| 33 | 
            -
              end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
              # The border.geojson fixture defines three geometries:
         | 
| 36 | 
            -
              # * index 0: closed geometry circumventing the airfield of Pujaut
         | 
| 37 | 
            -
              # * index 1: closed geometry circumventing the village of Pujaut
         | 
| 38 | 
            -
              # * index 2: unclosed I-shaped geometry following the TGV from the S to N bridges over the Rhône
         | 
| 39 | 
            -
              # * index 3: unclosed U-shaped geometry around Île de Bartelasse from N to S end of Pont Daladier
         | 
| 40 | 
            -
              subject do
         | 
| 41 | 
            -
                AIPP::Border.new(fixtures_dir.join('border.geojson'))
         | 
| 42 | 
            -
              end
         | 
| 43 | 
            -
             | 
| 44 | 
            -
              describe :initialize do
         | 
| 45 | 
            -
                it "fails for files unless the extension is .geojson" do
         | 
| 46 | 
            -
                  _{ AIPP::Border.new("/path/to/another.txt") }.must_raise ArgumentError
         | 
| 47 | 
            -
                end
         | 
| 48 | 
            -
              end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
              describe :name do
         | 
| 51 | 
            -
                it "returns the upcased file name" do
         | 
| 52 | 
            -
                  _(subject.name).must_equal 'BORDER'
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
              end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
              describe :closed? do
         | 
| 57 | 
            -
                it "returns true for closed geometries" do
         | 
| 58 | 
            -
                  _(subject.closed?(geometry_index: 0)).must_equal true
         | 
| 59 | 
            -
                  _(subject.closed?(geometry_index: 1)).must_equal true
         | 
| 60 | 
            -
                end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                it "returns false for unclosed geometries" do
         | 
| 63 | 
            -
                  _(subject.closed?(geometry_index: 2)).must_equal false
         | 
| 64 | 
            -
                  _(subject.closed?(geometry_index: 3)).must_equal false
         | 
| 65 | 
            -
                end
         | 
| 66 | 
            -
              end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
              describe :nearest do
         | 
| 69 | 
            -
                let :point do
         | 
| 70 | 
            -
                  AIXM.xy(lat: 44.008187986625636, long: 4.759397506713866)
         | 
| 71 | 
            -
                end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                it "finds the nearest position on any geometry" do
         | 
| 74 | 
            -
                  position = subject.nearest(xy: point)
         | 
| 75 | 
            -
                  _(position.geometry_index).must_equal 1
         | 
| 76 | 
            -
                  _(position.coordinates_index).must_equal 12
         | 
| 77 | 
            -
                  _(position.xy).must_equal AIXM.xy(lat: 44.01065725159039, long: 4.760427474975586)
         | 
| 78 | 
            -
                end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                it "finds the nearest postition on a given geometry" do
         | 
| 81 | 
            -
                  position = subject.nearest(xy: point, geometry_index: 0)
         | 
| 82 | 
            -
                  _(position.geometry_index).must_equal 0
         | 
| 83 | 
            -
                  _(position.coordinates_index).must_equal 2
         | 
| 84 | 
            -
                  _(position.xy).must_equal AIXM.xy(lat: 44.00269350325321, long: 4.7519731521606445)
         | 
| 85 | 
            -
                end
         | 
| 86 | 
            -
              end
         | 
| 87 | 
            -
             | 
| 88 | 
            -
              describe :segment do
         | 
| 89 | 
            -
                it "fails if positions are not on the same geometry" do
         | 
| 90 | 
            -
                  from_position = AIPP::Border::Position.new(geometries: subject.geometries, geometry_index: 0, coordinates_index: 0)
         | 
| 91 | 
            -
                  to_position = AIPP::Border::Position.new(geometries: subject.geometries, geometry_index: 1, coordinates_index: 0)
         | 
| 92 | 
            -
                  _{ subject.segment(from_position: from_position, to_position: to_position) }.must_raise ArgumentError
         | 
| 93 | 
            -
                end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                it "returns shortest segment on an unclosed I-shaped geometry" do
         | 
| 96 | 
            -
                  from_position = subject.nearest(xy: AIXM.xy(lat: 44.002940457248556, long: 4.734249114990234))
         | 
| 97 | 
            -
                  to_position = subject.nearest(xy: AIXM.xy(lat: 44.07155380033749, long: 4.7687530517578125), geometry_index: from_position.geometry_index)
         | 
| 98 | 
            -
                  _(subject.segment(from_position: from_position, to_position: to_position)).must_equal [
         | 
| 99 | 
            -
                    AIXM.xy(lat: 44.00516299694704, long: 4.7371673583984375),
         | 
| 100 | 
            -
                    AIXM.xy(lat: 44.02195282780904, long: 4.743347167968749),
         | 
| 101 | 
            -
                    AIXM.xy(lat: 44.037503870182896, long: 4.749870300292969),
         | 
| 102 | 
            -
                    AIXM.xy(lat: 44.05379106204314, long: 4.755706787109375),
         | 
| 103 | 
            -
                    AIXM.xy(lat: 44.070073775703484, long: 4.7646331787109375)
         | 
| 104 | 
            -
                  ]
         | 
| 105 | 
            -
                end
         | 
| 106 | 
            -
             | 
| 107 | 
            -
                it "returns shortest segment on an unclosed U-shaped geometry" do
         | 
| 108 | 
            -
                  from_position = subject.nearest(xy: AIXM.xy(lat: 43.96563876212758, long: 4.8126983642578125))
         | 
| 109 | 
            -
                  to_position = subject.nearest(xy: AIXM.xy(lat: 43.956989327857265, long: 4.83123779296875), geometry_index: from_position.geometry_index)
         | 
| 110 | 
            -
                  _(subject.segment(from_position: from_position, to_position: to_position)).must_equal [
         | 
| 111 | 
            -
                    AIXM.xy(lat: 43.9646503190861, long: 4.815788269042969),
         | 
| 112 | 
            -
                    AIXM.xy(lat: 43.98614524381678, long: 4.82025146484375),
         | 
| 113 | 
            -
                    AIXM.xy(lat: 43.98491011404692, long: 4.840850830078125),
         | 
| 114 | 
            -
                    AIXM.xy(lat: 43.99479043262446, long: 4.845314025878906),
         | 
| 115 | 
            -
                    AIXM.xy(lat: 43.98367495857784, long: 4.8538970947265625),
         | 
| 116 | 
            -
                    AIXM.xy(lat: 43.967121395851485, long: 4.851493835449218),
         | 
| 117 | 
            -
                    AIXM.xy(lat: 43.96069638244953, long: 4.8442840576171875),
         | 
| 118 | 
            -
                    AIXM.xy(lat: 43.96069638244953, long: 4.829521179199219)
         | 
| 119 | 
            -
                  ]
         | 
| 120 | 
            -
                end
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                it "returns shortest segment ignoring endings on a closed geometry" do
         | 
| 123 | 
            -
                  from_position = subject.nearest(xy: AIXM.xy(lat: 44.00022390676026, long: 4.789009094238281))
         | 
| 124 | 
            -
                  to_position = subject.nearest(xy: AIXM.xy(lat: 43.99800118202362, long: 4.765834808349609), geometry_index: from_position.geometry_index)
         | 
| 125 | 
            -
                  _(subject.segment(from_position: from_position, to_position: to_position)).must_equal [
         | 
| 126 | 
            -
                    AIXM.xy(lat: 44.00077957493397, long: 4.787635803222656),
         | 
| 127 | 
            -
                    AIXM.xy(lat: 43.99818641226534, long: 4.784030914306641),
         | 
| 128 | 
            -
                    AIXM.xy(lat: 43.994111213373934, long: 4.78205680847168),
         | 
| 129 | 
            -
                    AIXM.xy(lat: 44.00115001749186, long: 4.777421951293944),
         | 
| 130 | 
            -
                    AIXM.xy(lat: 44.002940457248556, long: 4.770212173461914)
         | 
| 131 | 
            -
                  ]
         | 
| 132 | 
            -
                end
         | 
| 133 | 
            -
             | 
| 134 | 
            -
              end
         | 
| 135 | 
            -
            end
         | 
| @@ -1,81 +0,0 @@ | |
| 1 | 
            -
            require_relative '../../spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            describe AIPP::Downloader do
         | 
| 4 | 
            -
              let :fixtures_dir do
         | 
| 5 | 
            -
                Pathname(__FILE__).join('..', '..', '..', 'fixtures')
         | 
| 6 | 
            -
              end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              let :tmp_dir do
         | 
| 9 | 
            -
                Pathname(Dir.mktmpdir).tap do |tmp_dir|
         | 
| 10 | 
            -
                  (sources_dir = tmp_dir.join('sources')).mkpath
         | 
| 11 | 
            -
                  FileUtils.cp(fixtures_dir.join('source.zip'), sources_dir)
         | 
| 12 | 
            -
                end
         | 
| 13 | 
            -
              end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
              after do
         | 
| 16 | 
            -
                FileUtils.rm_rf(tmp_dir)
         | 
| 17 | 
            -
              end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              describe :read do
         | 
| 20 | 
            -
                context "source archive does not exist" do
         | 
| 21 | 
            -
                  it "creates the source archive" do
         | 
| 22 | 
            -
                    Spy.on(Kernel, open: File.open(fixtures_dir.join('new.html')))
         | 
| 23 | 
            -
                    subject = AIPP::Downloader.new(storage: tmp_dir, source: 'new-source') do |downloader|
         | 
| 24 | 
            -
                      _(File.exist?(tmp_dir.join('work'))).must_equal true
         | 
| 25 | 
            -
                      downloader.read(document: 'new', url: 'http://localhost/new.html')
         | 
| 26 | 
            -
                    end
         | 
| 27 | 
            -
                    _(zip_entries(subject.source_file)).must_equal %w(new.html)
         | 
| 28 | 
            -
                    _(subject.send(:sources_path).children.count).must_equal 2
         | 
| 29 | 
            -
                  end
         | 
| 30 | 
            -
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                context "source archive does exist" do
         | 
| 33 | 
            -
                  it "unzips and uses the source archive" do
         | 
| 34 | 
            -
                    Spy.on(Kernel, open: File.open(fixtures_dir.join('new.html')))
         | 
| 35 | 
            -
                    subject = AIPP::Downloader.new(storage: tmp_dir, source: 'source') do |downloader|
         | 
| 36 | 
            -
                      _(File.exist?(tmp_dir.join('work'))).must_equal true
         | 
| 37 | 
            -
                      downloader.read(document: 'new', url: 'http://localhost/new.html').tap do |content|
         | 
| 38 | 
            -
                        _(content).must_be_instance_of Nokogiri::HTML5::Document
         | 
| 39 | 
            -
                        _(content.text).must_match /fixture-html-new/
         | 
| 40 | 
            -
                      end
         | 
| 41 | 
            -
                    end
         | 
| 42 | 
            -
                    _(zip_entries(subject.source_file)).must_equal %w(new.html one.html two.html)
         | 
| 43 | 
            -
                    _(subject.send(:sources_path).children.count).must_equal 1
         | 
| 44 | 
            -
                  end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                  it "downloads HTML documents to Nokogiri::HTML5::Document" do
         | 
| 47 | 
            -
                    Spy.on(Kernel, open: File.open(fixtures_dir.join('new.html')))
         | 
| 48 | 
            -
                    AIPP::Downloader.new(storage: tmp_dir, source: 'source') do |downloader|
         | 
| 49 | 
            -
                      downloader.read(document: 'new', url: 'http://localhost/new.html').tap do |content|
         | 
| 50 | 
            -
                        _(content).must_be_instance_of Nokogiri::HTML5::Document
         | 
| 51 | 
            -
                        _(content.text).must_match /fixture-html-new/
         | 
| 52 | 
            -
                      end
         | 
| 53 | 
            -
                    end
         | 
| 54 | 
            -
                  end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                  it "downloads and caches PDF documents to AIPP::PDF" do
         | 
| 57 | 
            -
                    Spy.on(Kernel, open: File.open(fixtures_dir.join('new.pdf')))
         | 
| 58 | 
            -
                    AIPP::Downloader.new(storage: tmp_dir, source: 'source') do |downloader|
         | 
| 59 | 
            -
                      downloader.read(document: 'new', url: 'http://localhost/new.pdf').tap do |content|
         | 
| 60 | 
            -
                        _(content).must_be_instance_of AIPP::PDF
         | 
| 61 | 
            -
                        _(content.text).must_match /fixture-pdf-new/
         | 
| 62 | 
            -
                      end
         | 
| 63 | 
            -
                    end
         | 
| 64 | 
            -
                  end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                  it "downloads explicitly specified type" do
         | 
| 67 | 
            -
                    Spy.on(Kernel, open: File.open(fixtures_dir.join('new.pdf')))
         | 
| 68 | 
            -
                    AIPP::Downloader.new(storage: tmp_dir, source: 'source') do |downloader|
         | 
| 69 | 
            -
                      downloader.read(document: 'new', url: 'http://localhost/new', type: :pdf).tap do |content|
         | 
| 70 | 
            -
                        _(content).must_be_instance_of AIPP::PDF
         | 
| 71 | 
            -
                        _(content.text).must_match /fixture-pdf-new/
         | 
| 72 | 
            -
                      end
         | 
| 73 | 
            -
                    end
         | 
| 74 | 
            -
                  end
         | 
| 75 | 
            -
                end
         | 
| 76 | 
            -
              end
         | 
| 77 | 
            -
             | 
| 78 | 
            -
              def zip_entries(zip_file)
         | 
| 79 | 
            -
                Zip::File.open(zip_file).entries.map(&:name).sort
         | 
| 80 | 
            -
              end
         | 
| 81 | 
            -
            end
         | 
| @@ -1,46 +0,0 @@ | |
| 1 | 
            -
            require_relative '../../spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            class Shoe
         | 
| 4 | 
            -
              include AIPP::Patcher
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              attr_accessor :size
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              patch Shoe, :size do |parser, object, value|
         | 
| 9 | 
            -
                case value
         | 
| 10 | 
            -
                  when 'S' then 36
         | 
| 11 | 
            -
                  when 'one-size-fits-all' then nil
         | 
| 12 | 
            -
                  else throw(:abort)
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
              end
         | 
| 15 | 
            -
            end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            describe AIPP::Patcher do
         | 
| 18 | 
            -
              subject do
         | 
| 19 | 
            -
                Shoe.new.attach_patches
         | 
| 20 | 
            -
              end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              context "with patches attached" do
         | 
| 23 | 
            -
                after do
         | 
| 24 | 
            -
                  subject.detach_patches
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                it "overwrites with non-nil values" do
         | 
| 28 | 
            -
                  _(subject.tap { |s| s.size = 'S' }.size).must_equal 36
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                it "overwrite with nil values" do
         | 
| 32 | 
            -
                  _(subject.tap { |s| s.size = 'one-size-fits-all' }.size).must_be_nil
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                it "skips overwrite if abort is thrown" do
         | 
| 36 | 
            -
                  _(subject.tap { |s| s.size = 42 }.size).must_equal 42
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
              context "with patches detached" do
         | 
| 41 | 
            -
                it "removes patches" do
         | 
| 42 | 
            -
                  subject.detach_patches
         | 
| 43 | 
            -
                  _(subject.tap { |s| s.size = 'S' }.size).must_equal 'S'
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
              end
         | 
| 46 | 
            -
            end
         | 
    
        data/spec/lib/aipp/pdf_spec.rb
    DELETED
    
    | @@ -1,124 +0,0 @@ | |
| 1 | 
            -
            require_relative '../../spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            describe AIPP::PDF do
         | 
| 4 | 
            -
              let :fixtures_dir do
         | 
| 5 | 
            -
                Pathname(__FILE__).join('..', '..', '..', 'fixtures')
         | 
| 6 | 
            -
              end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              subject do
         | 
| 9 | 
            -
                AIPP::PDF.new(fixtures_dir.join('document.pdf'))
         | 
| 10 | 
            -
              end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
              describe :@page_ranges do
         | 
| 13 | 
            -
                it "returns an array of page end positions" do
         | 
| 14 | 
            -
                  _(subject.instance_variable_get(:@page_ranges)).must_equal [74, 149, 225]
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              describe :page_for do
         | 
| 19 | 
            -
                it "finds the page for any given position" do
         | 
| 20 | 
            -
                  _(subject.send(:page_for, index: 0)).must_equal 1
         | 
| 21 | 
            -
                  _(subject.send(:page_for, index: 50)).must_equal 1
         | 
| 22 | 
            -
                  _(subject.send(:page_for, index: 74)).must_equal 1
         | 
| 23 | 
            -
                  _(subject.send(:page_for, index: 75)).must_equal 2
         | 
| 24 | 
            -
                  _(subject.send(:page_for, index: 149)).must_equal 2
         | 
| 25 | 
            -
                  _(subject.send(:page_for, index: 150)).must_equal 3
         | 
| 26 | 
            -
                  _(subject.send(:page_for, index: 223)).must_equal 3
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
              end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
              describe :from do
         | 
| 31 | 
            -
                it "fences beginning to any position" do
         | 
| 32 | 
            -
                  _(subject.from(100).range).must_equal (100..223)
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                it "fences beginning to first existing position" do
         | 
| 36 | 
            -
                  _(subject.from(:begin).range).must_equal (0..223)
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
              describe :to do
         | 
| 41 | 
            -
                it "fences beginning to any position" do
         | 
| 42 | 
            -
                  _(subject.to(100).range).must_equal (0..100)
         | 
| 43 | 
            -
                end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                it "fences beginning to first existing position" do
         | 
| 46 | 
            -
                  _(subject.to(:end).range).must_equal (0..223)
         | 
| 47 | 
            -
                end
         | 
| 48 | 
            -
              end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
              context "without boundaries" do
         | 
| 51 | 
            -
                describe :text do
         | 
| 52 | 
            -
                  it "returns the entire text" do
         | 
| 53 | 
            -
                    _(subject.text).must_match /\Apage 1, line 1/
         | 
| 54 | 
            -
                    _(subject.text).must_match /page 3, line 5\z/
         | 
| 55 | 
            -
                  end
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                describe :each_line do
         | 
| 59 | 
            -
                  it "maps lines to positions" do
         | 
| 60 | 
            -
                    target = [
         | 
| 61 | 
            -
                      ["page 1, line 1\n", 1, false],
         | 
| 62 | 
            -
                      ["page 1, line 2\n", 1, false],
         | 
| 63 | 
            -
                      ["page 1, line 3\n", 1, false],
         | 
| 64 | 
            -
                      ["page 1, line 4\n", 1, false],
         | 
| 65 | 
            -
                      ["page 1, line 5\f", 1, false],
         | 
| 66 | 
            -
                      ["page 2, line 1\n", 2, false],
         | 
| 67 | 
            -
                      ["page 2, line 2\n", 2, false],
         | 
| 68 | 
            -
                      ["page 2, line 3\n", 2, false],
         | 
| 69 | 
            -
                      ["page 2, line 4\n", 2, false],
         | 
| 70 | 
            -
                      ["page 2, line 5\f", 2, false],
         | 
| 71 | 
            -
                      ["page 3, line 1\n", 3, false],
         | 
| 72 | 
            -
                      ["page 3, line 2\n", 3, false],
         | 
| 73 | 
            -
                      ["page 3, line 3\n", 3, false],
         | 
| 74 | 
            -
                      ["page 3, line 4\n", 3, false],
         | 
| 75 | 
            -
                      ["page 3, line 5", 3, true]
         | 
| 76 | 
            -
                    ]
         | 
| 77 | 
            -
                    subject.each_line do |line, page, last|
         | 
| 78 | 
            -
                      target_line, target_page, target_last = target.shift
         | 
| 79 | 
            -
                      _(line).must_equal target_line
         | 
| 80 | 
            -
                      _(page).must_equal target_page
         | 
| 81 | 
            -
                      _(last).must_equal target_last
         | 
| 82 | 
            -
                    end
         | 
| 83 | 
            -
                  end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                  it "returns an enumerator if no block is given" do
         | 
| 86 | 
            -
                    _(subject.each_line).must_be_instance_of Enumerator
         | 
| 87 | 
            -
                  end
         | 
| 88 | 
            -
                end
         | 
| 89 | 
            -
              end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
              context "with boundaries" do
         | 
| 92 | 
            -
                before do
         | 
| 93 | 
            -
                  subject.from(100).to(200)
         | 
| 94 | 
            -
                end
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                describe :text do
         | 
| 97 | 
            -
                  it "returns the entire text" do
         | 
| 98 | 
            -
                    _(subject.text).must_match /\Ane 2/
         | 
| 99 | 
            -
                    _(subject.text).must_match /page 3\z/
         | 
| 100 | 
            -
                  end
         | 
| 101 | 
            -
                end
         | 
| 102 | 
            -
             | 
| 103 | 
            -
                describe :each_line do
         | 
| 104 | 
            -
                  it "maps lines to positions" do
         | 
| 105 | 
            -
                    target = [
         | 
| 106 | 
            -
                      ["ne 2\n", 2, false],
         | 
| 107 | 
            -
                      ["page 2, line 3\n", 2, false],
         | 
| 108 | 
            -
                      ["page 2, line 4\n", 2, false],
         | 
| 109 | 
            -
                      ["page 2, line 5\f", 2, false],
         | 
| 110 | 
            -
                      ["page 3, line 1\n", 3, false],
         | 
| 111 | 
            -
                      ["page 3, line 2\n", 3, false],
         | 
| 112 | 
            -
                      ["page 3, line 3\n", 3, false],
         | 
| 113 | 
            -
                      ["page 3", 3, true]
         | 
| 114 | 
            -
                    ]
         | 
| 115 | 
            -
                    subject.each_line do |line, page, last|
         | 
| 116 | 
            -
                      target_line, target_page, target_last = target.shift
         | 
| 117 | 
            -
                      _(line).must_equal target_line
         | 
| 118 | 
            -
                      _(page).must_equal target_page
         | 
| 119 | 
            -
                      _(last).must_equal target_last
         | 
| 120 | 
            -
                    end
         | 
| 121 | 
            -
                  end
         | 
| 122 | 
            -
                end
         | 
| 123 | 
            -
              end
         | 
| 124 | 
            -
            end
         | 
| @@ -1,44 +0,0 @@ | |
| 1 | 
            -
            require_relative '../../spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            describe AIPP::THash do
         | 
| 4 | 
            -
              context "non-circular dependencies" do
         | 
| 5 | 
            -
                subject do
         | 
| 6 | 
            -
                  AIPP::THash[
         | 
| 7 | 
            -
                    dns: %i(net),
         | 
| 8 | 
            -
                    webserver: %i(dns logger),
         | 
| 9 | 
            -
                    net: [],
         | 
| 10 | 
            -
                    logger: []
         | 
| 11 | 
            -
                  ]
         | 
| 12 | 
            -
                end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                describe :tsort do
         | 
| 15 | 
            -
                  it "must compile the overall dependency list" do
         | 
| 16 | 
            -
                    _(subject.tsort).must_equal %i(net dns logger webserver)
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  it "must compile partial dependency lists" do
         | 
| 20 | 
            -
                    _(subject.tsort(:dns)).must_equal %i(net dns)
         | 
| 21 | 
            -
                    _(subject.tsort(:logger)).must_equal %i(logger)
         | 
| 22 | 
            -
                    _(subject.tsort(:webserver)).must_equal %i(net dns logger webserver)
         | 
| 23 | 
            -
                  end
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
              context "circular dependencies" do
         | 
| 28 | 
            -
                subject do
         | 
| 29 | 
            -
                  AIPP::THash[
         | 
| 30 | 
            -
                    dns: %i(net),
         | 
| 31 | 
            -
                    webserver: %i(dns logger),
         | 
| 32 | 
            -
                    net: %i(dns),
         | 
| 33 | 
            -
                    logger: []
         | 
| 34 | 
            -
                  ]
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                describe :tsort do
         | 
| 38 | 
            -
                  it "must raise cyclic dependency error" do
         | 
| 39 | 
            -
                    _{ subject.tsort }.must_raise TSort::Cyclic
         | 
| 40 | 
            -
                    _{ subject.tsort(:dns) }.must_raise TSort::Cyclic
         | 
| 41 | 
            -
                  end
         | 
| 42 | 
            -
                end
         | 
| 43 | 
            -
              end
         | 
| 44 | 
            -
            end
         | 
| @@ -1,76 +0,0 @@ | |
| 1 | 
            -
            require_relative '../../spec_helper'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            describe Enumerable do
         | 
| 4 | 
            -
             | 
| 5 | 
            -
              describe :split do
         | 
| 6 | 
            -
                context "by object" do
         | 
| 7 | 
            -
                  it "must split at matching element" do
         | 
| 8 | 
            -
                    _([1, 2, 0, 3, 4].split(0)).must_equal [[1, 2], [3, 4]]
         | 
| 9 | 
            -
                  end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  it "won't split when no element matches" do
         | 
| 12 | 
            -
                    _([1, 2, 3].split(0)).must_equal [[1, 2, 3]]
         | 
| 13 | 
            -
                  end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                  it "won't split zero length enumerable" do
         | 
| 16 | 
            -
                    _([].split(0)).must_equal []
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  it "must keep leading empty subarrays" do
         | 
| 20 | 
            -
                    _([0, 1, 2, 0, 3, 4].split(0)).must_equal [[], [1, 2], [3, 4]]
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                  it "must keep empty subarrays in the middle" do
         | 
| 24 | 
            -
                    _([1, 2, 0, 0, 3, 4].split(0)).must_equal [[1, 2], [], [3, 4]]
         | 
| 25 | 
            -
                  end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                  it "must drop trailing empty subarrays" do
         | 
| 28 | 
            -
                    _([1, 2, 0, 3, 4, 0].split(0)).must_equal [[1, 2], [3, 4]]
         | 
| 29 | 
            -
                  end
         | 
| 30 | 
            -
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                context "by block" do
         | 
| 33 | 
            -
                  it "must split at matching element" do
         | 
| 34 | 
            -
                    _([1, 2, 0, 3, 4].split { |e| e.zero? }).must_equal [[1, 2], [3, 4]]
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                  it "won't split when no element matches" do
         | 
| 38 | 
            -
                    _([1, 2, 3].split { |e| e.zero? }).must_equal [[1, 2, 3]]
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                  it "won't split zero length enumerable" do
         | 
| 42 | 
            -
                    _([].split { |e| e.zero? }).must_equal []
         | 
| 43 | 
            -
                  end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                  it "must keep leading empty subarrays" do
         | 
| 46 | 
            -
                    _([0, 1, 2, 0, 3, 4].split { |e| e.zero? }).must_equal [[], [1, 2], [3, 4]]
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                  it "must keep empty subarrays in the middle" do
         | 
| 50 | 
            -
                    _([1, 2, 0, 0, 3, 4].split { |e| e.zero? }).must_equal [[1, 2], [], [3, 4]]
         | 
| 51 | 
            -
                  end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                  it "must drop trailing empty subarrays" do
         | 
| 54 | 
            -
                    _([1, 2, 0, 3, 4, 0].split { |e| e.zero? }).must_equal [[1, 2], [3, 4]]
         | 
| 55 | 
            -
                  end
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
              end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
              describe :group_by_chunks do
         | 
| 60 | 
            -
                it "fails to group if the first element does not meet the chunk condition" do
         | 
| 61 | 
            -
                  subject = [10, 11, 12, 2, 20, 21 ]
         | 
| 62 | 
            -
                  _{ subject.group_by_chunks { |i| i < 10 } }.must_raise ArgumentError
         | 
| 63 | 
            -
                end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                it "must map matching elements to array of subsequent non-matching elements" do
         | 
| 66 | 
            -
                  subject = [1, 10, 11, 12, 2, 20, 21, 3, 30, 31, 32]
         | 
| 67 | 
            -
                  _(subject.group_by_chunks { |i| i < 10 }).must_equal(1 => [10, 11, 12], 2 => [20, 21], 3 => [30, 31, 32])
         | 
| 68 | 
            -
                end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                it "must map matching elements to empty array if no subsequent non-matching elements exist" do
         | 
| 71 | 
            -
                  subject = [1, 10, 11, 12, 2, 3, 30]
         | 
| 72 | 
            -
                  _(subject.group_by_chunks { |i| i < 10 }).must_equal(1 => [10, 11, 12], 2 => [], 3 => [30])
         | 
| 73 | 
            -
                end
         | 
| 74 | 
            -
              end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
            end
         |