File Coverage

blib/lib/App/Test/DWG/LibreDWG/JSON.pm
Criterion Covered Total %
statement 47 96 48.9
branch 1 26 3.8
condition 2 18 11.1
subroutine 13 15 86.6
pod 2 2 100.0
total 65 157 41.4


line stmt bran cond sub pod time code
1             package App::Test::DWG::LibreDWG::JSON;
2              
3 4     4   178972 use strict;
  4         8  
  4         183  
4 4     4   22 use warnings;
  4         7  
  4         226  
5              
6 4     4   2292 use CAD::AutoCAD::Detect qw(detect_dwg_file);
  4         86956  
  4         104  
7 4     4   2917 use Capture::Tiny qw(capture);
  4         169142  
  4         338  
8 4     4   2469 use File::Copy;
  4         20990  
  4         367  
9 4     4   40 use File::Path qw(mkpath);
  4         7  
  4         273  
10 4     4   2381 use File::Spec::Functions qw(catfile);
  4         4122  
  4         404  
11 4     4   72 use File::Temp qw(tempdir);
  4         13  
  4         213  
12 4     4   2345 use Getopt::Std;
  4         11891  
  4         310  
13 4     4   2144 use IO::Barf qw(barf);
  4         4928  
  4         73  
14 4     4   269 use Readonly;
  4         8  
  4         4892  
15              
16             Readonly::Hash our %REL => (
17             'MC0.0' => 'r1.1',
18             'AC1.2' => 'r1.2',
19             'AC1.40' => 'r1.4',
20             'AC1.50' => 'r2.0',
21             'AC2.10' => 'r2.10',
22             'AC1001' => 'r2.4',
23             'AC1002' => 'r2.5',
24             'AC1003' => 'r2.6',
25             'AC1004' => 'r9',
26             'AC1006' => 'r10',
27             'AC1009' => 'r11',
28             'AC1012' => 'r13',
29             'AC1013' => 'r13c3',
30             'AC1014' => 'r14',
31             'AC1015' => 'r2000',
32             'AC1018' => 'r2004',
33             'AC1021' => 'r2007',
34             'AC1024' => 'r2010',
35             'AC1027' => 'r2013',
36             'AC1032' => 'r2018',
37             );
38             Readonly::Scalar our $DR => 'dwgread';
39             Readonly::Scalar our $DW => 'dwgwrite';
40              
41             our $VERSION = 0.05;
42              
43             # Constructor.
44             sub new {
45 2     2 1 786048 my ($class, @params) = @_;
46              
47             # Create object.
48 2         8 my $self = bless {}, $class;
49              
50             # Object.
51 2         12 return $self;
52             }
53              
54             # Run.
55             sub run {
56 1     1 1 3 my $self = shift;
57              
58             # Process arguments.
59 1         13 $self->{'_opts'} = {
60             'd' => undef,
61             'h' => 0,
62             'i' => 0,
63             'v' => 0,
64             };
65 1 50 33     15 if (! getopts('d:hiv:', $self->{'_opts'}) || @ARGV < 1
      33        
66             || $self->{'_opts'}->{'h'}) {
67              
68 1         165 print STDERR "Usage: $0 [-d test_dir] [-h] [-i] [-v level] [--version] dwg_file\n";
69 1         53 print STDERR "\t-d test_dir\tTest directory (default is directory in system tmp).\n";
70 1         17 print STDERR "\t-h\t\tPrint help.\n";
71 1         13 print STDERR "\t-i\t\tIgnore errors.\n";
72 1         12 print STDERR "\t-v level\tVerbosity level (default 0, max 9).\n";
73 1         13 print STDERR "\t--version\tPrint version.\n";
74 1         108 print STDERR "\tdwg_file\tAutoCAD DWG file to test.\n";
75 1         8 return 1;
76             }
77 0           $self->{'_dwg_file'} = shift @ARGV;
78              
79 0           my $tmp_dir = $self->{'_opts'}->{'d'};
80 0 0 0       if (defined $tmp_dir && ! -d $tmp_dir) {
81 0           mkpath($tmp_dir);
82             }
83 0 0 0       if (! defined $tmp_dir || ! -d $tmp_dir) {
84 0           $tmp_dir = tempdir(CLEANUP => 1);
85             }
86 0           $self->{'_tmp_dir'} = $tmp_dir;
87              
88             # Copy original file to dir.
89 0           my $dwg_file_first = catfile($tmp_dir, 'first.dwg');
90 0           copy($self->{'_dwg_file'}, $dwg_file_first);
91              
92             # Get magic string.
93 0           my $magic = detect_dwg_file($dwg_file_first);
94 0 0         if (! exists $REL{$magic}) {
95 0           print STDERR "dwgwrite for magic '$magic' doesn't supported.\n";
96 0           return 1;
97             }
98 0           my $dwgwrite_version = $REL{$magic};
99              
100             # Verbose level.
101 0           my $v = '-v'.$self->{'_opts'}->{'v'};
102              
103 0   0       my $dwgread = $ENV{'DWGREAD'} || $DR;
104 0   0       my $dwgwrite = $ENV{'DWGWRITE'} || $DW;
105              
106             # Convert dwg file to JSON.
107 0           my $json_file_first = catfile($tmp_dir, 'first.json');
108 0           my $dwg_to_json_first = "$dwgread $v -o $json_file_first $dwg_file_first";
109 0 0         if ($self->_exec($dwg_to_json_first, 'dwg_to_json')) {
110 0           return 1;
111             }
112              
113             # Convert JSON to dwg file.
114 0           my $dwg_file_second = catfile($tmp_dir, 'second.dwg');
115 0           my $json_to_dwg_first = "$dwgwrite --as $dwgwrite_version $v -o $dwg_file_second $json_file_first";
116 0 0         if ($self->_exec($json_to_dwg_first, 'json_to_dwg')) {
117 0           return 1;
118             }
119              
120             # Convert new dwg file to JSON.
121 0           my $json_file_second = catfile($tmp_dir, 'second.json');
122 0           my $dwg_to_json_second = "$dwgread $v -o $json_file_second $dwg_file_second";
123 0 0         if ($self->_exec($dwg_to_json_second, 'dwg_to_json_second')) {
124 0           return 1;
125             }
126              
127             # Compare JSON files.
128 0           my $diff = "diff $json_file_first $json_file_second";
129 0           system($diff);
130              
131 0           return 0;
132             }
133              
134             sub _exec {
135 0     0     my ($self, $command, $log_prefix) = @_;
136              
137             my ($stdout, $stderr, $exit_code) = capture {
138 0     0     system($command);
139 0           };
140              
141 0 0         if (defined $log_prefix) {
142 0 0         if ($stdout) {
143 0           my $stdout_file = catfile($self->{'_tmp_dir'},
144             $log_prefix.'-stdout.log');
145 0           barf($stdout_file, $stdout);
146             }
147 0 0         if ($stderr) {
148 0           my $stderr_file = catfile($self->{'_tmp_dir'},
149             $log_prefix.'-stderr.log');
150 0           barf($stderr_file, $stderr);
151              
152             # Report errors.
153 0 0         if (! $self->{'_opts'}->{'i'}) {
154 0 0         if (my @num = ($stderr =~ m/ERROR/gms)) {
155 0           print STDERR "Command '$command' has ".scalar @num." ERRORs\n";
156             }
157             }
158             }
159             }
160              
161 0 0         if ($exit_code) {
162 0           print STDERR "Command '$command' exit with $exit_code.\n";
163 0           return 1;
164             }
165              
166 0           return 0;
167             }
168              
169             1;
170              
171              
172             __END__