// Path: src/se/vidstige/jadb/AdbServerLauncher.java
// public class AdbServerLauncher {
//     private final String executable;
//     private Subprocess subprocess;
// 
//     /**
//      * Creates a new launcher loading ADB from the environment.
//      * 
//      * @param subprocess the sub-process.
//      * @param environment the environment to use to locate the ADB executable.
//      */
//     public AdbServerLauncher(Subprocess subprocess, Map<String, String> environment) {
//         this(subprocess, findAdbExecutable(environment));
//     }
// 
//     /**
//      * Creates a new launcher with the specified ADB.
//      *
//      * @param subprocess the sub-process.
//      * @param executable the location of the ADB executable.
//      */
//     public AdbServerLauncher(Subprocess subprocess, String executable) {
//         this.subprocess = subprocess;
//         this.executable = executable;
//     }
// 
//     private static String findAdbExecutable(Map<String, String> environment) {
//         String androidHome = environment.get("ANDROID_HOME");
//         if (androidHome == null || androidHome.equals("")) {
//             return "adb";
//         }
//         return androidHome + "/platform-tools/adb";
//     }
// 
//     public void launch() throws IOException, InterruptedException {
//         Process p = subprocess.execute(new String[]{executable, "start-server"});
//         p.waitFor();
//         int exitValue = p.exitValue();
//         if (exitValue != 0) throw new IOException("adb exited with exit code: " + exitValue);
//     }
// }
// 
// Path: test/se/vidstige/jadb/test/fakes/FakeSubprocess.java
// public class FakeSubprocess extends Subprocess {
//     private List<Expectation> expectations = new ArrayList<>();
// 
//     public Expectation expect(String[] command, int exitValue) {
//         Expectation builder = new Expectation(command, exitValue);
//         expectations.add(builder);
//         return builder;
//     }
// 
//     private String format(String[] command) {
//         StringBuilder sb = new StringBuilder();
//         for (int i = 0; i < command.length; i++) {
//             if (i > 0) {
//                 sb.append(" ");
//             }
//             sb.append(command[i]);
//         }
//         return sb.toString();
//     }
// 
//     @Override
//     public Process execute(String[] command) throws IOException {
//         List<Expectation> toRemove = new ArrayList<>();
//         for (Expectation e : expectations) {
//             if (e.matches(command)) {
//                 toRemove.add(e);
//             }
//         }
//         expectations.removeAll(toRemove);
//         if (toRemove.size() == 1) {
//             return new FakeProcess(toRemove.get(0).getExitValue());
//         }
//         throw new AssertionError("Unexpected command: " + format(command));
//     }
// 
//     public void verifyExpectations() {
//         if (expectations.size() > 0) {
//             throw new AssertionError("Subprocess never called: " + format(expectations.get(0).getCommand()));
//         }
//     }
// 
//     private static class Expectation {
//         private final String[] command;
//         private final int exitValue;
// 
//         public Expectation(String[] command, int exitValue) {
//             this.command = command;
//             this.exitValue = exitValue;
//         }
// 
//         public boolean matches(String[] command) {
//             return Arrays.equals(command, this.command);
//         }
// 
//         public int getExitValue() {
//             return exitValue;
//         }
// 
//         public String[] getCommand() {
//             return command;
//         }
//     }
// }


import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import se.vidstige.jadb.AdbServerLauncher;
import se.vidstige.jadb.test.fakes.FakeSubprocess;
import java.io.IOException;
import java.util.*;
package se.vidstige.jadb.test.unit;



public class AdbServerLauncherFixture {

    private FakeSubprocess subprocess;
    private Map<String, String> environment = new HashMap<>();

    @Before
    public void setUp() {
        subprocess = new FakeSubprocess();
    }
    @After
    public void tearDown() {
        subprocess.verifyExpectations();
    }

