github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/tests/system/lib/debug.rb (about)

     1  class Debug
     2    def self.visualize_tree(instances, sharing)
     3      @count ||= 0
     4      Visualizer.new(instances, sharing, @count).render
     5      @count += 1
     6    end
     7  
     8    class Visualizer
     9      def initialize(instances, sharing, suffix)
    10        @instances = instances
    11        @sharing = sharing
    12        @output = File.join Helpers.current_dir, "tree_#{suffix}"
    13      end
    14  
    15      def render
    16        File.write "#{@output}.gv", to_dot
    17        system "dot -Tpng -o #{@output}.png #{@output}.gv"
    18        system "xdg-open #{@output}.png"
    19      end
    20  
    21      def to_dot
    22        @buf = []
    23        @buf << 'digraph debug {'
    24        @buf << '  node [shape="box", fontname="lato", fontsize=10, margin=0.12, color="#297EF2", fontcolor="#32363F"];'
    25        @buf << '  edge [color="#32363F"];'
    26        @buf << '  ranksep=0.4; nodesep=0.5;'
    27  
    28        @instances.each_with_index do |inst, idx|
    29          @buf << '' << "  subgraph cluster_#{inst.name} {"
    30          @buf << "    label=\"#{inst.name}\"; labeljust=\"l\"; fontname=\"lato\"; fontsize=12" << ''
    31          @buf << "    #{esc Folder::ROOT_DIR, inst} [label=\"/\"]"
    32          if idx == 0
    33            @buf << "    invisible [style=invis]"
    34            @buf << "    invisible -> #{esc Folder::ROOT_DIR, inst} [style=invis]"
    35          end
    36          tree_for(inst).sort_by { |doc| doc['name'] || '' }.each do |doc|
    37            next if ignored? doc
    38            @buf << "    #{esc doc['_id'], inst} [label=<#{doc['name']}<BR/>#{doc['_id']}<BR/>#{doc['_rev']}>]"
    39            @buf << "    #{esc doc['dir_id'], inst} -> #{esc doc['_id'], inst}"
    40          end
    41          @buf << '  }'
    42        end
    43  
    44        @buf << '}' << ''
    45        @buf.join "\n"
    46      end
    47  
    48      def ignored?(doc)
    49        return true if doc["_id"].start_with?("_") # Design docs
    50        return true if doc["_id"] == Folder::ROOT_DIR
    51        path = doc["path"]
    52        return false if path.nil?
    53        return true if path.start_with?("/Photos")
    54        return true if path.start_with?("/Administrati")
    55        false
    56      end
    57  
    58      # Escape identifiers for graphviz
    59      def esc(id, inst)
    60        case id
    61        when Folder::ROOT_DIR then "#{inst.name}_root"
    62        when Folder::TRASH_DIR then "#{inst.name}_trash"
    63        when Folder::SHARED_WITH_ME_DIR then "#{inst.name}_shared"
    64        when Folder::NO_LONGER_SHARED_DIR then "#{inst.name}_no_longer"
    65        else 'x' + id
    66        end
    67      end
    68  
    69      def tree_for(inst)
    70        Helpers.couch.all_docs inst.domain, CozyFile.doctype
    71      end
    72    end
    73  end