    @Test
    public void testStartServer() throws Exception {
        subprocess.expect(new String[]{"/abc/platform-tools/adb", "start-server"}, 0);
        Map<String, String> environment = new HashMap<>();
        environment.put("ANDROID_HOME", "/abc");
// Path: src/se/vidstige/jadb/AdbServerLauncher.java
// public class AdbServerLauncher {
//     private final String executable;
//     private Subprocess subprocess;
// 
//     /**
//      * Creates a new launcher loading ADB from the environment.
//      * 
//      * @param subprocess the sub-process.
//      * @param environment the environment to use to locate the ADB executable.
//      */
//     public AdbServerLauncher(Subprocess subprocess, Map<String, String> environment) {
//         this(subprocess, findAdbExecutable(environment));
//     }
// 
//     /**
//      * Creates a new launcher with the specified ADB.
//      *
//      * @param subprocess the sub-process.
//      * @param executable the location of the ADB executable.
//      */
//     public AdbServerLauncher(Subprocess subprocess, String executable) {
//         this.subprocess = subprocess;
//         this.executable = executable;
//     }
// 
//     private static String findAdbExecutable(Map<String, String> environment) {
//         String androidHome = environment.get("ANDROID_HOME");
//         if (androidHome == null || androidHome.equals("")) {
//             return "adb";
//         }
//         return androidHome + "/platform-tools/adb";
//     }
// 
//     public void launch() throws IOException, InterruptedException {
//         Process p = subprocess.execute(new String[]{executable, "start-server"});
//         p.waitFor();
//         int exitValue = p.exitValue();
//         if (exitValue != 0) throw new IOException("adb exited with exit code: " + exitValue);
//     }
// }
// 
// Path: test/se/vidstige/jadb/test/fakes/FakeSubprocess.java
// public class FakeSubprocess extends Subprocess {
//     private List<Expectation> expectations = new ArrayList<>();
// 
//     public Expectation expect(String[] command, int exitValue) {
//         Expectation builder = new Expectation(command, exitValue);
//         expectations.add(builder);
//         return builder;
//     }
// 
//     private String format(String[] command) {
//         StringBuilder sb = new StringBuilder();
//         for (int i = 0; i < command.length; i++) {
//             if (i > 0) {
//                 sb.append(" ");
//             }
//             sb.append(command[i]);
//         }
//         return sb.toString();
//     }
// 
//     @Override
//     public Process execute(String[] command) throws IOException {
//         List<Expectation> toRemove = new ArrayList<>();
//         for (Expectation e : expectations) {
//             if (e.matches(command)) {
//                 toRemove.add(e);
//             }
//         }
//         expectations.removeAll(toRemove);
//         if (toRemove.size() == 1) {
//             return new FakeProcess(toRemove.get(0).getExitValue());
//         }
//         throw new AssertionError("Unexpected command: " + format(command));
//     }
// 
//     public void verifyExpectations() {
//         if (expectations.size() > 0) {
//             throw new AssertionError("Subprocess never called: " + format(expectations.get(0).getCommand()));
//         }
//     }
// 
//     private static class Expectation {
//         private final String[] command;
//         private final int exitValue;
// 
//         public Expectation(String[] command, int exitValue) {
//             this.command = command;
//             this.exitValue = exitValue;
//         }
// 
//         public boolean matches(String[] command) {
//             return Arrays.equals(command, this.command);
//         }
// 
//         public int getExitValue() {
//             return exitValue;
//         }
// 
//         public String[] getCommand() {
//             return command;
//         }
//     }
// }


// Path: test/se/vidstige/jadb/test/unit/AdbServerLauncherFixture.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import se.vidstige.jadb.AdbServerLauncher;
import se.vidstige.jadb.test.fakes.FakeSubprocess;
import java.io.IOException;
import java.util.*;

package se.vidstige.jadb.test.unit;



public class AdbServerLauncherFixture {

    private FakeSubprocess subprocess;
    private Map<String, String> environment = new HashMap<>();

    @Before
    public void setUp() {
        subprocess = new FakeSubprocess();
    }
    @After
    public void tearDown() {
        subprocess.verifyExpectations();
    }

    @Test
    public void testStartServer() throws Exception {
        subprocess.expect(new String[]{"/abc/platform-tools/adb", "start-server"}, 0);
        Map<String, String> environment = new HashMap<>();
        environment.put("ANDROID_HOME", "/abc");
        new AdbServerLauncher(subprocess, environment).launch();